diff --git a/.eslintrc.js b/.eslintrc.js index 135252825dcf..ed6f162ad8d4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -235,8 +235,21 @@ module.exports = { ], }, - // Remove once no JS files are left overrides: [ + // Enforces every Onyx type and its properties to have a comment explaining its purpose. + { + files: ['src/types/onyx/**/*.ts'], + rules: { + 'jsdoc/require-jsdoc': [ + 'error', + { + contexts: ['TSInterfaceDeclaration', 'TSTypeAliasDeclaration', 'TSPropertySignature'], + }, + ], + }, + }, + + // Remove once no JS files are left { files: ['*.js', '*.jsx'], rules: { diff --git a/src/libs/ModifiedExpenseMessage.ts b/src/libs/ModifiedExpenseMessage.ts index 003074aa55f9..c1c2165fd3a7 100644 --- a/src/libs/ModifiedExpenseMessage.ts +++ b/src/libs/ModifiedExpenseMessage.ts @@ -3,12 +3,12 @@ import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PolicyTagList, ReportAction} from '@src/types/onyx'; +import type {ModifiedExpense} from '@src/types/onyx/OriginalMessage'; import * as CurrencyUtils from './CurrencyUtils'; import DateUtils from './DateUtils'; import getReportPolicyID from './getReportPolicyID'; import * as Localize from './Localize'; import * as PolicyUtils from './PolicyUtils'; -import type {ExpenseOriginalMessage} from './ReportUtils'; import * as TransactionUtils from './TransactionUtils'; let allPolicyTags: OnyxCollection = {}; @@ -109,7 +109,7 @@ function getForReportAction(reportID: string | undefined, reportAction: OnyxEntr if (reportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE) { return ''; } - const reportActionOriginalMessage = reportAction?.originalMessage as ExpenseOriginalMessage | undefined; + const reportActionOriginalMessage = reportAction?.originalMessage as ModifiedExpense | undefined; const policyID = getReportPolicyID(reportID) ?? ''; const removalFragments: string[] = []; diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 1830edd91b68..ac0ee9e9025e 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -11,6 +11,7 @@ import type { ActionName, ChangeLog, IOUMessage, + JoinWorkspaceResolution, OriginalMessageActionableMentionWhisper, OriginalMessageActionableReportMentionWhisper, OriginalMessageActionableTrackedExpenseWhisper, @@ -1205,7 +1206,9 @@ function isActionableJoinRequest(reportAction: OnyxEntry): reportA */ function isActionableJoinRequestPending(reportID: string): boolean { const sortedReportActions = getSortedReportActions(Object.values(getAllReportActions(reportID))); - const findPendingRequest = sortedReportActions.find((reportActionItem) => isActionableJoinRequest(reportActionItem) && reportActionItem.originalMessage.choice === ''); + const findPendingRequest = sortedReportActions.find( + (reportActionItem) => isActionableJoinRequest(reportActionItem) && reportActionItem.originalMessage.choice === ('' as JoinWorkspaceResolution), + ); return !!findPendingRequest; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 4c2372886d50..d68d308feedd 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -40,13 +40,15 @@ import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon'; import type { ChangeLog, IOUMessage, + ModifiedExpense, OriginalMessageActionName, + OriginalMessageApproved, OriginalMessageCreated, OriginalMessageDismissedViolation, OriginalMessageReimbursementDequeued, OriginalMessageRenamed, + OriginalMessageSubmitted, PaymentMethodType, - ReimbursementDeQueuedMessage, } from '@src/types/onyx/OriginalMessage'; import type {Status} from '@src/types/onyx/PersonalDetails'; import type {NotificationPreference, Participants, PendingChatMember, Participant as ReportParticipant} from '@src/types/onyx/Report'; @@ -87,30 +89,6 @@ type AvatarRange = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | type WelcomeMessage = {showReportName: boolean; phrase1?: string; phrase2?: string}; -type ExpenseOriginalMessage = { - oldComment?: string; - newComment?: string; - comment?: string; - merchant?: string; - oldCreated?: string; - created?: string; - oldMerchant?: string; - oldAmount?: number; - amount?: number; - oldCurrency?: string; - currency?: string; - category?: string; - oldCategory?: string; - tag?: string; - oldTag?: string; - billable?: string; - oldBillable?: string; - oldTaxAmount?: number; - taxAmount?: number; - taxRate?: string; - oldTaxRate?: string; -}; - type SpendBreakdown = { nonReimbursableSpend: number; reimbursableSpend: number; @@ -211,12 +189,12 @@ type ReportOfflinePendingActionAndErrors = { }; type OptimisticApprovedReportAction = Pick< - ReportAction, + ReportAction & OriginalMessageApproved, 'actionName' | 'actorAccountID' | 'automatic' | 'avatar' | 'isAttachment' | 'originalMessage' | 'message' | 'person' | 'reportActionID' | 'shouldShow' | 'created' | 'pendingAction' >; type OptimisticSubmittedReportAction = Pick< - ReportAction, + ReportAction & OriginalMessageSubmitted, | 'actionName' | 'actorAccountID' | 'adminAccountID' @@ -2208,7 +2186,7 @@ function getReimbursementDeQueuedActionMessage( report: OnyxEntry | EmptyObject, isLHNPreview = false, ): string { - const originalMessage = reportAction?.originalMessage as ReimbursementDeQueuedMessage | undefined; + const originalMessage = reportAction?.originalMessage; const amount = originalMessage?.amount; const currency = originalMessage?.currency; const formattedAmount = CurrencyUtils.convertToDisplayString(amount, currency); @@ -3024,8 +3002,8 @@ function getModifiedExpenseOriginalMessage( transactionChanges: TransactionChanges, isFromExpenseReport: boolean, policy: OnyxEntry, -): ExpenseOriginalMessage { - const originalMessage: ExpenseOriginalMessage = {}; +): ModifiedExpense { + const originalMessage: ModifiedExpense = {}; // Remark: Comment field is the only one which has new/old prefixes for the keys (newComment/ oldComment), // all others have old/- pattern such as oldCreated/created if ('comment' in transactionChanges) { @@ -7151,7 +7129,6 @@ export { export type { Ancestor, DisplayNameWithTooltips, - ExpenseOriginalMessage, OptimisticAddCommentReportAction, OptimisticChatReport, OptimisticClosedReportAction, diff --git a/src/libs/actions/Card.ts b/src/libs/actions/Card.ts index 756ef902d913..9a011d88e582 100644 --- a/src/libs/actions/Card.ts +++ b/src/libs/actions/Card.ts @@ -5,7 +5,7 @@ import type {ActivatePhysicalExpensifyCardParams, ReportVirtualExpensifyCardFrau import {SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Response} from '@src/types/onyx'; +import type {ExpensifyCardDetails} from '@src/types/onyx/Card'; type ReplacementReason = 'damaged' | 'stolen'; @@ -158,7 +158,7 @@ function clearCardListErrors(cardID: number) { * * @returns promise with card details object */ -function revealVirtualCardDetails(cardID: number): Promise { +function revealVirtualCardDetails(cardID: number): Promise { return new Promise((resolve, reject) => { const parameters: RevealExpensifyCardDetailsParams = {cardID}; @@ -170,7 +170,7 @@ function revealVirtualCardDetails(cardID: number): Promise { reject('cardPage.cardDetailsLoadingFailure'); return; } - resolve(response); + resolve(response as ExpensifyCardDetails); }) // eslint-disable-next-line prefer-promise-reject-errors .catch(() => reject('cardPage.cardDetailsLoadingFailure')); diff --git a/src/libs/actions/Wallet.ts b/src/libs/actions/Wallet.ts index 045cc34f39ef..3dd3f01c0703 100644 --- a/src/libs/actions/Wallet.ts +++ b/src/libs/actions/Wallet.ts @@ -61,10 +61,6 @@ function setAdditionalDetailsErrors(errorFields: OnyxCommon.ErrorFields) { Onyx.merge(ONYXKEYS.WALLET_ADDITIONAL_DETAILS, {errorFields}); } -function setAdditionalDetailsErrorMessage(additionalErrorMessage: string) { - Onyx.merge(ONYXKEYS.WALLET_ADDITIONAL_DETAILS, {additionalErrorMessage}); -} - /** * Save the source that triggered the KYC wall and optionally the chat report ID associated with the IOU */ @@ -304,7 +300,6 @@ export { openInitialSettingsPage, openEnablePaymentsPage, setAdditionalDetailsErrors, - setAdditionalDetailsErrorMessage, setAdditionalDetailsQuestions, updateCurrentStep, answerQuestionsForWallet, diff --git a/src/libs/models/BankAccount.ts b/src/libs/models/BankAccount.ts index a8dea594daa5..a86a30b57e86 100644 --- a/src/libs/models/BankAccount.ts +++ b/src/libs/models/BankAccount.ts @@ -1,7 +1,7 @@ import {Str} from 'expensify-common'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; -import type {AdditionalData} from '@src/types/onyx/BankAccount'; +import type {BankAccountAdditionalData} from '@src/types/onyx/BankAccount'; import type BankAccountJSON from '@src/types/onyx/BankAccount'; type State = ValueOf; @@ -194,7 +194,7 @@ class BankAccount { /** * Get the additional data of a bankAccount */ - getAdditionalData(): Partial { + getAdditionalData(): Partial { return this.json.accountData?.additionalData ?? {}; } diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 5d747a7cfa16..c557229aca72 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -68,6 +68,7 @@ type ReportScreenOnyxProps = { /** An array containing all report actions related to this report, sorted based on a date criterion */ sortedAllReportActions: OnyxTypes.ReportAction[]; + /** Additional report details */ reportNameValuePairs: OnyxEntry; /** The report metadata loading states */ diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index a85523593b4c..b9abd96583b4 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -67,6 +67,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; +import type {JoinWorkspaceResolution} from '@src/types/onyx/OriginalMessage'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; import {RestrictedReadOnlyContextMenuActions} from './ContextMenu/ContextMenuActions'; @@ -398,7 +399,7 @@ function ReportActionItem({ const attachmentContextValue = useMemo(() => ({reportID: report.reportID, type: CONST.ATTACHMENT_TYPE.REPORT}), [report.reportID]); const actionableItemButtons: ActionableItem[] = useMemo(() => { - if (!isActionableWhisper && (!ReportActionsUtils.isActionableJoinRequest(action) || action.originalMessage.choice !== '')) { + if (!isActionableWhisper && (!ReportActionsUtils.isActionableJoinRequest(action) || action.originalMessage.choice !== ('' as JoinWorkspaceResolution))) { return []; } diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index aa4139f8ee50..921a445b0c4e 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -44,8 +44,10 @@ type ReportFooterProps = ReportFooterOnyxProps & { /** Report object for the current report */ report?: OnyxTypes.Report; + /** Report metadata */ reportMetadata?: OnyxEntry; + /** Additional report details */ reportNameValuePairs?: OnyxEntry; /** The policy of the report */ diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.tsx b/src/pages/settings/Wallet/ExpensifyCardPage.tsx index 49686e19852c..6ab2554c2cda 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage.tsx +++ b/src/pages/settings/Wallet/ExpensifyCardPage.tsx @@ -32,7 +32,7 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {GetPhysicalCardForm} from '@src/types/form'; import type {LoginList, Card as OnyxCard, PrivatePersonalDetails} from '@src/types/onyx'; -import type {TCardDetails} from '@src/types/onyx/Card'; +import type {ExpensifyCardDetails} from '@src/types/onyx/Card'; import RedDotCardSection from './RedDotCardSection'; import CardDetails from './WalletPage/CardDetails'; @@ -101,7 +101,7 @@ function ExpensifyCardPage({ const virtualCards = useMemo(() => cardsToShow?.filter((card) => card?.nameValuePairs?.isVirtual), [cardsToShow]); const physicalCards = useMemo(() => cardsToShow?.filter((card) => !card?.nameValuePairs?.isVirtual), [cardsToShow]); - const [cardsDetails, setCardsDetails] = useState>({}); + const [cardsDetails, setCardsDetails] = useState>({}); const [isCardDetailsLoading, setIsCardDetailsLoading] = useState>({}); const [cardsDetailsErrors, setCardsDetailsErrors] = useState>({}); @@ -116,7 +116,7 @@ function ExpensifyCardPage({ // eslint-disable-next-line rulesdir/no-thenable-actions-in-views Card.revealVirtualCardDetails(revealedCardID) .then((value) => { - setCardsDetails((prevState: Record) => ({...prevState, [revealedCardID]: value as TCardDetails})); + setCardsDetails((prevState: Record) => ({...prevState, [revealedCardID]: value})); setCardsDetailsErrors((prevState) => ({ ...prevState, [revealedCardID]: '', diff --git a/src/types/onyx/Account.ts b/src/types/onyx/Account.ts index 46eac1e94aa4..05fe52382597 100644 --- a/src/types/onyx/Account.ts +++ b/src/types/onyx/Account.ts @@ -4,8 +4,10 @@ import type DismissedReferralBanners from './DismissedReferralBanners'; import type * as OnyxCommon from './OnyxCommon'; import type {TravelSettings} from './TravelSettings'; +/** Two factor authentication steps */ type TwoFactorAuthStep = ValueOf | ''; +/** Model of user account */ type Account = { /** Whether SAML is enabled for the current account */ isSAMLEnabled?: boolean; @@ -55,10 +57,19 @@ type Account = { /** Whether a sign is loading */ isLoading?: boolean; + /** Authentication failure errors */ errors?: OnyxCommon.Errors | null; + + /** Authentication success message */ success?: string; + + /** Whether the two factor authentication codes were copied */ codesAreCopied?: boolean; + + /** Current two factor authentication step */ twoFactorAuthStep?: TwoFactorAuthStep; + + /** Referral banners that the user dismissed */ dismissedReferralBanners?: DismissedReferralBanners; /** Object containing all account information necessary to connect with Spontana */ diff --git a/src/types/onyx/AccountData.ts b/src/types/onyx/AccountData.ts index 124a006ff57c..010715f15f85 100644 --- a/src/types/onyx/AccountData.ts +++ b/src/types/onyx/AccountData.ts @@ -1,15 +1,7 @@ -import type {BankName} from './Bank'; +import type {BankAccountAdditionalData} from './BankAccount'; import type * as OnyxCommon from './OnyxCommon'; -type AdditionalData = { - isP2PDebitCard?: boolean; - beneficialOwners?: string[]; - currency?: string; - bankName?: BankName; - fieldsType?: string; - country?: string; -}; - +/** Model of bank account data */ type AccountData = { /** The masked bank account number */ accountNumber?: string; @@ -38,13 +30,14 @@ type AccountData = { /** All user emails that have access to this bank account */ sharees?: string[]; + /** Institution that processes the account payments */ processor?: string; /** The bankAccountID in the bankAccounts db */ bankAccountID?: number; /** All data related to the bank account */ - additionalData?: AdditionalData; + additionalData?: BankAccountAdditionalData; /** The bank account type */ type?: string; @@ -52,6 +45,7 @@ type AccountData = { /** Any error message to show */ errors?: OnyxCommon.Errors; + /** The debit card ID */ fundID?: number; }; diff --git a/src/types/onyx/Bank.ts b/src/types/onyx/Bank.ts index 72b5fcda4788..3eee283da5c6 100644 --- a/src/types/onyx/Bank.ts +++ b/src/types/onyx/Bank.ts @@ -3,15 +3,28 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type IconAsset from '@src/types/utils/IconAsset'; +/** Bank icon configurations */ type BankIcon = { + /** Source of the icon, can be a component or an image */ icon: IconAsset; + + /** Size of the icon */ iconSize?: number; + + /** Height of the icon */ iconHeight?: number; + + /** Width of the icon */ iconWidth?: number; + + /** Icon wrapper styles */ iconStyles?: ViewStyle[]; }; +/** Bank names */ type BankName = ValueOf; + +/** Bank name keys */ type BankNameKey = keyof typeof CONST.BANK_NAMES; export type {BankIcon, BankName, BankNameKey}; diff --git a/src/types/onyx/BankAccount.ts b/src/types/onyx/BankAccount.ts index d0f80708842c..862b5aa45a4e 100644 --- a/src/types/onyx/BankAccount.ts +++ b/src/types/onyx/BankAccount.ts @@ -1,16 +1,30 @@ import type CONST from '@src/CONST'; import type AccountData from './AccountData'; +import type {BankName} from './Bank'; import type * as OnyxCommon from './OnyxCommon'; -type AdditionalData = { +/** Model of additional bank account data */ +type BankAccountAdditionalData = { + /** Is a Peer-To-Peer Debit Card */ isP2PDebitCard?: boolean; + + /** Owners that can benefit from this bank account */ beneficialOwners?: string[]; + + /** In which currency is the bank account */ currency?: string; - bankName?: string; + + /** In which bank is the bank account */ + bankName?: BankName; + + /** Whether the bank account details were obtained for local transfer or international wire */ fieldsType?: string; + + /** In which country is the bank account */ country?: string; }; +/** Model of bank account */ type BankAccount = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** The bank account type */ accountType?: typeof CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT; @@ -18,15 +32,16 @@ type BankAccount = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** string like 'Account ending in XXXX' */ description?: string; + /** Determines if the bank account is a default payment method */ isDefault?: boolean; - /* Determines if the bank account is a savings account */ + /** Determines if the bank account is a savings account */ isSavings?: boolean; - /** Date when the 3 micro amounts for validation were supposed to reach the bank account. */ + /** Date when the 3 micro amounts for validation were supposed to reach the bank account */ validateCodeExpectedDate?: string; - /** string like 'bankAccount-{}' where is the bankAccountID */ + /** string like `bankAccount-` */ key?: string; /** Alias for bankAccountID */ @@ -42,7 +57,8 @@ type BankAccount = OnyxCommon.OnyxValueWithOfflineFeedback<{ errors?: OnyxCommon.Errors; }>; +/** Record of bank accounts, indexed by bankAccountID */ type BankAccountList = Record; export default BankAccount; -export type {AccountData, AdditionalData, BankAccountList}; +export type {AccountData, BankAccountAdditionalData, BankAccountList}; diff --git a/src/types/onyx/Beta.ts b/src/types/onyx/Beta.ts index 35ed4c804ab8..1c282409aea5 100644 --- a/src/types/onyx/Beta.ts +++ b/src/types/onyx/Beta.ts @@ -1,6 +1,7 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +/** New Dot Beta features */ type Beta = ValueOf; export default Beta; diff --git a/src/types/onyx/BlockedFromConcierge.ts b/src/types/onyx/BlockedFromConcierge.ts index 4eebd537604c..ed4381076555 100644 --- a/src/types/onyx/BlockedFromConcierge.ts +++ b/src/types/onyx/BlockedFromConcierge.ts @@ -1,3 +1,4 @@ +/** Model of blocked user from concierge */ type BlockedFromConcierge = { /** The date that the user will be unblocked */ expiresAt: string; diff --git a/src/types/onyx/Card.ts b/src/types/onyx/Card.ts index 50403b982c0d..595104d4aed3 100644 --- a/src/types/onyx/Card.ts +++ b/src/types/onyx/Card.ts @@ -2,44 +2,86 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type * as OnyxCommon from './OnyxCommon'; +/** Model of Expensify card */ type Card = { + /** Card ID number */ cardID: number; + + /** Current card state */ state: ValueOf; + + /** Bank name */ bank: string; + + /** Available amount to spend */ availableSpend: number; + + /** Domain name */ domainName: string; + + /** Last four Primary Account Number digits */ lastFourPAN?: string; + + /** Current fraud state of the card */ fraud: ValueOf; + + /** Card related error messages */ errors?: OnyxCommon.Errors; + + /** Is card data loading */ isLoading?: boolean; + + /** Additional card data */ nameValuePairs?: { + /** Type of card spending limits */ limitType?: ValueOf; - cardTitle?: string; // Used only for admin-issued virtual cards + + /** User-defined nickname for a virtual card */ + cardTitle?: string; + + /** Account ID of user that issued the card */ issuedBy?: number; + + /** + * Whether the card has a custom unapproved expense limit. + * When not set, the domain unapproved expense limit is used + */ hasCustomUnapprovedExpenseLimit?: boolean; + + /** + * The maximum unapproved spend allowed on the card. + * If it's $100 and you spend $100, you need to get the expenses approved for the card to continue working + */ unapprovedExpenseLimit?: number; + + /** Card product under which the card is provisioned */ feedCountry?: string; + + /** Is a virtual card */ isVirtual?: boolean; + + /** Previous card state */ previousState?: number; + + /** Card expiration date */ expirationDate?: string; }; }; -type TCardDetails = { +/** Model of Expensify card details */ +type ExpensifyCardDetails = { + /** Card Primary Account Number */ pan: string; + + /** Card expiration date */ expiration: string; + + /** Card Verification Value number */ cvv: string; - address: { - street: string; - street2: string; - city: string; - state: string; - zip: string; - country: string; - }; }; +/** Record of Expensify cards, indexed by cardID */ type CardList = Record; export default Card; -export type {TCardDetails, CardList}; +export type {ExpensifyCardDetails, CardList}; diff --git a/src/types/onyx/Console.ts b/src/types/onyx/Console.ts index 592d23fecfa0..c8d2b714ae2b 100644 --- a/src/types/onyx/Console.ts +++ b/src/types/onyx/Console.ts @@ -1,11 +1,18 @@ import type CONST from '@src/CONST'; +/** Model of a log */ type Log = { + /** Log time */ time: Date; + + /** Log level */ level: keyof typeof CONST.DEBUG_CONSOLE.LEVELS; + + /** Log message */ message: string; }; +/** Record of captured logs */ type CapturedLogs = Record; export type {Log, CapturedLogs}; diff --git a/src/types/onyx/Credentials.ts b/src/types/onyx/Credentials.ts index 6a22eeb5af89..135cbae5fe76 100644 --- a/src/types/onyx/Credentials.ts +++ b/src/types/onyx/Credentials.ts @@ -1,3 +1,4 @@ +/** Model of user credentials */ type Credentials = { /** The email/phone the user logged in with */ login?: string; diff --git a/src/types/onyx/Currency.ts b/src/types/onyx/Currency.ts index b8d6f8dda88b..69b4203cdbf1 100644 --- a/src/types/onyx/Currency.ts +++ b/src/types/onyx/Currency.ts @@ -1,3 +1,4 @@ +/** Model of currency */ type Currency = { /** Symbol for the currency */ symbol: string; @@ -21,6 +22,7 @@ type Currency = { cacheBurst?: number; }; +/** Record of currencies, index by currency code */ type CurrencyList = Record; export default Currency; diff --git a/src/types/onyx/CustomStatusDraft.ts b/src/types/onyx/CustomStatusDraft.ts index 73c8fa4baa1a..d29061f5b5ed 100644 --- a/src/types/onyx/CustomStatusDraft.ts +++ b/src/types/onyx/CustomStatusDraft.ts @@ -1,3 +1,4 @@ +/** Model of custom status draft */ type CustomStatusDraft = { /** The emoji code of the draft status */ emojiCode?: string; diff --git a/src/types/onyx/DismissedReferralBanners.ts b/src/types/onyx/DismissedReferralBanners.ts index 86937d3bfbaf..92b3da647759 100644 --- a/src/types/onyx/DismissedReferralBanners.ts +++ b/src/types/onyx/DismissedReferralBanners.ts @@ -1,10 +1,20 @@ import type CONST from '@src/CONST'; +/** Model of dismissed referral banners */ type DismissedReferralBanners = { + /** Is 'Submit expense' referral dismissed */ [CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SUBMIT_EXPENSE]?: boolean; + + /** Is 'Start chat' referral dismissed */ [CONST.REFERRAL_PROGRAM.CONTENT_TYPES.START_CHAT]?: boolean; + + /** Is 'Pay someone' referral dismissed */ [CONST.REFERRAL_PROGRAM.CONTENT_TYPES.PAY_SOMEONE]?: boolean; + + /** Is 'Refer friend' referral dismissed */ [CONST.REFERRAL_PROGRAM.CONTENT_TYPES.REFER_FRIEND]?: boolean; + + /** Is 'Share code' referral dismissed */ [CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE]?: boolean; }; diff --git a/src/types/onyx/Download.ts b/src/types/onyx/Download.ts index 9c6c2f61f716..de9e91064ed1 100644 --- a/src/types/onyx/Download.ts +++ b/src/types/onyx/Download.ts @@ -1,3 +1,4 @@ +/** Model of file download */ type Download = { /** If a file download is happening */ isDownloading: boolean; diff --git a/src/types/onyx/FrequentlyUsedEmoji.ts b/src/types/onyx/FrequentlyUsedEmoji.ts index c8f6a5179fc6..82de844c0c6f 100644 --- a/src/types/onyx/FrequentlyUsedEmoji.ts +++ b/src/types/onyx/FrequentlyUsedEmoji.ts @@ -1,3 +1,4 @@ +/** Model of frequently used emoji */ type FrequentlyUsedEmoji = { /** The emoji code */ code: string; diff --git a/src/types/onyx/Fund.ts b/src/types/onyx/Fund.ts index a3c0a95849d1..8ee8fe42e734 100644 --- a/src/types/onyx/Fund.ts +++ b/src/types/onyx/Fund.ts @@ -1,41 +1,75 @@ import type CONST from '@src/CONST'; import type {BankName} from './Bank'; +import type {BankAccountAdditionalData} from './BankAccount'; import type * as OnyxCommon from './OnyxCommon'; -type AdditionalData = { - isBillingCard?: boolean; - isP2PDebitCard?: boolean; -}; - +/** Model of debit card account data */ type AccountData = { - additionalData?: AdditionalData; + /** Additional account data */ + additionalData?: BankAccountAdditionalData; + + /** Address name */ addressName?: string; + + /** Address state */ addressState?: string; + + /** Address street */ addressStreet?: string; + + /** Address zip code */ addressZip?: number; + + /** Debit card month */ cardMonth?: number; - /** The masked credit card number */ + /** The masked debit card number */ cardNumber?: string; + /** Debit card year */ cardYear?: number; + + /** Debit card creation date */ created?: string; + + /** Debit card currency */ currency?: string; + + /** Debit card ID number */ fundID?: number; + + /** Debit card bank name */ bank?: BankName; }; +/** Model of debit card fund */ type Fund = OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** All data related to the debit card */ accountData?: AccountData; + + /** Debit card type */ accountType?: typeof CONST.PAYMENT_METHODS.DEBIT_CARD; + + /** Debit card description */ description?: string; + + /** String like `fund-` */ key?: string; + + /** Alias for fundID */ methodID?: number; + + /** Debit card title */ title?: string; + + /** Is default debit card */ isDefault?: boolean; + + /** Debit card related error messages */ errors?: OnyxCommon.Errors; }>; +/** Record of debit card funds, indexed by fundID */ type FundList = Record; export default Fund; diff --git a/src/types/onyx/IOU.ts b/src/types/onyx/IOU.ts index 8ffac34f2512..59db6db0a35c 100644 --- a/src/types/onyx/IOU.ts +++ b/src/types/onyx/IOU.ts @@ -1,67 +1,171 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +import type {IOUType} from '@src/CONST'; import type {Icon} from './OnyxCommon'; import type Report from './Report'; +/** Model of IOU participant */ type Participant = { + /** IOU participant account ID */ accountID?: number; + + /** IOU participant login */ login?: string; + + /** IOU participant display name */ displayName?: string; + + /** Is IOU participant associated with policy expense chat */ isPolicyExpenseChat?: boolean; + + /** Whether the IOU participant is an invoice receiver */ isInvoiceRoom?: boolean; + + /** Is IOU participant associated with is own policy expense chat */ isOwnPolicyExpenseChat?: boolean; + + /** Type of chat associated with IOU participant */ chatType?: ValueOf; + + /** IOU participant report ID */ reportID?: string; + + /** IOU participant policy ID */ policyID?: string; + + /** Is IOU participant selected in list */ selected?: boolean; + + /** Text that IOU participant display name and login, if available, for searching purposes */ searchText?: string; + + /** Additional text shown in lists (participant phone number or display name) */ alternateText?: string; + + /** IOU participant first name */ firstName?: string; + + /** Icons used in lists (participant avatar) */ icons?: Icon[]; + + /** Key to be used in lists (participant account ID) */ keyForList?: string; + + /** IOU participant last name */ lastName?: string; + + /** IOU participant phone number */ phoneNumber?: string; + + /** Text to be displayed in lists (participant display name) */ text?: string; + + /** Is IOU participant selected in list */ isSelected?: boolean; + + /** Is IOU participant the current user */ isSelfDM?: boolean; + + /** Whether the IOU participant is an invoice sender */ isSender?: boolean; - iouType?: string; - item?: Report; + + /** The type of IOU report, i.e. split, request, send, track */ + iouType?: IOUType; + + /** When the participant is associated with a policy expense chat, this is the account ID of the policy owner */ ownerAccountID?: number; + + /** The report associated to the IOU participant */ + item?: Report; }; +/** Model of IOU split */ type Split = { + /** IOU split participant email */ email?: string; + + /** IOU split participant amount paid */ amount?: number; + + /** IOU split participant account ID */ accountID?: number; + + /** Chat report ID */ chatReportID?: string; + + /** IOU report ID */ iouReportID?: string; + + /** Report Action ID */ reportActionID?: string; + + /** Transaction ID */ transactionID?: string; + + /** Policy ID */ policyID?: string; + + /** Created chat report action ID */ createdChatReportActionID?: string; + + /** Created IOU report action ID */ createdIOUReportActionID?: string; + + /** Report preview report action ID */ reportPreviewReportActionID?: string; + + /** Transaction thread report ID */ transactionThreadReportID?: string; + + /** Created report action ID for thread */ createdReportActionIDForThread?: string; + + /** IOU tax amount */ taxAmount?: number; }; +/** Model of IOU request */ type IOU = { + /** ID of the IOU request */ id: string; + + /** Amount requested in IOU */ amount?: number; + /** Selected Currency Code of the current IOU */ currency?: string; + + /** Comment of the IOU request creator */ comment?: string; + + /** Category assigned to the IOU request */ category?: string; + + /** Merchant where the amount was spent */ merchant?: string; + + /** Date timestamp when the IOU request was created */ created?: string; + + /** Local file path of the expense receipt */ receiptPath?: string; + + /** File name of the expense receipt */ receiptFilename?: string; + + /** Transaction ID assigned to the IOU request */ transactionID?: string; + + /** Users involved in the IOU request */ participants?: Participant[]; + + /** Tag assigned to the IOU request */ tag?: string; + + /** Whether the IOU request is billable */ billable?: boolean; + + /** Whether the IOU request is to be split with multiple users */ isSplitRequest?: boolean; }; diff --git a/src/types/onyx/IntroSelected.ts b/src/types/onyx/IntroSelected.ts index 14a0d2f70dfe..6850f651ca2a 100644 --- a/src/types/onyx/IntroSelected.ts +++ b/src/types/onyx/IntroSelected.ts @@ -1,5 +1,6 @@ import type {OnboardingPurposeType} from '@src/CONST'; +/** Model of onboarding */ type IntroSelected = { /** The choice that the user selected in the engagement modal */ choice: OnboardingPurposeType; diff --git a/src/types/onyx/InvitedEmailsToAccountIDs.ts b/src/types/onyx/InvitedEmailsToAccountIDs.ts index 929d21746682..1f233e7c968c 100644 --- a/src/types/onyx/InvitedEmailsToAccountIDs.ts +++ b/src/types/onyx/InvitedEmailsToAccountIDs.ts @@ -1,3 +1,4 @@ +/** Record of workspace invited accountIDs, indexed by login name of inviter */ type InvitedEmailsToAccountIDs = Record; export default InvitedEmailsToAccountIDs; diff --git a/src/types/onyx/LastPaymentMethod.ts b/src/types/onyx/LastPaymentMethod.ts index 677a23fa9586..ea0c644fc730 100644 --- a/src/types/onyx/LastPaymentMethod.ts +++ b/src/types/onyx/LastPaymentMethod.ts @@ -1,3 +1,4 @@ +/** Record of last payment methods, indexed by policy id */ type LastPaymentMethod = Record; export default LastPaymentMethod; diff --git a/src/types/onyx/LastSelectedDistanceRates.ts b/src/types/onyx/LastSelectedDistanceRates.ts index 1db1cf32b160..3b09864db905 100644 --- a/src/types/onyx/LastSelectedDistanceRates.ts +++ b/src/types/onyx/LastSelectedDistanceRates.ts @@ -1,3 +1,4 @@ +/** Record of last selected distance rates, indexed by policy id */ type LastSelectedDistanceRates = Record; export default LastSelectedDistanceRates; diff --git a/src/types/onyx/Locale.ts b/src/types/onyx/Locale.ts index 89d7636009d7..37c340945bf1 100644 --- a/src/types/onyx/Locale.ts +++ b/src/types/onyx/Locale.ts @@ -1,6 +1,7 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +/** Available locale values */ type Locale = ValueOf; export default Locale; diff --git a/src/types/onyx/Login.ts b/src/types/onyx/Login.ts index fec12da1b8e4..d89b7f2a29a3 100644 --- a/src/types/onyx/Login.ts +++ b/src/types/onyx/Login.ts @@ -1,5 +1,6 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of user login data */ type Login = OnyxCommon.OnyxValueWithOfflineFeedback< { /** Phone/Email associated with user */ @@ -20,6 +21,7 @@ type Login = OnyxCommon.OnyxValueWithOfflineFeedback< 'defaultLogin' | 'validateLogin' | 'addedLogin' | 'deletedLogin' >; +/** Record of user login data, indexed by partnerUserID */ type LoginList = Record; export default Login; diff --git a/src/types/onyx/MapboxAccessToken.ts b/src/types/onyx/MapboxAccessToken.ts index bea23bcf86c4..9af8621d09b4 100644 --- a/src/types/onyx/MapboxAccessToken.ts +++ b/src/types/onyx/MapboxAccessToken.ts @@ -1,6 +1,12 @@ +/** Model of Mapbox access token data */ type MapboxAccessToken = { + /** Mapbox access token */ token: string; + + /** Mapbox access token expiration date */ expiration: string; + + /** Mapbox access error messages */ errors: string[]; }; diff --git a/src/types/onyx/Modal.ts b/src/types/onyx/Modal.ts index 1ea96cd283ce..b4b761cc8677 100644 --- a/src/types/onyx/Modal.ts +++ b/src/types/onyx/Modal.ts @@ -1,3 +1,4 @@ +/** Modal state */ type Modal = { /** Indicates when an Alert modal is about to be visible */ willAlertModalBecomeVisible?: boolean; @@ -8,6 +9,7 @@ type Modal = { /** Indicates if there is a modal currently visible or not */ isVisible?: boolean; + /** Indicates if the modal is a popover */ isPopover?: boolean; }; diff --git a/src/types/onyx/Network.ts b/src/types/onyx/Network.ts index 9ccdc103c0f8..4ef24a314647 100644 --- a/src/types/onyx/Network.ts +++ b/src/types/onyx/Network.ts @@ -1,5 +1,6 @@ import type {NetworkStatus} from '@libs/NetworkConnection'; +/** Model of network state */ type Network = { /** Is the network currently offline or not */ isOffline: boolean; diff --git a/src/types/onyx/NewGroupChatDraft.ts b/src/types/onyx/NewGroupChatDraft.ts index 008475212cbe..9e4ad3c54299 100644 --- a/src/types/onyx/NewGroupChatDraft.ts +++ b/src/types/onyx/NewGroupChatDraft.ts @@ -1,11 +1,21 @@ +/** Selected chat participant */ type SelectedParticipant = { + /** Participant ID */ accountID: number; + + /** Participant login name */ login: string; }; +/** Model of new group chat draft */ type NewGroupChatDraft = { + /** New group chat participants */ participants: SelectedParticipant[]; + + /** New group chat name */ reportName: string | null; + + /** New group chat avatar URI */ avatarUri: string | null; }; export type {SelectedParticipant}; diff --git a/src/types/onyx/Onboarding.ts b/src/types/onyx/Onboarding.ts index 3559dea90450..9860dd93f9ce 100644 --- a/src/types/onyx/Onboarding.ts +++ b/src/types/onyx/Onboarding.ts @@ -1,3 +1,4 @@ +/** Model of onboarding */ type Onboarding = { /** A Boolean that informs whether the user has completed the guided setup onboarding flow */ hasCompletedGuidedSetupFlow: boolean; diff --git a/src/types/onyx/OnyxCommon.ts b/src/types/onyx/OnyxCommon.ts index 8b96a89a2a1b..688e2ef73ff8 100644 --- a/src/types/onyx/OnyxCommon.ts +++ b/src/types/onyx/OnyxCommon.ts @@ -3,10 +3,13 @@ import type {MaybePhraseKey} from '@libs/Localize'; import type {AvatarSource} from '@libs/UserUtils'; import type CONST from '@src/CONST'; +/** Pending onyx actions */ type PendingAction = ValueOf | null; +/** Mapping of form fields with pending actions */ type PendingFields = {[key in Exclude]?: PendingAction}; +/** Offline properties that store information about data that was written while the app was offline */ type OfflineFeedback = { /** The type of action that's pending */ pendingAction?: PendingAction; @@ -15,14 +18,23 @@ type OfflineFeedback = { pendingFields?: PendingFields; }; +/** Onyx data with offline properties that store information about data that was written while the app was offline */ type OnyxValueWithOfflineFeedback = keyof TOnyx extends string ? TOnyx & OfflineFeedback : never; +/** Mapping of form fields with errors */ type ErrorFields = Record; +/** Mapping of form fields with error translation keys and variables */ type Errors = Record; +/** + * Types of avatars + ** avatar - user avatar + ** workspace - workspace avatar + */ type AvatarType = typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; +/** Icon properties */ type Icon = { /** Avatar source to display */ source: AvatarSource; diff --git a/src/types/onyx/OnyxUpdatesFromServer.ts b/src/types/onyx/OnyxUpdatesFromServer.ts index 0877ea6755f8..99d565ede08f 100644 --- a/src/types/onyx/OnyxUpdatesFromServer.ts +++ b/src/types/onyx/OnyxUpdatesFromServer.ts @@ -3,25 +3,51 @@ import CONST from '@src/CONST'; import type Request from './Request'; import type Response from './Response'; +/** Model of a onyx server update */ type OnyxServerUpdate = OnyxUpdate & { + /** Whether the update should notify UI */ shouldNotify?: boolean; + + /** Whether the update should be shown as a push notification */ shouldShowPushNotification?: boolean; }; +/** Model of a onyx update event */ type OnyxUpdateEvent = { + /** Type of the update event received from the server */ eventType: string; + + /** Collections of data updates */ data: OnyxServerUpdate[]; }; +/** Model of onyx server updates */ type OnyxUpdatesFromServer = { + /** Delivery method of onyx updates */ type: 'https' | 'pusher' | 'airship'; + + /** Last update ID from server */ lastUpdateID: number | string; + + /** Previous update ID from server */ previousUpdateID: number | string; + + /** Request data sent to the server */ request?: Request; + + /** Response data from server */ response?: Response; + + /** Collection of onyx updates */ updates?: OnyxUpdateEvent[]; }; +/** + * Helper function to determine if onyx update received from server is valid + * + * @param value - represent the onyx update received from the server + * @returns boolean indicating if the onyx update received from the server is valid + */ function isValidOnyxUpdateFromServer(value: unknown): value is OnyxUpdatesFromServer { if (!value || typeof value !== 'object') { return false; diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index c62bd8f34f24..8f645a411520 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -2,9 +2,16 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; +/** Types of join workspace resolutions */ +type JoinWorkspaceResolution = ValueOf; + +/** Types of payments methods */ type PaymentMethodType = DeepValueOf; +/** Names of report actions */ type ActionName = DeepValueOf; + +/** Names of task report actions */ type OriginalMessageActionName = | 'ADDCOMMENT' | 'APPROVED' @@ -29,329 +36,600 @@ type OriginalMessageActionName = | 'ACTIONABLETRACKEXPENSEWHISPER' | 'TRIPPREVIEW' | ValueOf; + +/** Model of `approved` report action */ type OriginalMessageApproved = { + /** Approved */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.APPROVED; - originalMessage: unknown; + + /** Content of the original message */ + originalMessage: { + /** Approved expense amount */ + amount: number; + + /** Currency of the approved expense amount */ + currency: string; + + /** Report ID of the expense */ + expenseReportID: string; + }; }; + +/** Types of sources of original message */ type OriginalMessageSource = 'Chronos' | 'email' | 'ios' | 'android' | 'web' | ''; +/** Model of `hold` report action */ type OriginalMessageHold = { + /** Hold */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.HOLD; + + /** Content of the original message */ originalMessage: unknown; }; +/** Model of `hold comment` report action */ type OriginalMessageHoldComment = { + /** Hold comment */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.HOLD_COMMENT; + + /** Content of the original message */ originalMessage: unknown; }; +/** Model of `unhold` report action */ type OriginalMessageUnHold = { + /** Unhold */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.UNHOLD; + + /** Content of the original message */ originalMessage: unknown; }; +/** Details provided when sending money */ type IOUDetails = { + /** How much was sent */ amount: number; + + /** Optional comment */ comment?: string; + + /** Currency of the money sent */ currency: string; }; +/** Model of original message of `IOU` report action */ type IOUMessage = { - /** The ID of the iou transaction */ + /** The ID of the `IOU` transaction */ IOUTransactionID?: string; + + /** ID of the `IOU` report */ IOUReportID?: string; + + /** ID of the expense report */ expenseReportID?: string; + + /** How much was transactioned */ amount: number; + + /** Optional comment */ comment?: string; + + /** Currency of the transactioned money */ currency: string; + + /** When was the `IOU` last modified */ lastModified?: string; + + /** Who participated in the transaction, by accountID */ participantAccountIDs?: number[]; + + /** Type of `IOU` report action */ type: ValueOf; + + /** If the action was cancelled, this is the reason for the cancellation */ cancellationReason?: string; + + /** Type of payment method used in transaction */ paymentType?: PaymentMethodType; + + /** Timestamp of when the `IOU` report action was deleted */ deleted?: string; + /** Only exists when we are sending money */ IOUDetails?: IOUDetails; + + /** Collection of accountIDs of users mentioned in message */ whisperedTo?: number[]; }; +/** Model of original message of `reimbursed dequeued` report action */ type ReimbursementDeQueuedMessage = { - cancellationReason: string; + /** Why the reimbursement was cancelled */ + cancellationReason: ValueOf; + + /** ID of the `expense` report */ expenseReportID?: string; + + /** Amount that wasn't reimbursed */ amount: number; + + /** Currency of the money that wasn't reimbursed */ currency: string; }; +/** Model of `IOU` report action */ type OriginalMessageIOU = { + /** IOU */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.IOU; - originalMessage: IOUMessage; -}; -type FlagSeverityName = ValueOf< - Pick< - typeof CONST.MODERATION, - 'FLAG_SEVERITY_SPAM' | 'FLAG_SEVERITY_INCONSIDERATE' | 'FLAG_SEVERITY_INTIMIDATION' | 'FLAG_SEVERITY_BULLYING' | 'FLAG_SEVERITY_HARASSMENT' | 'FLAG_SEVERITY_ASSAULT' - > ->; -type FlagSeverity = { - accountID: number; - timestamp: string; + /** Content of the original message */ + originalMessage: IOUMessage; }; +/** Names of moderation decisions */ type DecisionName = ValueOf< Pick< typeof CONST.MODERATION, 'MODERATOR_DECISION_PENDING' | 'MODERATOR_DECISION_PENDING_HIDE' | 'MODERATOR_DECISION_PENDING_REMOVE' | 'MODERATOR_DECISION_APPROVED' | 'MODERATOR_DECISION_HIDDEN' > >; + +/** Model of moderator decision */ type Decision = { + /** Name of the decision */ decision: DecisionName; + + /** When was the decision name */ timestamp?: string; }; +/** Model of user reaction */ type User = { + /** Account ID of the user that reacted to the comment */ accountID: number; + + /** What's the skin tone of the user reaction */ skinTone: number; }; +/** Model of comment reaction */ type Reaction = { + /** Which emoji was used to react to the comment */ emoji: string; + + /** Which users reacted with this emoji */ users: User[]; }; +/** Model of original message of `closed` report action */ type Closed = { + /** Name of the policy */ policyName: string; + + /** What was the reason to close the report */ reason: ValueOf; + + /** When was the message last modified */ lastModified?: string; + + /** If the report was closed because accounts got merged, then this is the new account ID */ newAccountID?: number; + + /** If the report was closed because accounts got merged, then this is the old account ID */ oldAccountID?: number; }; +/** Model of `add comment` report action */ type OriginalMessageAddComment = { + /** Add comment */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT; + + /** Content of the original message */ originalMessage: { + /** HTML content of the comment */ html: string; + + /** Origin of the comment */ source?: OriginalMessageSource; + + /** When was the comment last modified */ lastModified?: string; + + /** ID of the task report */ taskReportID?: string; - edits?: string[]; - childReportID?: string; - isDeletedParentAction?: boolean; - flags?: Record; - moderationDecisions?: Decision[]; + + /** Collection of accountIDs of users mentioned in message */ whisperedTo: number[]; - reactions?: Reaction[]; }; }; +/** Model of `actionable mention whisper` report action */ type OriginalMessageActionableMentionWhisper = { + /** Actionable mention whisper */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER; + + /** Content of the original message */ originalMessage: { + /** Account IDs of users that aren't members of the room */ inviteeAccountIDs: number[]; - inviteeEmails: string; - lastModified: string; - reportID: number; + + /** Decision on whether to invite users that were mentioned but aren't members or do nothing */ resolution?: ValueOf | null; + + /** Collection of accountIDs of users mentioned in message */ whisperedTo?: number[]; }; }; +/** Model of `actionable report mention whisper` report action */ type OriginalMessageActionableReportMentionWhisper = { + /** Actionable report mention whisper */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER; + + /** Content of the original message */ originalMessage: { - reportNames: string[]; - mentionedAccountIDs: number[]; - reportActionID: number; - reportID: number; - lastModified: string; + /** Decision on whether to create a report that were mentioned but doesn't exist or do nothing */ resolution?: ValueOf | null; + + /** Collection of accountIDs of users mentioned in message */ whisperedTo?: number[]; }; }; +/** Model of `submitted` report action */ type OriginalMessageSubmitted = { + /** Submitted */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.SUBMITTED; - originalMessage: unknown; + + /** Content of the original message */ + originalMessage: { + /** Approved expense amount */ + amount: number; + + /** Currency of the approved expense amount */ + currency: string; + + /** Report ID of the expense */ + expenseReportID: string; + }; }; +/** Model of `closed` report action */ type OriginalMessageClosed = { + /** Closed */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.CLOSED; + + /** Content of the original message */ originalMessage: Closed; }; +/** Model of `created` report action */ type OriginalMessageCreated = { + /** Created */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.CREATED; + + /** Content of the original message */ originalMessage?: unknown; }; +/** Model of `marked reimbursed` report action */ type OriginalMessageMarkedReimbursed = { + /** Marked reimbursed */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED; + + /** Content of the original message */ originalMessage?: unknown; }; +/** Model of `renamed` report action, created when chat rooms get renamed */ type OriginalMessageRenamed = { + /** Renamed */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.RENAMED; + + /** Content of the original message */ originalMessage: { + /** Renamed room comment */ html: string; + + /** When was report action last modified */ lastModified: string; + + /** Old room name */ oldName: string; + + /** New room name */ newName: string; }; }; +/** Model of Chronos OOO Timestamp */ type ChronosOOOTimestamp = { + /** Date timestamp */ date: string; - timezone: string; - // eslint-disable-next-line @typescript-eslint/naming-convention - timezone_type: number; }; +/** Model of change log */ type ChangeLog = { + /** Account IDs of users that either got invited or removed from the room */ targetAccountIDs?: number[]; + + /** Name of the chat room */ roomName?: string; + + /** ID of the report */ reportID?: number; }; +/** Model of Chronos OOO Event */ type ChronosOOOEvent = { + /** ID of the OOO event */ id: string; + + /** How many days will the user be OOO */ lengthInDays: number; + + /** Description of the OOO state */ summary: string; + + /** When will the OOO state start */ start: ChronosOOOTimestamp; + + /** When will the OOO state end */ end: ChronosOOOTimestamp; }; +/** Model of modified expense */ +type ModifiedExpense = { + /** Old content of the comment */ + oldComment?: string; + + /** Edited content of the comment */ + newComment?: string; + + /** Edited merchant name */ + merchant?: string; + + /** Old creation date timestamp */ + oldCreated?: string; + + /** Edited creation date timestamp */ + created?: string; + + /** Old merchant name */ + oldMerchant?: string; + + /** Old expense amount */ + oldAmount?: number; + + /** Edited expense amount */ + amount?: number; + + /** Old expense amount currency */ + oldCurrency?: string; + + /** Edited expense amount currency */ + currency?: string; + + /** Edited expense category */ + category?: string; + + /** Old expense category */ + oldCategory?: string; + + /** Edited expense tag */ + tag?: string; + + /** Old expense tag */ + oldTag?: string; + + /** Edited billable */ + billable?: string; + + /** Old billable */ + oldBillable?: string; + + /** Old expense tag amount */ + oldTaxAmount?: number; + + /** Edited expense tax amount */ + taxAmount?: number; + + /** Edited expense tax rate */ + taxRate?: string; + + /** Old expense tax rate */ + oldTaxRate?: string; + + /** Collection of accountIDs of users mentioned in expense report */ + whisperedTo?: number[]; +}; + +/** Model of `Chronos OOO List` report action */ type OriginalMessageChronosOOOList = { + /** Chronos OOO list */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.CHRONOS_OOO_LIST; + + /** Content of the original message */ originalMessage: { - edits: string[]; + /** Collection of OOO events to show in report action */ events: ChronosOOOEvent[]; - html: string; - lastModified: string; }; }; +/** Model of `report preview` report action */ type OriginalMessageReportPreview = { + /** Report preview */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW; + + /** Content of the original message */ originalMessage: { + /** ID of the report to be previewed */ linkedReportID: string; - lastModified?: string; + + /** Collection of accountIDs of users mentioned in report */ whisperedTo?: number[]; }; }; +/** Model of `policy change log` report action */ type OriginalMessagePolicyChangeLog = { + /** Policy change log */ actionName: ValueOf; + + /** Content of the original message */ originalMessage: ChangeLog; }; +/** Model of `join policy changelog` report action */ type OriginalMessageJoinPolicyChangeLog = { + /** Actionable join request */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_JOIN_REQUEST; + + /** Content of the original message */ originalMessage: { - choice: string; - email: string; - inviterEmail: string; - lastModified: string; + /** What was the invited user decision */ + choice: JoinWorkspaceResolution; + + /** ID of the affected policy */ policyID: string; }; }; +/** Model of `room change log` report action */ type OriginalMessageRoomChangeLog = { + /** Room change log */ actionName: ValueOf; + + /** Content of the original message */ originalMessage: ChangeLog; }; +/** Model of `policy task` report action */ type OriginalMessagePolicyTask = { + /** Policy task */ actionName: | typeof CONST.REPORT.ACTIONS.TYPE.TASK_EDITED | typeof CONST.REPORT.ACTIONS.TYPE.TASK_CANCELLED | typeof CONST.REPORT.ACTIONS.TYPE.TASK_COMPLETED | typeof CONST.REPORT.ACTIONS.TYPE.TASK_REOPENED | typeof CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE; + + /** Content of the original message */ originalMessage: unknown; }; +/** Model of `modified expense` report action */ type OriginalMessageModifiedExpense = { + /** Modified expense */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE; - originalMessage: { - oldMerchant?: string; - merchant?: string; - oldCurrency?: string; - currency?: string; - oldAmount?: number; - amount?: number; - oldComment?: string; - newComment?: string; - oldCreated?: string; - created?: string; - oldCategory?: string; - category?: string; - oldTag?: string; - tag?: string; - oldTaxAmount?: number; - taxAmount?: number; - oldTaxRate?: string; - taxRate?: string; - oldBillable?: string; - billable?: string; - whisperedTo?: number[]; - }; + + /** Content of the original message */ + originalMessage: ModifiedExpense; }; +/** Model of `reimbursement queued` report action */ type OriginalMessageReimbursementQueued = { + /** Reimbursement queued */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_QUEUED; + + /** Content of the original message */ originalMessage: { + /** How is the payment getting reimbursed */ paymentType: DeepValueOf; }; }; +/** Model of `actionable tracked expense whisper` report action */ type OriginalMessageActionableTrackedExpenseWhisper = { + /** Actionable track expense whisper */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_TRACK_EXPENSE_WHISPER; + + /** Content of the original message */ originalMessage: { + /** ID of the transaction */ transactionID: string; + + /** When was the tracked expense whisper last modified */ lastModified: string; + + /** What was the decision of the user */ resolution?: ValueOf; }; }; +/** Model of `reimbursement dequeued` report action */ type OriginalMessageReimbursementDequeued = { + /** Reimbursement dequeued */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_DEQUEUED; - originalMessage: { - expenseReportID: string; - }; + + /** Content of the original message */ + originalMessage: ReimbursementDeQueuedMessage; }; +/** Model of `moved` report action */ type OriginalMessageMoved = { + /** Moved */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.MOVED; + + /** Content of the original message */ originalMessage: { + /** ID of the old policy */ fromPolicyID: string; + + /** ID of the new policy */ toPolicyID: string; + + /** ID of the new parent report */ newParentReportID: string; + + /** ID of the moved report */ movedReportID: string; }; }; +/** Model of `merged with cash transaction` report action */ type OriginalMessageMergedWithCashTransaction = { + /** Merged with cash transaction */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.MERGED_WITH_CASH_TRANSACTION; + + /** Content of the original message */ originalMessage: Record; // No data is sent with this action }; +/** Model of `dismissed violation` report action */ type OriginalMessageDismissedViolation = { + /** Dismissed violation */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.DISMISSED_VIOLATION; + + /** Content of the original message */ originalMessage: { + /** Why the violation was dismissed */ reason: string; + + /** Name of the violation */ violationName: string; }; }; +/** Model of `trip room preview` report action */ type OriginalMessageTripRoomPreview = { + /** Trip Room Preview */ actionName: typeof CONST.REPORT.ACTIONS.TYPE.TRIPPREVIEW; + + /** Content of the original message */ originalMessage: { + /** ID of the report to be previewed */ linkedReportID: string; + + /** When was report action last modified */ lastModified?: string; + + /** Collection of accountIDs of users mentioned in report */ whisperedTo?: number[]; }; }; +/** Model of report action */ type OriginalMessage = | OriginalMessageApproved | OriginalMessageIOU @@ -383,6 +661,7 @@ type OriginalMessage = export default OriginalMessage; export type { + JoinWorkspaceResolution, ChronosOOOEvent, Decision, Reaction, @@ -392,6 +671,9 @@ export type { Closed, OriginalMessageActionName, ChangeLog, + ModifiedExpense, + OriginalMessageApproved, + OriginalMessageSubmitted, OriginalMessageIOU, OriginalMessageCreated, OriginalMessageRenamed, diff --git a/src/types/onyx/PaymentMethod.ts b/src/types/onyx/PaymentMethod.ts index 4b3a4c8986fb..b95f890939eb 100644 --- a/src/types/onyx/PaymentMethod.ts +++ b/src/types/onyx/PaymentMethod.ts @@ -3,12 +3,24 @@ import type IconAsset from '@src/types/utils/IconAsset'; import type BankAccount from './BankAccount'; import type Fund from './Fund'; +/** Model of a payment method */ type PaymentMethod = (BankAccount | Fund) & { + /** Text shown under menu item title */ description: string; + + /** Source of the menu item icon, which can be a component or an image asset */ icon: IconAsset; + + /** Size of the menu item icon */ iconSize?: number; + + /** Height of the menu item icon */ iconHeight?: number; + + /** Width of the menu item icon */ iconWidth?: number; + + /** Icon wrapper styles */ iconStyles?: ViewStyle[]; }; diff --git a/src/types/onyx/PersonalBankAccount.ts b/src/types/onyx/PersonalBankAccount.ts index 3e52a3cf59f3..b36e7754ca23 100644 --- a/src/types/onyx/PersonalBankAccount.ts +++ b/src/types/onyx/PersonalBankAccount.ts @@ -1,6 +1,7 @@ import type {Route} from '@src/ROUTES'; import type * as OnyxCommon from './OnyxCommon'; +/** Model of personal bank account */ type PersonalBankAccount = { /** An error message to display to the user */ errors?: OnyxCommon.Errors; diff --git a/src/types/onyx/PersonalDetails.ts b/src/types/onyx/PersonalDetails.ts index b7c96998080c..939835028392 100644 --- a/src/types/onyx/PersonalDetails.ts +++ b/src/types/onyx/PersonalDetails.ts @@ -2,8 +2,10 @@ import type {AvatarSource} from '@libs/UserUtils'; import type TIMEZONES from '@src/TIMEZONES'; import type * as OnyxCommon from './OnyxCommon'; +/** Selectable timezones */ type SelectedTimezone = (typeof TIMEZONES)[number]; +/** Model of timezone */ type Timezone = { /** Value of selected timezone */ selected?: SelectedTimezone; @@ -12,6 +14,7 @@ type Timezone = { automatic?: boolean; }; +/** Model of user status */ type Status = { /** The emoji code of the status */ emojiCode: string; @@ -23,6 +26,7 @@ type Status = { clearAfter: string; // ISO 8601 format; }; +/** Model of user personal details */ type PersonalDetails = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** ID of the current user from their personal details */ accountID: number; @@ -48,6 +52,7 @@ type PersonalDetails = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Avatar thumbnail URL of the current user from their personal details */ avatarThumbnail?: string; + /** Avatar original file name with extension */ originalFileName?: string; /** Flag to set when Avatar uploading */ @@ -78,11 +83,13 @@ type PersonalDetails = OnyxCommon.OnyxValueWithOfflineFeedback<{ status?: Status; }>; +/** Model of personal details metadata */ type PersonalDetailsMetadata = { /** Whether we are waiting for the data to load via the API */ isLoading?: boolean; }; +/** Record of user personal details, indexed by user id */ type PersonalDetailsList = Record; export default PersonalDetails; diff --git a/src/types/onyx/PlaidBankAccount.ts b/src/types/onyx/PlaidBankAccount.ts index 7620c4aee367..6e59fc015ca4 100644 --- a/src/types/onyx/PlaidBankAccount.ts +++ b/src/types/onyx/PlaidBankAccount.ts @@ -1,3 +1,4 @@ +/** Model of plaid bank account data */ type PlaidBankAccount = { /** Masked account number */ accountNumber: string; diff --git a/src/types/onyx/PlaidData.ts b/src/types/onyx/PlaidData.ts index 8ec93119cbd8..8f8e16324176 100644 --- a/src/types/onyx/PlaidData.ts +++ b/src/types/onyx/PlaidData.ts @@ -1,6 +1,7 @@ import type * as OnyxCommon from './OnyxCommon'; import type PlaidBankAccount from './PlaidBankAccount'; +/** Model of plaid data */ type PlaidData = { /** Name of the bank */ bankName?: string; @@ -14,7 +15,10 @@ type PlaidData = { /** List of plaid bank accounts */ bankAccounts?: PlaidBankAccount[]; + /** Whether the data is being fetched from server */ isLoading?: boolean; + + /** Error messages to show in UI */ errors: OnyxCommon.Errors; }; diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 0137f1f55bc5..ad8575a81829 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -5,58 +5,114 @@ import type * as OnyxTypes from '.'; import type * as OnyxCommon from './OnyxCommon'; import type {WorkspaceTravelSettings} from './TravelSettings'; +/** Distance units */ type Unit = 'mi' | 'km'; +/** Tax rate attributes of the policy distance rate */ type TaxRateAttributes = { + /** Percentage of the tax that can be reclaimable */ taxClaimablePercentage?: number; + + /** External ID associated to this tax rate */ taxRateExternalID?: string; }; +/** Model of policy distance rate */ type Rate = OnyxCommon.OnyxValueWithOfflineFeedback< { + /** Name of the distance rate */ name?: string; + + /** Amount to be reimbursed per distance unit travelled */ rate?: number; + + /** Currency used to pay the distance rate */ currency?: string; + + /** Generated ID to identify the distance rate */ customUnitRateID?: string; + + /** Whether this distance rate is currently enabled */ enabled?: boolean; + + /** Error messages to show in UI */ errors?: OnyxCommon.Errors; + + /** Form fields that triggered the errors */ errorFields?: OnyxCommon.ErrorFields; + + /** Tax rate attributes of the policy */ attributes?: TaxRateAttributes; }, keyof TaxRateAttributes >; +/** Custom unit attributes */ type Attributes = { + /** Distance unit name */ unit: Unit; + + /** Whether the tax tracking is enabled or not */ taxEnabled?: boolean; }; +/** Policy custom unit */ type CustomUnit = OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** Custom unit name */ name: string; + + /** ID that identifies this custom unit */ customUnitID: string; + + /** Contains custom attributes like unit, for this custom unit */ attributes: Attributes; + + /** Distance rates using this custom unit */ rates: Record; + + /** The default category in which this custom unit is used */ defaultCategory?: string; + + /** Whether this custom unit is enabled */ enabled?: boolean; + + /** Error messages to show in UI */ errors?: OnyxCommon.Errors; + + /** Form fields that triggered errors */ errorFields?: OnyxCommon.ErrorFields; }>; +/** Policy company address data */ type CompanyAddress = { + /** Street address */ addressStreet: string; + + /** City */ city: string; + + /** State */ state: string; + + /** Zip post code */ zipCode: string; + + /** Country code */ country: Country | ''; }; +/** Policy disabled fields */ type DisabledFields = { + /** Whether the default billable field is disabled */ defaultBillable?: boolean; + + /** Whether the reimbursable field is disabled */ reimbursable?: boolean; }; +/** Policy tax rate */ type TaxRate = OnyxCommon.OnyxValueWithOfflineFeedback<{ - /** Name of the a tax rate. */ + /** Name of the tax rate. */ name: string; /** The value of the tax rate. */ @@ -81,8 +137,10 @@ type TaxRate = OnyxCommon.OnyxValueWithOfflineFeedback<{ errorFields?: OnyxCommon.ErrorFields; }>; +/** Record of policy tax rates, indexed by id_{taxRateName} where taxRateName is the name of the tax rate in UPPER_SNAKE_CASE */ type TaxRates = Record; +/** Policy tax rates with default tax rate */ type TaxRatesWithDefault = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Name of the tax */ name: string; @@ -106,136 +164,337 @@ type TaxRatesWithDefault = OnyxCommon.OnyxValueWithOfflineFeedback<{ errorFields?: OnyxCommon.ErrorFields; }>; +/** Connection last synchronization state */ type ConnectionLastSync = { + /** Date when the connection's last successful sync occurred */ successfulDate?: string; + + /** Date when the connection's last failed sync occurred */ errorDate?: string; + + /** Whether the connection's last sync was successful */ isSuccessful: boolean; + + /** Where did the connection's last sync came from */ source: 'DIRECT' | 'EXPENSIFYWEB' | 'EXPENSIFYAPI' | 'AUTOSYNC' | 'AUTOAPPROVE'; }; +/** Financial account (bank account, debit card, etc) */ type Account = { + /** GL code assigned to the financial account */ glCode?: string; + + /** Name of the financial account */ name: string; + + /** Currency of the financial account */ currency: string; + + /** ID assigned to the financial account */ id: string; }; +/** + * Model of QuickBooks Online employee data + * + * TODO: QBO remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type Employee = { + /** ID assigned to the employee */ id: string; + + /** Employee's first name */ firstName?: string; + + /** Employee's last name */ lastName?: string; + + /** Employee's display name */ name: string; + + /** Employee's e-mail */ email: string; }; +/** + * Model of QuickBooks Online vendor data + * + * TODO: QBO remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type Vendor = { + /** ID assigned to the vendor */ id: string; + + /** Vendor's name */ name: string; + + /** Vendor's currency */ currency: string; + + /** Vendor's e-mail */ email: string; }; +/** + * Model of QuickBooks Online tax code data + * + * TODO: QBO remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type TaxCode = { + /** TODO: Will be handled in another issue */ totalTaxRateVal: string; + + /** TODO: Will be handled in another issue */ simpleName: string; + + /** TODO: Will be handled in another issue */ taxCodeRef: string; + + /** TODO: Will be handled in another issue */ taxRateRefs: Record; + + /** TODO: Will be handled in another issue */ + /** Name of the tax code */ name: string; }; /** * Data imported from QuickBooks Online. + * + * TODO: QBO remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) */ type QBOConnectionData = { - country: string; + /** Country code */ + country: ValueOf; + + /** TODO: Will be handled in another issue */ edition: string; + + /** TODO: Will be handled in another issue */ homeCurrency: string; + + /** TODO: Will be handled in another issue */ isMultiCurrencyEnabled: boolean; + /** Collection of journal entry accounts */ journalEntryAccounts: Account[]; + + /** Collection of bank accounts */ bankAccounts: Account[]; + + /** Collection of credit cards */ creditCards: Account[]; + + /** Collection of export destination accounts */ accountsReceivable: Account[]; + + /** TODO: Will be handled in another issue */ accountPayable: Account[]; + + /** TODO: Will be handled in another issue */ otherCurrentAssetAccounts: Account[]; + /** TODO: Will be handled in another issue */ taxCodes: TaxCode[]; + + /** TODO: Will be handled in another issue */ employees: Employee[]; + + /** Collections of vendors */ vendors: Vendor[]; }; +/** Sync entity names */ type IntegrationEntityMap = (typeof CONST.INTEGRATION_ENTITY_MAP_TYPES)[keyof typeof CONST.INTEGRATION_ENTITY_MAP_TYPES]; +/** + * Non reimbursable account types exported from QuickBooks Online + * + * TODO: QBO remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type QBONonReimbursableExportAccountType = (typeof CONST.QUICKBOOKS_NON_REIMBURSABLE_EXPORT_ACCOUNT_TYPE)[keyof typeof CONST.QUICKBOOKS_NON_REIMBURSABLE_EXPORT_ACCOUNT_TYPE]; + +/** + * Reimbursable account types exported from QuickBooks Online + * + * TODO: QBO remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type QBOReimbursableExportAccountType = (typeof CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE)[keyof typeof CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE]; /** * User configuration for the QuickBooks Online accounting integration. + * + * TODO: QBO remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) */ type QBOConnectionConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** TODO: Will be handled in another issue */ realmId: string; + + /** TODO: Will be handled in another issue */ companyName: string; + + /** Configuration of automatic synchronization from QuickBooks Online to the app */ autoSync: { + /** TODO: Will be handled in another issue */ jobID: string; + + /** Whether changes made in QuickBooks Online should be reflected into the app automatically */ enabled: boolean; }; + + /** Whether employees can be invited */ syncPeople: boolean; + + /** TODO: Will be handled in another issue */ syncItems: boolean; + + /** TODO: Will be handled in another issue */ markChecksToBePrinted: boolean; + + /** Defines how reimbursable expenses are exported */ reimbursableExpensesExportDestination: QBOReimbursableExportAccountType; + + /** Defines how non reimbursable expenses are exported */ nonReimbursableExpensesExportDestination: QBONonReimbursableExportAccountType; + + /** Default vendor of non reimbursable bill */ nonReimbursableBillDefaultVendor: string; + + /** ID of the invoice collection account */ collectionAccountID?: string; + + /** ID of the bill payment account */ reimbursementAccountID?: string; + + /** Account that receives the reimbursable expenses */ reimbursableExpensesAccount?: Account; + + /** Account that receives the non reimbursable expenses */ nonReimbursableExpensesAccount?: Account; + + /** Account that receives the exported invoices */ receivableAccount?: Account; + + /** + * Whether a default vendor will be created and applied to all credit card + * transactions upon import + */ autoCreateVendor: boolean; + + /** TODO: Will be handled in another issue */ hasChosenAutoSyncOption: boolean; + + /** Whether Quickbooks Online classes should be imported */ syncClasses: IntegrationEntityMap; + + /** Whether Quickbooks Online customers should be imported */ syncCustomers: IntegrationEntityMap; + + /** Whether Quickbooks Online locations should be imported */ syncLocations: IntegrationEntityMap; + + /** TODO: Will be handled in another issue */ lastConfigurationTime: number; + + /** Whether the taxes should be synchronized */ syncTax: boolean; + + /** Whether new categories are enabled in chart of accounts */ enableNewCategories: boolean; + + /** TODO: Will be handled in another issue */ errors?: OnyxCommon.Errors; + + /** TODO: Will be handled in another issue */ exportDate: ValueOf; + + /** Configuration of the export */ export: { + /** E-mail of the exporter */ exporter: string; }; + + /** Collections of form field errors */ errorFields?: OnyxCommon.ErrorFields; }>; +/** Xero bill status values + * + * TODO: Xero remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type BillStatusValues = 'DRAFT' | 'AWT_APPROVAL' | 'AWT_PAYMENT'; +/** Xero expense status values + * + * TODO: Xero remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type ExpenseTypesValues = 'BILL' | 'BANK_TRANSACTION' | 'SALES_INVOICE' | 'NOTHING'; +/** Xero bill date values + * + * TODO: Xero remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type BillDateValues = 'REPORT_SUBMITTED' | 'REPORT_EXPORTED' | 'LAST_EXPENSE'; +/** + * Model of an organization in Xero + * + * TODO: Xero remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type Tenant = { + /** ID of the organization */ id: string; + + /** Name of the organization */ name: string; + + /** TODO: Will be handled in another issue */ value: string; }; +/** TODO: Xero remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) */ type XeroTrackingCategory = { + /** TODO: Will be handled in another issue */ id: string; + + /** TODO: Will be handled in another issue */ name: string; }; +/** + * Data imported from Xero + * + * TODO: Xero remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) + */ type XeroConnectionData = { + /** Collection of bank accounts */ bankAccounts: Account[]; + + /** TODO: Will be handled in another issue */ countryCode: string; + + /** TODO: Will be handled in another issue */ organisationID: string; + + /** TODO: Will be handled in another issue */ revenueAccounts: Array<{ + /** TODO: Will be handled in another issue */ id: string; + + /** TODO: Will be handled in another issue */ name: string; }>; + + /** Collection of organizations */ tenants: Tenant[]; + + /** TODO: Will be handled in another issue */ trackingCategories: XeroTrackingCategory[]; }; +/** TODO: Xero remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) */ type XeroMappingType = { + /** TODO: Will be handled in another issue */ customer: string; } & { [key in `trackingCategory_${string}`]: string; @@ -243,68 +502,147 @@ type XeroMappingType = { /** * User configuration for the Xero accounting integration. + * + * TODO: Xero remaining comments will be handled here (https://github.com/Expensify/App/issues/43033) */ type XeroConnectionConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** Xero auto synchronization configs */ autoSync: { + /** Whether data should be automatically synched between the app and Xero */ enabled: boolean; + + /** TODO: Will be handled in another issue */ jobID: string; }; + + /** TODO: Will be handled in another issue */ enableNewCategories: boolean; + + /** Xero export configs */ export: { + /** Current bill status */ billDate: BillDateValues; + + /** TODO: Will be handled in another issue */ billStatus: { + /** Current status of the purchase bill */ purchase: BillStatusValues; + + /** Current status of the sales bill */ sales: BillStatusValues; }; + + /** TODO: Will be handled in another issue */ billable: ExpenseTypesValues; + + /** The e-mail of the exporter */ exporter: string; + + /** TODO: Will be handled in another issue */ nonReimbursable: ExpenseTypesValues; + + /** TODO: Will be handled in another issue */ nonReimbursableAccount: string; + + /** TODO: Will be handled in another issue */ reimbursable: ExpenseTypesValues; }; + + /** Whether customers should be imported from Xero */ importCustomers: boolean; + + /** Whether tax rates should be imported from Xero */ importTaxRates: boolean; + + /** Whether tracking categories should be imported from Xero */ importTrackingCategories: boolean; + + /** TODO: Will be handled in another issue */ isConfigured: boolean; + + /** TODO: Will be handled in another issue */ mappings: XeroMappingType; + + /** TODO: Will be handled in another issue */ sync: { + /** TODO: Will be handled in another issue */ hasChosenAutoSyncOption: boolean; + + /** TODO: Will be handled in another issue */ hasChosenSyncReimbursedReportsOption: boolean; + + /** ID of the bank account for Xero invoice collections */ invoiceCollectionsAccountID: string; + + /** ID of the bank account for Xero bill payment account */ reimbursementAccountID: string; + + /** Whether the reimbursed reports should be synched */ syncReimbursedReports: boolean; }; + + /** ID of Xero organization */ tenantID: string; + + /** TODO: Will be handled in another issue */ errors?: OnyxCommon.Errors; + + /** Collection of form field errors */ errorFields?: OnyxCommon.ErrorFields; }>; +/** State of integration connection */ type Connection = { + /** State of the last synchronization */ lastSync?: ConnectionLastSync; + + /** Data imported from integration */ data?: ConnectionData; + + /** Configuration of the connection */ config: ConnectionConfig; }; +/** Available integration connections */ type Connections = { + /** QuickBooks integration connection */ quickbooksOnline: Connection; + + /** Xero integration connection */ xero: Connection; }; +/** Names of integration connections */ type ConnectionName = keyof Connections; +/** Model of verified reimbursement bank account linked to policy */ type ACHAccount = { + /** ID of the bank account */ bankAccountID: number; + + /** Bank account number */ accountNumber: string; + + /** Routing number of bank account */ routingNumber: string; + + /** Address name of the bank account */ addressName: string; + + /** Name of the bank */ bankName: string; + + /** E-mail of the reimburser */ reimburser: string; }; +/** Day of the month to schedule submission */ type AutoReportingOffset = number | ValueOf; +/** Types of policy report fields */ type PolicyReportFieldType = 'text' | 'date' | 'dropdown' | 'formula'; +/** Model of policy report field */ type PolicyReportField = { /** Name of the field */ name: string; @@ -330,14 +668,13 @@ type PolicyReportField = { /** Options to select from if field is of type dropdown */ values: string[]; - target: string; - /** Tax UDFs have keys holding the names of taxes (eg, VAT), values holding percentages (eg, 15%) and a value indicating the currently selected tax value (eg, 15%). */ keys: string[]; /** list of externalIDs, this are either imported from the integrations or auto generated by us, each externalID */ externalIDs: string[]; + /** Collection of flags that state whether droplist field options are disabled */ disabledOptions: boolean[]; /** Is this a tax user defined report field */ @@ -353,22 +690,37 @@ type PolicyReportField = { defaultExternalID?: string | null; }; +/** Names of policy features */ type PolicyFeatureName = ValueOf; +/** Current user policy join request state */ type PendingJoinRequestPolicy = { + /** Whether the current user requested to join the policy */ isJoinRequestPending: boolean; + + /** Record of public policy details, indexed by policy ID */ policyDetailsForNonMembers: Record< string, OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** Name of the policy */ name: string; + + /** Policy owner account ID */ ownerAccountID: number; + + /** Policy owner e-mail */ ownerEmail: string; + + /** Policy type */ type: ValueOf; + + /** Policy avatar */ avatar?: string; }> >; }; +/** Model of policy data */ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< { /** The ID of the policy */ @@ -422,8 +774,9 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** The scheduled submit frequency set up on this policy */ autoReportingFrequency?: ValueOf; - /** Whether the scheduled submit is enabled */ + /** Scheduled submit data */ harvesting?: { + /** Whether the scheduled submit is enabled */ enabled: boolean; }; @@ -491,8 +844,9 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< */ isTaxTrackingEnabled?: boolean; - /** Whether or not the policy has tax tracking enabled */ + /** Tax data */ tax?: { + /** Whether or not the policy has tax tracking enabled */ trackingEnabled: boolean; }; @@ -553,11 +907,21 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< 'generalSettings' | 'addWorkspaceRoom' | keyof ACHAccount >; +/** Stages of policy connection sync */ type PolicyConnectionSyncStage = ValueOf; + +/** Names of policy connection services */ type PolicyConnectionName = ValueOf; + +/** Policy connection sync progress state */ type PolicyConnectionSyncProgress = { + /** Current sync stage */ stageInProgress: PolicyConnectionSyncStage; + + /** Name of the connected service */ connectionName: PolicyConnectionName; + + /** Timestamp of the connection */ timestamp: string; }; diff --git a/src/types/onyx/PolicyCategory.ts b/src/types/onyx/PolicyCategory.ts index d4162bfdcddf..c9191ae5b8d9 100644 --- a/src/types/onyx/PolicyCategory.ts +++ b/src/types/onyx/PolicyCategory.ts @@ -1,5 +1,6 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of policy category */ type PolicyCategory = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Name of a category */ name: string; @@ -30,6 +31,7 @@ type PolicyCategory = OnyxCommon.OnyxValueWithOfflineFeedback<{ errors?: OnyxCommon.Errors | null; }>; +/** Record of policy categories, indexed by their name */ type PolicyCategories = Record; export type {PolicyCategory, PolicyCategories}; diff --git a/src/types/onyx/PolicyEmployee.ts b/src/types/onyx/PolicyEmployee.ts index 4a5f374de44a..741e1e01ec05 100644 --- a/src/types/onyx/PolicyEmployee.ts +++ b/src/types/onyx/PolicyEmployee.ts @@ -1,5 +1,6 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of policy employee */ type PolicyEmployee = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Role of the user in the policy */ role?: string; @@ -20,6 +21,7 @@ type PolicyEmployee = OnyxCommon.OnyxValueWithOfflineFeedback<{ errors?: OnyxCommon.Errors; }>; +/** Record of policy employees, indexed by their email */ type PolicyEmployeeList = Record; export default PolicyEmployee; diff --git a/src/types/onyx/PolicyJoinMember.ts b/src/types/onyx/PolicyJoinMember.ts index 7c540b334b4a..bb7b346e6ded 100644 --- a/src/types/onyx/PolicyJoinMember.ts +++ b/src/types/onyx/PolicyJoinMember.ts @@ -1,5 +1,6 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of policy join member */ type PolicyJoinMember = { /** The ID of the policy */ policyID?: string; diff --git a/src/types/onyx/PolicyOwnershipChangeChecks.ts b/src/types/onyx/PolicyOwnershipChangeChecks.ts index 8033cffdee3c..9950122b069a 100644 --- a/src/types/onyx/PolicyOwnershipChangeChecks.ts +++ b/src/types/onyx/PolicyOwnershipChangeChecks.ts @@ -1,7 +1,15 @@ +/** Model of policy ownership change checks */ type PolicyOwnershipChangeChecks = { + /** Whether the outstanding balance should be cleared after changing workspace owner */ shouldClearOutstandingBalance?: boolean; + + /** Whether the amount owed should be transferred after changing workspace owner */ shouldTransferAmountOwed?: boolean; + + /** Whether the subscription should be transferred after changing workspace owner */ shouldTransferSubscription?: boolean; + + /** Whether the single subscription should be transferred after changing workspace owner */ shouldTransferSingleSubscription?: boolean; }; diff --git a/src/types/onyx/PolicyTag.ts b/src/types/onyx/PolicyTag.ts index 40bac23dc4f3..6b2a2bf5ffd6 100644 --- a/src/types/onyx/PolicyTag.ts +++ b/src/types/onyx/PolicyTag.ts @@ -1,5 +1,6 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of policy tag */ type PolicyTag = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Name of a Tag */ name: string; @@ -18,8 +19,10 @@ type PolicyTag = OnyxCommon.OnyxValueWithOfflineFeedback<{ errors?: OnyxCommon.Errors | null; }>; +/** Record of policy tags, indexed by their name */ type PolicyTags = Record; +/** Record of policy tag lists, index by the name of the tag list */ type PolicyTagList = Record< T, OnyxCommon.OnyxValueWithOfflineFeedback<{ diff --git a/src/types/onyx/PreferredTheme.ts b/src/types/onyx/PreferredTheme.ts index 408748ad06ea..98c001df018c 100644 --- a/src/types/onyx/PreferredTheme.ts +++ b/src/types/onyx/PreferredTheme.ts @@ -2,6 +2,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +/** Possible user preferred themes to be used in the whole app */ type PreferredTheme = OnyxEntry>; export default PreferredTheme; diff --git a/src/types/onyx/PriorityMode.ts b/src/types/onyx/PriorityMode.ts index 224c86867f35..404c678945ad 100644 --- a/src/types/onyx/PriorityMode.ts +++ b/src/types/onyx/PriorityMode.ts @@ -2,6 +2,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +/** Modes that define how the user's chats are displayed in his chat list */ type PriorityMode = OnyxEntry>; export default PriorityMode; diff --git a/src/types/onyx/PrivatePersonalDetails.ts b/src/types/onyx/PrivatePersonalDetails.ts index 3099cb0095e9..1f81108bf538 100644 --- a/src/types/onyx/PrivatePersonalDetails.ts +++ b/src/types/onyx/PrivatePersonalDetails.ts @@ -1,25 +1,59 @@ import type {Country} from '@src/CONST'; +/** User address data */ type Address = { + /** Street line 1 */ street: string; + + /** Street line 2 */ street2?: string; + + /** City */ city?: string; + + /** State */ state?: string; + + /** Zip post code */ zip?: string; + + /** Country code */ country?: Country | ''; + + /** Zip post code */ zipPostCode?: string; + + /** Street line 1 */ addressLine1?: string; + + /** Street line 2 */ addressLine2?: string; + + /** Latitude */ lat?: string; + + /** Longitude */ lng?: string; + + /** Zip post code */ zipCode?: string; + + /** Google place description */ address?: string; }; +/** Model of user private personal details */ type PrivatePersonalDetails = { + /** User's legal first name */ legalFirstName?: string; + + /** User's legal last name */ legalLastName?: string; + + /** User's date of birth */ dob?: string; + + /** User's phone number */ phoneNumber?: string; /** User's home address */ diff --git a/src/types/onyx/PrivateSubscription.ts b/src/types/onyx/PrivateSubscription.ts index fbed6a89e49c..b9314b2bc66a 100644 --- a/src/types/onyx/PrivateSubscription.ts +++ b/src/types/onyx/PrivateSubscription.ts @@ -1,6 +1,7 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +/** Model of private subscription */ type PrivateSubscription = { /** "auto increase annual seats" setting */ addNewUsersAutomatically: boolean; diff --git a/src/types/onyx/QuickAction.ts b/src/types/onyx/QuickAction.ts index 325893637911..c10ec8356546 100644 --- a/src/types/onyx/QuickAction.ts +++ b/src/types/onyx/QuickAction.ts @@ -1,8 +1,10 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +/** Names of quick actions that the user can execute */ type QuickActionName = ValueOf; +/** Model of user quick action */ type QuickAction = { /** The action to take */ action?: QuickActionName; diff --git a/src/types/onyx/RecentWaypoint.ts b/src/types/onyx/RecentWaypoint.ts index 6ed55e080560..6624eb044f98 100644 --- a/src/types/onyx/RecentWaypoint.ts +++ b/src/types/onyx/RecentWaypoint.ts @@ -1,3 +1,4 @@ +/** Model of recent endpoint used in distance expense */ type RecentWaypoint = { /** The name associated with the address of the waypoint */ name?: string; diff --git a/src/types/onyx/RecentlyUsedCategories.ts b/src/types/onyx/RecentlyUsedCategories.ts index d251b16f8667..c3d7c187c710 100644 --- a/src/types/onyx/RecentlyUsedCategories.ts +++ b/src/types/onyx/RecentlyUsedCategories.ts @@ -1,3 +1,4 @@ +/** Workspace categories that have been recently used by members */ type RecentlyUsedCategories = string[]; export default RecentlyUsedCategories; diff --git a/src/types/onyx/RecentlyUsedReportFields.ts b/src/types/onyx/RecentlyUsedReportFields.ts index 2b3d046c8316..95af207eaa31 100644 --- a/src/types/onyx/RecentlyUsedReportFields.ts +++ b/src/types/onyx/RecentlyUsedReportFields.ts @@ -1,3 +1,4 @@ +/** Record of policy recently used report fields, indexed by expensify_${reportFieldId} */ type RecentlyUsedReportFields = Record; export default RecentlyUsedReportFields; diff --git a/src/types/onyx/RecentlyUsedTags.ts b/src/types/onyx/RecentlyUsedTags.ts index 1d6112514609..650a0554ef37 100644 --- a/src/types/onyx/RecentlyUsedTags.ts +++ b/src/types/onyx/RecentlyUsedTags.ts @@ -1,3 +1,4 @@ +/** Record of policy recently used tags, indexed by nvp_recentlyUsedTags_{policyID} */ type RecentlyUsedTags = Record; export default RecentlyUsedTags; diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts index f2565b29eaf3..2322f6faab17 100644 --- a/src/types/onyx/ReimbursementAccount.ts +++ b/src/types/onyx/ReimbursementAccount.ts @@ -4,10 +4,13 @@ import type {ACHContractStepProps, BeneficialOwnersStepProps, CompanyStepProps, import type {BankName} from './Bank'; import type * as OnyxCommon from './OnyxCommon'; +/** Steps to setup a reimbursement bank account */ type BankAccountStep = ValueOf; +/** Substeps to setup a reimbursement bank account */ type BankAccountSubStep = ValueOf; +/** Model of ACH data */ type ACHData = Partial & { /** Step of the setup flow that we are on. Determines which view is presented. */ currentStep?: BankAccountStep; @@ -46,6 +49,7 @@ type ACHData = Partial; +/** Defines who's able to write messages in the chat */ type WriteCapability = ValueOf; +/** Defines which users have access to the chat */ type RoomVisibility = ValueOf; +/** Model of report private note */ type Note = OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** Content of the note */ note: string; + + /** Collection of errors to show to the user */ errors?: OnyxCommon.Errors; }>; /** The pending member of report */ type PendingChatMember = { + /** Account ID of the pending member */ accountID: string; + + /** Action to be applied to the pending member of report */ pendingAction: OnyxCommon.PendingAction; + + /** Collection of errors to show to the user */ errors?: OnyxCommon.Errors; }; +/** Report participant properties */ type Participant = OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** Whether the participant is visible in the report */ hidden?: boolean; + + /** What is the role of the participant in the report */ role?: 'admin' | 'member'; }>; +/** Types of invoice receivers in a report */ type InvoiceReceiver = | { + /** An individual */ type: typeof CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL; + + /** Account ID of the user */ accountID: number; } | { + /** A business */ type: typeof CONST.REPORT.INVOICE_RECEIVER_TYPE.BUSINESS; + + /** ID of the policy */ policyID: string; }; +/** Record of report participants, indexed by their accountID */ type Participants = Record; +/** Model of report data */ type Report = OnyxCommon.OnyxValueWithOfflineFeedback< { /** The URL of the Group Chat report custom avatar */ @@ -142,27 +167,58 @@ type Report = OnyxCommon.OnyxValueWithOfflineFeedback< /** Invoice room receiver data */ invoiceReceiver?: InvoiceReceiver; + /** Translation key of the last message in the report */ lastMessageTranslationKey?: string; + + /** ID of the parent report of the current report, if it exists */ parentReportID?: string; + + /** ID of the parent report action of the current report, if it exists */ parentReportActionID?: string; + + /** Whether the current report is optimistic */ isOptimisticReport?: boolean; + + /** Account ID of the report manager */ managerID?: number; + + /** When was the last visible action last modified */ lastVisibleActionLastModified?: string; + + /** Display name of the report, shown in options and mentions */ displayName?: string; + + /** HTML content of the last message in the report */ lastMessageHtml?: string; + + /** Account ID of the user that sent the last message */ lastActorAccountID?: number; - // The type of the last action + /** The type of the last action */ lastActionType?: ValueOf; + + /** Account ID of the report owner */ ownerAccountID?: number; + + /** E-mail of the report owner */ ownerEmail?: string; + + /** Collection of report participants, indexed by their accountID */ participants?: Participants; + + /** For expense reports, this is the total amount approved */ total?: number; + + /** For expense reports, this is the total amount requested */ unheldTotal?: number; + + /** For expense reports, this is the currency of the expense */ currency?: string; + + /** Collection of errors to be shown to the user */ errors?: OnyxCommon.Errors; - managerEmail?: string; - parentReportActionIDs?: number[]; + + /** Collection of errors that exist in report fields */ errorFields?: OnyxCommon.ErrorFields; /** Whether the report is waiting on a bank account */ @@ -185,13 +241,26 @@ type Report = OnyxCommon.OnyxValueWithOfflineFeedback< /** If the report contains nonreimbursable expenses, send the nonreimbursable total */ nonReimbursableTotal?: number; + + /** Whether the report is hidden from options list */ isHidden?: boolean; + + /** Whether the report is a chat room */ isChatRoom?: boolean; + + /** Collection of participants personal details */ participantsList?: PersonalDetails[]; + + /** Text to be displayed in options list, which matches reportName by default */ text?: string; - updateReportInLHN?: boolean; + + /** Collection of participant private notes, indexed by their accountID */ privateNotes?: Record; + + /** Whether participants private notes are being currently loaded */ isLoadingPrivateNotes?: boolean; + + /** Whether the report is currently selected in the options list */ selected?: boolean; /** Pending members of the report */ @@ -200,13 +269,16 @@ type Report = OnyxCommon.OnyxValueWithOfflineFeedback< /** The ID of the single transaction thread report associated with this report, if one exists */ transactionThreadReportID?: string; + /** Collection of policy report fields, indexed by their fieldID */ fieldList?: Record; + /** Collection of report permissions granted to the current user */ permissions?: Array>; }, PolicyReportField['fieldID'] >; +/** Collection of reports, indexed by report_{reportID} */ type ReportCollectionDataSet = CollectionDataSet; export default Report; diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts index cb11e468754c..ee6fc76ba3cd 100644 --- a/src/types/onyx/ReportAction.ts +++ b/src/types/onyx/ReportAction.ts @@ -6,15 +6,18 @@ import type ONYXKEYS from '@src/ONYXKEYS'; import type CollectionDataSet from '@src/types/utils/CollectionDataSet'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import type * as OnyxCommon from './OnyxCommon'; -import type {Decision, OriginalMessageModifiedExpense, OriginalMessageReportPreview, Reaction} from './OriginalMessage'; +import type {Decision, OriginalMessageModifiedExpense, OriginalMessageReportPreview} from './OriginalMessage'; import type OriginalMessage from './OriginalMessage'; import type {NotificationPreference} from './Report'; import type {Receipt} from './Transaction'; +/** Partial content of report action message */ type ReportActionMessageJSON = { + /** Collection of accountIDs from users that were mentioned in report */ whisperedTo?: number[]; }; +/** Model of report action message */ type Message = { /** The type of the action item fragment. Used to render a corresponding component */ type: string; @@ -53,10 +56,14 @@ type Message = { /** Whether the pending transaction was reversed and didn't post to the card */ isReversedTransaction?: boolean; + + /** Collection of accountIDs of users mentioned in message */ whisperedTo?: number[]; - reactions?: Reaction[]; + /** In situations where moderation is required, this is the moderator decision data */ moderationDecision?: Decision; + + /** Key to translate the message */ translationKey?: string; /** ID of a task report */ @@ -81,6 +88,7 @@ type Message = { deleted?: string; }; +/** Model of image */ type ImageMetadata = { /** The height of the image. */ height?: number; @@ -95,6 +103,7 @@ type ImageMetadata = { type?: string; }; +/** Model of link */ type LinkMetadata = { /** The URL of the link. */ url?: string; @@ -115,12 +124,19 @@ type LinkMetadata = { logo?: ImageMetadata; }; +/** Model of report action person */ type Person = { + /** Type of the message to display */ type?: string; + + /** Style applied to the message */ style?: string; + + /** Content of the message to display which corresponds to the user display name */ text?: string; }; +/** Main properties of report action */ type ReportActionBase = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** The ID of the reportAction. It is the string representation of the a 64-bit integer. */ reportActionID: string; @@ -131,6 +147,7 @@ type ReportActionBase = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** The ID of the previous reportAction on the report. It is a string represenation of a 64-bit integer (or null for CREATED actions). */ previousReportActionID?: string; + /** Account ID of the actor that created the action */ actorAccountID?: number; /** The account of the last message's actor */ @@ -151,10 +168,13 @@ type ReportActionBase = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Whether we have received a response back from the server */ isLoading?: boolean; + /** Avatar data to display on the report action */ avatar?: AvatarSource; + /** TODO: Not enough context */ automatic?: boolean; + /** TODO: Not enough context */ shouldShow?: boolean; /** The ID of childReport */ @@ -169,12 +189,22 @@ type ReportActionBase = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** The user's ID */ accountID?: number; - childOldestFourEmails?: string; + /** Account IDs of the oldest four participants, useful to determine which avatars to display in threads */ childOldestFourAccountIDs?: string; + + /** How many participants commented in the report */ childCommenterCount?: number; + + /** Timestamp of the most recent reply */ childLastVisibleActionCreated?: string; + + /** Number of thread replies */ childVisibleActionCount?: number; + + /** Report ID of the parent report, if there's one */ parentReportID?: string; + + /** In task reports this is account ID of the user assigned to the task */ childManagerAccountID?: number; /** The status of the child report */ @@ -182,12 +212,17 @@ type ReportActionBase = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Report action child status name */ childStateNum?: ValueOf; - childLastReceiptTransactionIDs?: string; + + /** Content of the last money request comment, used in report preview */ childLastMoneyRequestComment?: string; + + /** Account ID of the last actor */ childLastActorAccountID?: number; - timestamp?: number; - reportActionTimestamp?: number; + + /** Amount of money requests */ childMoneyRequestCount?: number; + + /** Whether the report action is the first one */ isFirstItem?: boolean; /** Informations about attachments of report action */ @@ -199,6 +234,7 @@ type ReportActionBase = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** ISO-formatted datetime */ lastModified?: string; + /** The accountID of the copilot who took this action on behalf of the user */ delegateAccountID?: number; /** Server side errors keyed by microtime */ @@ -235,12 +271,19 @@ type ReportActionBase = OnyxCommon.OnyxValueWithOfflineFeedback<{ whisperedToAccountIDs?: number[]; }>; +/** Model of report action */ type ReportAction = ReportActionBase & OriginalMessage; + +/** Model of report preview action */ type ReportPreviewAction = ReportActionBase & OriginalMessageReportPreview; + +/** Model of modifies expense action */ type ModifiedExpenseAction = ReportActionBase & OriginalMessageModifiedExpense; +/** Record of report actions, indexed by report action ID */ type ReportActions = Record; +/** Collection of mock report actions, indexed by reportActions_${reportID} */ type ReportActionsCollectionDataSet = CollectionDataSet; export default ReportAction; diff --git a/src/types/onyx/ReportActionReactions.ts b/src/types/onyx/ReportActionReactions.ts index 983598e0b420..fd14b681d6e9 100644 --- a/src/types/onyx/ReportActionReactions.ts +++ b/src/types/onyx/ReportActionReactions.ts @@ -1,5 +1,6 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of report user reaction */ type UserReaction = { /** ID of user reaction */ id: string; @@ -11,8 +12,10 @@ type UserReaction = { oldestTimestamp: string; }; +/** Record of report user reactions, indexed by their login name or account id */ type UsersReactions = Record; +/** Model of report action reaction */ type ReportActionReaction = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** The time the emoji was added */ createdAt: string; @@ -24,6 +27,7 @@ type ReportActionReaction = OnyxCommon.OnyxValueWithOfflineFeedback<{ users: UsersReactions; }>; +/** Record of report action reactions, indexed by emoji name */ type ReportActionReactions = Record; export default ReportActionReactions; diff --git a/src/types/onyx/ReportActionsDraft.ts b/src/types/onyx/ReportActionsDraft.ts index 41a701f16e71..762e4f690853 100644 --- a/src/types/onyx/ReportActionsDraft.ts +++ b/src/types/onyx/ReportActionsDraft.ts @@ -1,5 +1,7 @@ +/** Model of a report action draft */ type ReportActionsDraft = | { + /** Chat message content */ message: string; } | string; diff --git a/src/types/onyx/ReportActionsDrafts.ts b/src/types/onyx/ReportActionsDrafts.ts index e4c51c61ed25..56be910d53de 100644 --- a/src/types/onyx/ReportActionsDrafts.ts +++ b/src/types/onyx/ReportActionsDrafts.ts @@ -2,8 +2,10 @@ import type ONYXKEYS from '@src/ONYXKEYS'; import type CollectionDataSet from '@src/types/utils/CollectionDataSet'; import type ReportActionsDraft from './ReportActionsDraft'; +/** Record of report actions drafts, indexed by their ID */ type ReportActionsDrafts = Record; +/** Record of report actions drafts grouped by report, indexed by reportActionsDrafts_\ */ type ReportActionsDraftCollectionDataSet = CollectionDataSet; export default ReportActionsDrafts; diff --git a/src/types/onyx/ReportMetadata.ts b/src/types/onyx/ReportMetadata.ts index 1c6035853564..65a6f153c51b 100644 --- a/src/types/onyx/ReportMetadata.ts +++ b/src/types/onyx/ReportMetadata.ts @@ -1,3 +1,4 @@ +/** Model of report metadata */ type ReportMetadata = { /** Are we loading newer report actions? */ isLoadingNewerReportActions?: boolean; diff --git a/src/types/onyx/ReportNameValuePairs.ts b/src/types/onyx/ReportNameValuePairs.ts index 1cf56c300f00..7726d07a3074 100644 --- a/src/types/onyx/ReportNameValuePairs.ts +++ b/src/types/onyx/ReportNameValuePairs.ts @@ -1,6 +1,8 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of additional report details */ type ReportNameValuePairs = OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** Whether the report is an archived room */ isArchived: boolean; }>; diff --git a/src/types/onyx/ReportNextStep.ts b/src/types/onyx/ReportNextStep.ts index b619319d8f91..0d158880a137 100644 --- a/src/types/onyx/ReportNextStep.ts +++ b/src/types/onyx/ReportNextStep.ts @@ -1,24 +1,53 @@ +/** Model of report next step message */ type Message = { + /** Message content */ text: string; + + /** HTML tag name */ type?: string; + + /** Action for the user to take */ action?: string; }; +/** Model of report next step button data */ type DataOptions = { + /** Whether the user should see the option to pay via Expensify (ACH) */ canSeeACHOption?: boolean; + + /** Whether workspace reimbursements is set to Indirect reimbursements */ isManualReimbursementEnabled?: boolean; + + /** + * If there is a masked bank account number from the server, the account needs to be unlocked + * + * (Note: Copied directly from a comment in Old Dot JS) + */ maskedLockedAccountNumber?: string; + + /** Whether the preferred business bank account of the policy is deleted or no longer accessible to the policy reimburser */ preferredWithdrawalDeleted?: boolean; }; +/** Model of report next step button */ type Button = { + /** Text/label shown on the button */ text?: string; + + /** Text to show on a tooltip */ tooltip?: string; + + /** Whether the button should be disabled */ disabled?: boolean; + + /** Whether the button should be hidden */ hidden?: boolean; + + /** Data needed to render the button and handle its click events */ data?: DataOptions; }; +/** Model for next step of a report */ type ReportNextStep = { /** The message parts of the next step */ message?: Message[]; @@ -29,25 +58,29 @@ type ReportNextStep = { /** Whether the user should take some sort of action in order to unblock the report */ requiresUserAction?: boolean; - /** The type of next step */ + /** + * The type of next step + * + * "neutral" for normal next steps, "alert" for more urgent/actionable + */ type: 'alert' | 'neutral' | null; - /** If the "Undo submit" button should be visible */ + /** Whether the "Undo submit" button should be visible */ showUndoSubmit?: boolean; - /** Deprecated - If the next step should be displayed on mobile, related to OldApp */ + /** Whether the next step should be displayed on mobile, related to OldApp */ showForMobile?: boolean; - /** If the next step should be displayed at the expense level */ + /** Whether the next step should be displayed at the expense level */ showForExpense?: boolean; /** An optional alternate message to display on expenses instead of what is provided in the "message" field */ expenseMessage?: Message[]; - /** The next person in the approval chain of the report */ + /** Email of the next person in the approval chain that needs to approve the report */ nextReceiver?: string; - /** An array of buttons to be displayed next to the next step */ + /** An array listing the buttons to be displayed alongside the next step copy */ buttons?: Record; }; diff --git a/src/types/onyx/ReportUserIsTyping.ts b/src/types/onyx/ReportUserIsTyping.ts index 1e6f482ffa7a..b599da4974fe 100644 --- a/src/types/onyx/ReportUserIsTyping.ts +++ b/src/types/onyx/ReportUserIsTyping.ts @@ -1,3 +1,4 @@ +/** Record of report users typing state, indexed by their login name or account id */ type ReportUserIsTyping = Record; export default ReportUserIsTyping; diff --git a/src/types/onyx/Request.ts b/src/types/onyx/Request.ts index 233519f010fc..ab45fcf84c42 100644 --- a/src/types/onyx/Request.ts +++ b/src/types/onyx/Request.ts @@ -1,29 +1,61 @@ import type {OnyxUpdate} from 'react-native-onyx'; import type Response from './Response'; +/** Model of onyx requests sent to the API */ type OnyxData = { + /** Onyx instructions that are executed after getting response from server with jsonCode === 200 */ successData?: OnyxUpdate[]; + + /** Onyx instructions that are executed after getting response from server with jsonCode !== 200 */ failureData?: OnyxUpdate[]; + + /** Onyx instructions that are executed after getting any response from server */ finallyData?: OnyxUpdate[]; + + /** Onyx instructions that are executed before request is made to the server */ optimisticData?: OnyxUpdate[]; }; +/** HTTP request method names */ type RequestType = 'get' | 'post'; +/** Model of overall requests sent to the API */ type RequestData = { + /** Name of the API command */ command: string; + + /** Command name for logging purposes */ commandName?: string; + + /** Additional parameters that can be sent with the request */ data?: Record; + + /** The HTTP request method name */ type?: RequestType; + + /** Whether the app should connect to the secure API endpoints */ shouldUseSecure?: boolean; + + /** Onyx instructions that are executed after getting response from server with jsonCode === 200 */ successData?: OnyxUpdate[]; + + /** Onyx instructions that are executed after getting response from server with jsonCode !== 200 */ failureData?: OnyxUpdate[]; + + /** Onyx instructions that are executed after getting any response from server */ finallyData?: OnyxUpdate[]; + + /** Promise resolve handler */ resolve?: (value: Response) => void; + + /** Promise reject handler */ reject?: (value?: unknown) => void; + + /** Whether the app should skip the web proxy to connect to API endpoints */ shouldSkipWebProxy?: boolean; }; +/** Model of requests sent to the API */ type Request = RequestData & OnyxData; export default Request; diff --git a/src/types/onyx/Response.ts b/src/types/onyx/Response.ts index 5e606738c56d..aa060223637b 100644 --- a/src/types/onyx/Response.ts +++ b/src/types/onyx/Response.ts @@ -1,26 +1,65 @@ import type {OnyxUpdate} from 'react-native-onyx'; +/** Model of commands data */ type Data = { + /** Name of the API call */ phpCommandName: string; + + /** Collection of auth write requests */ authWriteCommands: string[]; }; +/** Model of server response */ type Response = { + /** ID of the next update that needs to be fetched from the server */ previousUpdateID?: number | string; + + /** ID of the last update that needs to be fetched from the server */ lastUpdateID?: number | string; + + /** HTTP response status code */ jsonCode?: number | string; + + /** Collection of onyx updates (SET/MERGE/...) */ onyxData?: OnyxUpdate[]; + + /** ID of the request that triggered this response */ requestID?: string; + + /** Report ID of the updated report */ reportID?: string; + + /** + * Whether the sequential queue should not send any requests to the server. + * Used when there's a gap between client and server updates. + */ shouldPauseQueue?: boolean; + + /** User session auth token */ authToken?: string; + + /** Used to load resources like attachment videos and images */ encryptedAuthToken?: string; + + /** Used to pass error messages for error handling purposes */ message?: string; + + /** Used to pass error title for error handling purposes */ title?: string; + + /** Commands data */ data?: Data; + + /** Used to pass error type for error handling purposes */ type?: string; + + /** Short lived auth token generated by API */ shortLivedAuthToken?: string; + + /** User authorization token to authorize Pusher connections */ auth?: string; + + /** Base64 key to decrypt messages from Pusher encrypted channels */ // eslint-disable-next-line @typescript-eslint/naming-convention shared_secret?: string; }; diff --git a/src/types/onyx/ScreenShareRequest.ts b/src/types/onyx/ScreenShareRequest.ts index 564ba99c22ac..920921e8c9b2 100644 --- a/src/types/onyx/ScreenShareRequest.ts +++ b/src/types/onyx/ScreenShareRequest.ts @@ -1,3 +1,4 @@ +/** Model of screen share request */ type ScreenShareRequest = { /** Access token required to join a screen share room, generated by the backend */ accessToken: string; diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts index 5189a125db9c..52afaa44f8d2 100644 --- a/src/types/onyx/SearchResults.ts +++ b/src/types/onyx/SearchResults.ts @@ -5,48 +5,80 @@ import type {ReportListItemType, TransactionListItemType} from '@components/Sele import type {SearchColumnType, SortOrder} from '@libs/SearchUtils'; import type CONST from '@src/CONST'; +/** Types of search data */ type SearchDataTypes = ValueOf; +/** Model of search result list item */ type ListItemType = T extends typeof CONST.SEARCH_DATA_TYPES.TRANSACTION ? typeof TransactionListItem : T extends typeof CONST.SEARCH_DATA_TYPES.REPORT ? typeof ReportListItem : never; +/** Model of search result section */ type SectionsType = T extends typeof CONST.SEARCH_DATA_TYPES.TRANSACTION ? TransactionListItemType[] : T extends typeof CONST.SEARCH_DATA_TYPES.REPORT ? ReportListItemType[] : never; +/** Mapping of search results to list item */ type SearchTypeToItemMap = { [K in SearchDataTypes]: { + /** Collection of search result list item */ listItem: ListItemType; + + /** Returns search results sections based on search results data */ getSections: (data: SearchResults['data']) => SectionsType; + + /** Returns sorted search results sections based on search results data */ getSortedSections: (data: SectionsType, sortBy?: SearchColumnType, sortOrder?: SortOrder) => SectionsType; }; }; +/** Model of search result state */ type SearchResultsInfo = { + /** Current search results offset/cursor */ offset: number; + + /** Type of search */ type: string; + + /** Whether the user can fetch more search results */ hasMoreResults: boolean; + + /** Whether the search results are currently loading */ isLoading: boolean; }; +/** Model of personal details search result */ type SearchPersonalDetails = { + /** ID of user account */ accountID: number; + + /** User's avatar URL */ avatar: string; + + /** User's display name */ displayName?: string; + + /** User's email */ login?: string; }; +/** Model of policy details search result */ type SearchPolicyDetails = { + /** ID of the policy */ id: string; + + /** Policy avatar URL */ avatarURL: string; + + /** Policy name */ name: string; }; +/** Model of report search result */ type SearchReport = { /** The ID of the report */ reportID?: string; @@ -67,6 +99,7 @@ type SearchReport = { action?: string; }; +/** Model of transaction search result */ type SearchTransaction = { /** The ID of the transaction */ transactionID: string; @@ -96,13 +129,19 @@ type SearchTransaction = { modifiedMerchant: string; /** The receipt object */ - receipt?: {source?: string}; + receipt?: { + /** Source of the receipt */ + source?: string; + }; /** The transaction tag */ tag: string; /** The transaction description */ - comment: {comment: string}; + comment: { + /** Content of the transaction description */ + comment: string; + }; /** The transaction category */ category: string; @@ -156,14 +195,21 @@ type SearchTransaction = { moneyRequestReportActionID?: string; }; +/** Model of account details search result */ type SearchAccountDetails = Partial; +/** Types of searchable transactions */ type SearchTransactionType = ValueOf; +/** Types of search queries */ type SearchQuery = ValueOf; +/** Model of search results */ type SearchResults = { + /** Current search results state */ search: SearchResultsInfo; + + /** Search results data */ data: Record> & Record & Record; }; diff --git a/src/types/onyx/SecurityGroup.ts b/src/types/onyx/SecurityGroup.ts index b2362c1eb628..7b213c2e88c8 100644 --- a/src/types/onyx/SecurityGroup.ts +++ b/src/types/onyx/SecurityGroup.ts @@ -1,4 +1,6 @@ +/** Model of security group */ type SecurityGroup = { + /** Whether the security group restricts primary login switching */ hasRestrictedPrimaryLogin: boolean; }; diff --git a/src/types/onyx/SelectedTabRequest.ts b/src/types/onyx/SelectedTabRequest.ts index 8a87db6eee82..db79b948dcde 100644 --- a/src/types/onyx/SelectedTabRequest.ts +++ b/src/types/onyx/SelectedTabRequest.ts @@ -1,6 +1,7 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +/** Selectable IOU request tabs */ type SelectedTabRequest = ValueOf; export default SelectedTabRequest; diff --git a/src/types/onyx/Session.ts b/src/types/onyx/Session.ts index d181114d02d3..7cb47a380717 100644 --- a/src/types/onyx/Session.ts +++ b/src/types/onyx/Session.ts @@ -2,8 +2,10 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type * as OnyxCommon from './OnyxCommon'; +/** Possible states of the automatic authentication after user clicks on a magic link */ type AutoAuthState = ValueOf; +/** Model of user session data */ type Session = { /** The user's email for the current session */ email?: string; @@ -26,6 +28,7 @@ type Session = { /** Currently logged in user accountID */ accountID?: number; + /** Current state of the automatic authentication after user clicks on a magic link */ autoAuthState?: AutoAuthState; /** Server side errors keyed by microtime */ diff --git a/src/types/onyx/Task.ts b/src/types/onyx/Task.ts index ee3b8e8abd87..fcdb97899338 100644 --- a/src/types/onyx/Task.ts +++ b/src/types/onyx/Task.ts @@ -1,5 +1,6 @@ import type Report from './Report'; +/** Model of task data */ type Task = { /** Title of the Task */ title?: string; @@ -7,8 +8,11 @@ type Task = { /** Description of the Task */ description?: string; - // TODO: Make sure this field exists in the API - /** Share destination of the Task */ + /** + * Report ID of the report where the task will be shared + * + * (Note: This variable doesn't exist in the API. It's only used locally for UI purposes) + */ shareDestination?: string; /** The task report if it's currently being edited */ diff --git a/src/types/onyx/Transaction.ts b/src/types/onyx/Transaction.ts index 23b2be2d5de8..21ffaee3f5ce 100644 --- a/src/types/onyx/Transaction.ts +++ b/src/types/onyx/Transaction.ts @@ -9,6 +9,7 @@ import type RecentWaypoint from './RecentWaypoint'; import type ReportAction from './ReportAction'; import type {ViolationName} from './TransactionViolation'; +/** Model of waypoint */ type Waypoint = { /** The name associated with the address of the waypoint */ name?: string; @@ -44,127 +45,256 @@ type Waypoint = { keyForList?: string; }; +/** + * Collection of waypoints, indexed by `waypoint${index}` + * where `index` corresponds to the position of the waypoint in the list + */ type WaypointCollection = Record; +/** Model of transaction comment */ type Comment = { + /** Content of the transaction comment */ comment?: string; + + /** Whether the transaction is on hold */ hold?: string; + + /** Collection of waypoints associated with the transaction */ waypoints?: WaypointCollection; + + /** Whether the transaction comment is loading */ isLoading?: boolean; - type?: string; + + /** Type of the transaction */ + type?: ValueOf; + + /** In custom unit transactions this holds the information of the custom unit */ customUnit?: TransactionCustomUnit; + + /** Source of the transaction which when specified matches `split` */ source?: string; + + /** ID of the original transaction */ originalTransactionID?: string; + + /** In split transactions this is a collection of participant split data */ splits?: Split[]; + + /** Violations that were dismissed */ dismissedViolations?: Record>; }; +/** Model of transaction custom unit */ type TransactionCustomUnit = { + /** ID of the custom unit */ customUnitID?: string; + + /** ID of the custom unit rate */ customUnitRateID?: string; + + /** Custom unit amount */ quantity?: number; - name?: string; + + /** Name of the custom unit */ + name?: ValueOf; + + /** Default rate for custom unit */ defaultP2PRate?: number; }; +/** Types of geometry */ type GeometryType = 'LineString'; +/** Geometry data */ type Geometry = { + /** Matrix of points, indexed by their coordinates */ coordinates: number[][] | null; + + /** Type of connections between coordinates */ type?: GeometryType; }; +/** Accepted receipt paths */ type ReceiptSource = string; +/** Model of receipt */ type Receipt = { - receiptID?: number; - path?: string; + /** Name of receipt file */ name?: string; + + /** Path of the receipt file */ source?: ReceiptSource; + + /** Name of receipt file */ filename?: string; + + /** Current receipt scan state */ state?: ValueOf; + + /** Type of the receipt file */ type?: string; + + /** Collection of reservations */ reservationList?: Reservation[]; }; +/** Model of route */ type Route = { + /** Distance amount of the route */ distance: number | null; + + /** Route geometry data */ geometry: Geometry; }; +/** Collection of routes, indexed by `route${index}` where `index` is the position of the route in the list */ type Routes = Record; -type ReceiptError = {error?: string; source: string; filename: string}; +/** Model of receipt error */ +type ReceiptError = { + /** Path of the receipt file */ + source: string; + + /** Name of the receipt file */ + filename: string; +}; +/** Collection of receipt errors, indexed by a UNIX timestamp of when the error occurred */ type ReceiptErrors = Record; +/** Tax rate data */ type TaxRateData = { - name: string; + /** Tax rate percentage */ value: string; + + /** Tax rate code */ code?: string; }; +/** Model of tax rate */ type TaxRate = { + /** Default name of the tax rate */ text: string; + + /** Key of the tax rate to index it on options list */ keyForList: string; - searchText: string; - tooltipText: string; - isDisabled?: boolean; + + /** Data of the tax rate */ data?: TaxRateData; }; +/** Model of reservation */ type Reservation = { + /** ID of the reservation */ reservationID?: string; + + /** Details about the start of the reservation */ start: ReservationTimeDetails; + + /** Details about the end of the reservation */ end: ReservationTimeDetails; + + /** Type of reservation */ type: ReservationType; + + /** In flight reservations, this represents the details of the airline company */ company?: Company; + + /** Collection of passenger confirmations */ confirmations?: ReservationConfirmation[]; + + /** In flight and car reservations, this represents the number of passengers */ numPassengers?: number; + + /** In hotel reservations, this represents the number of rooms reserved */ numberOfRooms?: number; + + /** In flight reservations, this represents the details of the route */ route?: { + /** Route airline code */ airlineCode: string; + + /** Passenger class */ class?: string; + + /** Passenger seat number */ number: string; }; + + /** In car reservations, this represents the car dealership name */ vendor?: string; + + /** In car reservations, this represents the details of the car */ carInfo?: CarInfo; }; +/** Model of trip reservation time details */ type ReservationTimeDetails = { + /** Date timestamp */ date: string; + + /** In hotel reservations, this is the address of the hotel */ address?: string; + + /** In car reservations, this is the location of the car dealership */ location?: string; + + /** In flight reservations, this is the long name of the airport */ longName?: string; + + /** In flight reservations, this is the short name of the airport */ shortName?: string; + + /** Timezone offset */ timezoneOffset?: string; }; +/** Model of airline company details */ type Company = { + /** Long name of airline company */ longName: string; + + /** Short name of airline company */ shortName?: string; + + /** Phone number of airline company support */ phone?: string; }; +/** Model of reservation confirmation */ type ReservationConfirmation = { + /** Passenger name */ name: string; + + /** Reservation code */ value: string; }; +/** Model of car details */ type CarInfo = { + /** Name of the car */ name?: string; + + /** Engine type */ engine?: string; }; +/** Types of reservations */ type ReservationType = ValueOf; +/** Participant split data */ type SplitShare = { + /** Amount to be split with participant */ amount: number; + + /** Whether the split was modified */ isModified?: boolean; }; +/** Record of participant split data, indexed by their `accountID` */ type SplitShares = Record; +/** Model of transaction */ type Transaction = OnyxCommon.OnyxValueWithOfflineFeedback< { /** The original transaction amount */ @@ -304,17 +434,28 @@ type Transaction = OnyxCommon.OnyxValueWithOfflineFeedback< keyof Comment >; +/** Keys of pending transaction fields */ type TransactionPendingFieldsKey = KeysOfUnion; +/** Additional transaction changes data */ type AdditionalTransactionChanges = { + /** Content of modified comment */ comment?: string; + + /** Collection of modified waypoints */ waypoints?: WaypointCollection; + + /** Previous amount before changes */ oldAmount?: number; + + /** Previous currency before changes */ oldCurrency?: string; }; +/** Model of transaction changes */ type TransactionChanges = Partial & AdditionalTransactionChanges; +/** Collection of mock transactions, indexed by `transactions_${transactionID}` */ type TransactionCollectionDataSet = CollectionDataSet; export default Transaction; diff --git a/src/types/onyx/TransactionViolation.ts b/src/types/onyx/TransactionViolation.ts index ab2037ff336a..745c3c260a1f 100644 --- a/src/types/onyx/TransactionViolation.ts +++ b/src/types/onyx/TransactionViolation.ts @@ -1,38 +1,82 @@ +import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; /** * Names of violations. * Derived from `CONST.VIOLATIONS` to maintain a single source of truth. */ -type ViolationName = (typeof CONST.VIOLATIONS)[keyof typeof CONST.VIOLATIONS]; +type ViolationName = ValueOf; +/** Model of transaction violation data */ +type TransactionViolationData = { + /** Who rejected the transaction */ + rejectedBy?: string; + + /** Why the transaction was rejected */ + rejectReason?: string; + + /** Limit that the transaction violated */ + formattedLimit?: string; + + /** Percentage amount of conversion surcharge applied to the transaction */ + surcharge?: number; + + /** Percentage amount of invoice markup applied to the transaction */ + invoiceMarkup?: number; + + /** Amount of days which the transaction date overpasses the date limit */ + maxAge?: number; + + /** Name of the tag that triggered this violation */ + tagName?: string; + + /** Name of the category that triggered this violation */ + category?: string; + + /** Whether the transaction failed due to a broken bank connection */ + brokenBankConnection?: boolean; + + /** Whether the workspace admin needs to resolve this violation */ + isAdmin?: boolean; + + /** Workspace admin email */ + email?: string; + + /** Whether the transaction is older than 7 days */ + isTransactionOlderThan7Days?: boolean; + + /** Workspace admin name */ + member?: string; + + /** Name of the tax that triggered this violation */ + taxName?: string; + + /** Index of the tag form field that triggered this violation */ + tagListIndex?: number; + + /** Name of the tag form field that triggered this violation */ + tagListName?: string; + + /** Collection of form fields that triggered this violation */ + errorIndexes?: number[]; + + /** Whether the current violation is `pending RTER` */ + pendingPattern?: boolean; +}; + +/** Model of a transaction violation */ type TransactionViolation = { + /** Type of transaction violation ('violation', 'notice', 'warning', ...) */ type: string; + + /** Name of the transaction violation */ name: ViolationName; - data?: { - rejectedBy?: string; - rejectReason?: string; - formattedLimit?: string; - surcharge?: number; - invoiceMarkup?: number; - maxAge?: number; - tagName?: string; - categoryLimit?: string; - limit?: string; - category?: string; - brokenBankConnection?: boolean; - isAdmin?: boolean; - email?: string; - isTransactionOlderThan7Days?: boolean; - member?: string; - taxName?: string; - tagListIndex?: number; - tagListName?: string; - errorIndexes?: number[]; - pendingPattern?: boolean; - }; + + /** Additional violation information to provide the user */ + data?: TransactionViolationData; }; +/** Collection of transaction violations */ type TransactionViolations = TransactionViolation[]; export type {TransactionViolation, ViolationName}; diff --git a/src/types/onyx/TravelSettings.ts b/src/types/onyx/TravelSettings.ts index e653c3378572..2e838ac2d008 100644 --- a/src/types/onyx/TravelSettings.ts +++ b/src/types/onyx/TravelSettings.ts @@ -1,3 +1,4 @@ +/** Model of user travel information to connect with Spotnana */ type TravelSettings = { /** UUIDs that spotnana provides us with when we provision users in their system, and the spotnanaCompanyIDs as the values */ accountIDs: Record; @@ -6,6 +7,7 @@ type TravelSettings = { hasAcceptedTerms: boolean; }; +/** Model of workspace travel information to connect with Spotnana */ type WorkspaceTravelSettings = { /** The UUID that spotnana provides us when we create a “company” in their system */ spotnanaCompanyID: string; diff --git a/src/types/onyx/User.ts b/src/types/onyx/User.ts index 973f09e16b82..f30ca846ef43 100644 --- a/src/types/onyx/User.ts +++ b/src/types/onyx/User.ts @@ -1,3 +1,4 @@ +/** Model of user data */ type User = { /** Whether or not the user is subscribed to news updates */ isSubscribedToNewsletter: boolean; diff --git a/src/types/onyx/UserLocation.ts b/src/types/onyx/UserLocation.ts index b22802bfefb1..8ff0b8f8f101 100644 --- a/src/types/onyx/UserLocation.ts +++ b/src/types/onyx/UserLocation.ts @@ -1,3 +1,4 @@ +/** Location coordinates for user */ type UserLocation = Pick; export default UserLocation; diff --git a/src/types/onyx/UserMetadata.ts b/src/types/onyx/UserMetadata.ts index fc6490264087..642fd035225b 100644 --- a/src/types/onyx/UserMetadata.ts +++ b/src/types/onyx/UserMetadata.ts @@ -1,7 +1,15 @@ +/** Model of user metadata */ type UserMetadata = { + /** Type of user plan */ planType?: string; + + /** Type of user role */ role?: string; + + /** Whether the user is on a free trial */ freeTrial?: boolean; + + /** User's account ID */ accountID?: number; }; diff --git a/src/types/onyx/UserWallet.ts b/src/types/onyx/UserWallet.ts index 55a1b31a9084..eb1b11c7adb0 100644 --- a/src/types/onyx/UserWallet.ts +++ b/src/types/onyx/UserWallet.ts @@ -2,12 +2,16 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type * as OnyxCommon from './OnyxCommon'; +/** Type of account linked to user's wallet */ type WalletLinkedAccountType = 'debitCard' | 'bankAccount'; +/** Error code sent from the server after updating user's wallet */ type ErrorCode = 'ssnError' | 'kbaNeeded' | 'kycFailed'; +/** Type of setup that the user follows to link an account to his wallet */ type SetupType = ValueOf; +/** Model of user wallet */ type UserWallet = { /** The user's available wallet balance */ availableBalance: number; diff --git a/src/types/onyx/WalletAdditionalDetails.ts b/src/types/onyx/WalletAdditionalDetails.ts index c574006e9f66..0593b64ffc3b 100644 --- a/src/types/onyx/WalletAdditionalDetails.ts +++ b/src/types/onyx/WalletAdditionalDetails.ts @@ -1,23 +1,48 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of user wallet Idology question */ type WalletAdditionalQuestionDetails = { + /** Question prompt */ prompt: string; + + /** Question type */ type: string; + + /** Possible answers */ answer: string[]; }; +/** Model of wallet personal details */ type WalletPersonalDetails = { + /** Legal first name */ legalFirstName: string; + + /** Legal last name */ legalLastName: string; + + /** Date of birth */ dob: string; + + /** Social Security Number (SSN) */ ssn: string; + + /** Street address */ addressStreet: string; + + /** City */ addressCity: string; + + /** State */ addressState: string; + + /** ZIP code */ addressZipCode: string; + + /** Phone number */ phoneNumber: string; }; +/** Model of user wallet additional details */ type WalletAdditionalDetails = { /** Questions returned by Idology */ questions?: WalletAdditionalQuestionDetails[]; @@ -30,12 +55,15 @@ type WalletAdditionalDetails = { /** Which field needs attention? */ errorFields?: OnyxCommon.ErrorFields; - additionalErrorMessage?: string; + + /** Whether the details are being loaded */ isLoading?: boolean; + + /** Error messages to display to the user */ errors?: OnyxCommon.Errors; }; -// TODO: refactor into one type after removing old wallet flow +/** TODO: refactor into one type after removing old wallet flow */ type WalletAdditionalDetailsRefactor = WalletAdditionalDetails & WalletPersonalDetails; export default WalletAdditionalDetails; diff --git a/src/types/onyx/WalletOnfido.ts b/src/types/onyx/WalletOnfido.ts index de7c80b34037..344ffdef170c 100644 --- a/src/types/onyx/WalletOnfido.ts +++ b/src/types/onyx/WalletOnfido.ts @@ -1,5 +1,6 @@ import type * as OnyxCommon from './OnyxCommon'; +/** Model of wallet Onfido flow */ type WalletOnfido = { /** Unique identifier returned from openOnfidoFlow then re-sent to ActivateWallet with Onfido response data */ applicantID?: string; diff --git a/src/types/onyx/WalletStatement.ts b/src/types/onyx/WalletStatement.ts index 62b8266c8e43..c9cc72662c1c 100644 --- a/src/types/onyx/WalletStatement.ts +++ b/src/types/onyx/WalletStatement.ts @@ -1,3 +1,4 @@ +/** Model of wallet statement */ type WalletStatement = { /** Whether we are currently generating a PDF version of the statement */ isGenerating: boolean; diff --git a/src/types/onyx/WalletTerms.ts b/src/types/onyx/WalletTerms.ts index c2653cae0f97..be66b779b91f 100644 --- a/src/types/onyx/WalletTerms.ts +++ b/src/types/onyx/WalletTerms.ts @@ -1,6 +1,7 @@ import type {Source} from '@components/KYCWall/types'; import type * as OnyxCommon from './OnyxCommon'; +/** Model of wallet terms */ type WalletTerms = { /** Any error message to show */ errors?: OnyxCommon.Errors; diff --git a/src/types/onyx/WalletTransfer.ts b/src/types/onyx/WalletTransfer.ts index 961a7c9752a5..8bcf6e7217a3 100644 --- a/src/types/onyx/WalletTransfer.ts +++ b/src/types/onyx/WalletTransfer.ts @@ -3,6 +3,7 @@ import type CONST from '@src/CONST'; import type * as OnyxCommon from './OnyxCommon'; import type PaymentMethod from './PaymentMethod'; +/** Model of user wallet transfer */ type WalletTransfer = { /** Selected accountID for transfer */ selectedAccountID?: string | number; @@ -22,9 +23,11 @@ type WalletTransfer = { /** Whether or not data is loading */ loading?: boolean; + /** Payment method used for transfer */ paymentMethodType?: ValueOf>; }; +/** Available payment methods */ type FilterMethodPaymentType = typeof CONST.PAYMENT_METHODS.DEBIT_CARD | typeof CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT | ''; export default WalletTransfer; diff --git a/src/types/onyx/WorkspaceRateAndUnit.ts b/src/types/onyx/WorkspaceRateAndUnit.ts index a374239c93f8..ebef0902d972 100644 --- a/src/types/onyx/WorkspaceRateAndUnit.ts +++ b/src/types/onyx/WorkspaceRateAndUnit.ts @@ -1,5 +1,7 @@ +/** Units of distance */ type Unit = 'mi' | 'km'; +/** Model of workspace distance rate */ type WorkspaceRateAndUnit = { /** policyID of the Workspace */ policyID: string; @@ -7,7 +9,7 @@ type WorkspaceRateAndUnit = { /** Unit of the Workspace */ unit?: Unit; - /** Unit of the Workspace */ + /** Distance rate of the Workspace */ rate?: string; }; diff --git a/tests/ui/UnreadIndicatorsTest.tsx b/tests/ui/UnreadIndicatorsTest.tsx index 0f13062b2e94..7b820281a5a6 100644 --- a/tests/ui/UnreadIndicatorsTest.tsx +++ b/tests/ui/UnreadIndicatorsTest.tsx @@ -607,7 +607,6 @@ describe('Unread Indicators', () => { lastReportAction = reportActions ? CollectionUtils.lastItem(reportActions) : undefined; Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, { lastMessageText: lastReportAction?.message?.[0]?.text, - lastVisibleActionCreated: DateUtils.getDBTime(lastReportAction?.timestamp), lastActorAccountID: lastReportAction?.actorAccountID, reportID: REPORT_ID, }); diff --git a/tests/utils/LHNTestUtils.tsx b/tests/utils/LHNTestUtils.tsx index d35eb61feb35..89c31d92843e 100644 --- a/tests/utils/LHNTestUtils.tsx +++ b/tests/utils/LHNTestUtils.tsx @@ -150,8 +150,6 @@ function getFakeReportAction(actor = 'email1@test.com', millisecondsInThePast = actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, shouldShow: true, created, - timestamp, - reportActionTimestamp: timestamp, person: [ { type: 'TEXT', @@ -168,17 +166,6 @@ function getFakeReportAction(actor = 'email1@test.com', millisecondsInThePast = isEdited: false, whisperedTo: [], isDeletedParentAction: false, - reactions: [ - { - emoji: 'heart', - users: [ - { - accountID: 1, - skinTone: -1, - }, - ], - }, - ], }, ], originalMessage: { @@ -198,17 +185,6 @@ function getFakeReportAction(actor = 'email1@test.com', millisecondsInThePast = }, html: 'hey', lastModified: '2023-08-28 15:28:12.432', - reactions: [ - { - emoji: 'heart', - users: [ - { - accountID: 1, - skinTone: -1, - }, - ], - }, - ], }, }; } diff --git a/tests/utils/ReportTestUtils.ts b/tests/utils/ReportTestUtils.ts index b9dc50aecec0..88fc6fc1bde1 100644 --- a/tests/utils/ReportTestUtils.ts +++ b/tests/utils/ReportTestUtils.ts @@ -19,7 +19,6 @@ const getFakeReportAction = (index: number, actionName?: ActionName): ReportActi html: 'hey', isDeletedParentAction: false, isEdited: false, - reactions: [], text: 'test', type: 'TEXT', whisperedTo: [], @@ -31,6 +30,8 @@ const getFakeReportAction = (index: number, actionName?: ActionName): ReportActi // IOUReportID: index, linkedReportID: index.toString(), whisperedTo: [], + reason: '', + violationName: '', }, pendingAction: null, person: [ @@ -42,10 +43,8 @@ const getFakeReportAction = (index: number, actionName?: ActionName): ReportActi ], reportActionID: index.toString(), previousReportActionID: (index === 0 ? 0 : index - 1).toString(), - reportActionTimestamp: 1696243169753, sequenceNumber: 0, shouldShow: true, - timestamp: 1696243169, } as ReportAction); const getMockedSortedReportActions = (length = 100): ReportAction[] => diff --git a/tests/utils/collections/reportActions.ts b/tests/utils/collections/reportActions.ts index 6dd82c3134ab..dc3e9d8427b5 100644 --- a/tests/utils/collections/reportActions.ts +++ b/tests/utils/collections/reportActions.ts @@ -58,17 +58,6 @@ export default function createRandomReportAction(index: number): ReportAction { isEdited: randBoolean(), isDeletedParentAction: randBoolean(), whisperedTo: randAggregation(), - reactions: [ - { - emoji: randWord(), - users: [ - { - accountID: index, - skinTone: index, - }, - ], - }, - ], }, ], originalMessage: {