From aae942d81a502471c4f84555bc977108d7af1036 Mon Sep 17 00:00:00 2001 From: Youssef Lourayad Date: Wed, 29 May 2024 22:05:23 +0100 Subject: [PATCH 0001/1209] Cleanup optimistic data of unusued IOU report --- src/libs/actions/Report.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index aa134d47cf77..a3a5b3e0a76b 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -186,12 +186,12 @@ const allReportActions: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, - callback: (action, key) => { - if (!key || !action) { + callback: (actions, key) => { + if (!key || !actions) { return; } const reportID = CollectionUtils.extractCollectionItemID(key); - allReportActions[reportID] = action; + allReportActions[reportID] = actions; }, }); @@ -1282,6 +1282,14 @@ function handleReportChanged(report: OnyxEntry) { return; } + if (report?.reportID && report.preexistingReportID && ReportUtils.isMoneyRequestReport(report)) { + Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, { + [report.parentReportActionID]: null, + }); + Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, null); + return; + } + // It is possible that we optimistically created a DM/group-DM for a set of users for which a report already exists. // In this case, the API will let us know by returning a preexistingReportID. // We should clear out the optimistically created report and re-route the user to the preexisting report. From cc0141ed920ef3f6162ad8aaa1458a52e327b5ab Mon Sep 17 00:00:00 2001 From: Sheena Trepanier Date: Mon, 17 Jun 2024 16:44:51 -0700 Subject: [PATCH 0002/1209] Move articles out of Accounts Settings and delete Account Settings --- .../settings/{account-settings => }/Add-profile-photo.md | 0 .../{account-settings => }/Change-or-add-email-address.md | 0 .../{account-settings => }/Close-or-reopen-account.md | 0 .../settings/{account-settings => }/Manage-devices.md | 0 .../settings/{account-settings => }/Merge-accounts.md | 0 .../settings/{account-settings => }/Set-Notifications.md | 0 .../settings/{account-settings => }/Set-time-zone.md | 0 docs/expensify-classic/hubs/settings/account-settings.html | 6 ------ 8 files changed, 6 deletions(-) rename docs/articles/expensify-classic/settings/{account-settings => }/Add-profile-photo.md (100%) rename docs/articles/expensify-classic/settings/{account-settings => }/Change-or-add-email-address.md (100%) rename docs/articles/expensify-classic/settings/{account-settings => }/Close-or-reopen-account.md (100%) rename docs/articles/expensify-classic/settings/{account-settings => }/Manage-devices.md (100%) rename docs/articles/expensify-classic/settings/{account-settings => }/Merge-accounts.md (100%) rename docs/articles/expensify-classic/settings/{account-settings => }/Set-Notifications.md (100%) rename docs/articles/expensify-classic/settings/{account-settings => }/Set-time-zone.md (100%) delete mode 100644 docs/expensify-classic/hubs/settings/account-settings.html diff --git a/docs/articles/expensify-classic/settings/account-settings/Add-profile-photo.md b/docs/articles/expensify-classic/settings/Add-profile-photo.md similarity index 100% rename from docs/articles/expensify-classic/settings/account-settings/Add-profile-photo.md rename to docs/articles/expensify-classic/settings/Add-profile-photo.md diff --git a/docs/articles/expensify-classic/settings/account-settings/Change-or-add-email-address.md b/docs/articles/expensify-classic/settings/Change-or-add-email-address.md similarity index 100% rename from docs/articles/expensify-classic/settings/account-settings/Change-or-add-email-address.md rename to docs/articles/expensify-classic/settings/Change-or-add-email-address.md diff --git a/docs/articles/expensify-classic/settings/account-settings/Close-or-reopen-account.md b/docs/articles/expensify-classic/settings/Close-or-reopen-account.md similarity index 100% rename from docs/articles/expensify-classic/settings/account-settings/Close-or-reopen-account.md rename to docs/articles/expensify-classic/settings/Close-or-reopen-account.md diff --git a/docs/articles/expensify-classic/settings/account-settings/Manage-devices.md b/docs/articles/expensify-classic/settings/Manage-devices.md similarity index 100% rename from docs/articles/expensify-classic/settings/account-settings/Manage-devices.md rename to docs/articles/expensify-classic/settings/Manage-devices.md diff --git a/docs/articles/expensify-classic/settings/account-settings/Merge-accounts.md b/docs/articles/expensify-classic/settings/Merge-accounts.md similarity index 100% rename from docs/articles/expensify-classic/settings/account-settings/Merge-accounts.md rename to docs/articles/expensify-classic/settings/Merge-accounts.md diff --git a/docs/articles/expensify-classic/settings/account-settings/Set-Notifications.md b/docs/articles/expensify-classic/settings/Set-Notifications.md similarity index 100% rename from docs/articles/expensify-classic/settings/account-settings/Set-Notifications.md rename to docs/articles/expensify-classic/settings/Set-Notifications.md diff --git a/docs/articles/expensify-classic/settings/account-settings/Set-time-zone.md b/docs/articles/expensify-classic/settings/Set-time-zone.md similarity index 100% rename from docs/articles/expensify-classic/settings/account-settings/Set-time-zone.md rename to docs/articles/expensify-classic/settings/Set-time-zone.md diff --git a/docs/expensify-classic/hubs/settings/account-settings.html b/docs/expensify-classic/hubs/settings/account-settings.html deleted file mode 100644 index e53f92312b7c..000000000000 --- a/docs/expensify-classic/hubs/settings/account-settings.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -layout: default -title: Account Settings ---- - -{% include section.html %} From e69dd460c76176e324a374bf6905fafa18f2d5cc Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jul 2024 16:09:51 +0530 Subject: [PATCH 0003/1209] Added pluralization system for lang translations --- src/components/MoneyReportHeader.tsx | 4 +- src/components/ProcessMoneyReportHoldMenu.tsx | 2 +- src/components/ReceiptAudit.tsx | 2 +- .../ExportWithDropdownMenu.tsx | 2 +- .../ReportActionItem/ReportPreview.tsx | 13 +- .../Search/SearchListWithHeader.tsx | 4 +- src/components/Search/SearchPageHeader.tsx | 2 +- src/languages/en.ts | 108 ++++++++++------ src/languages/es.ts | 115 +++++++++++------- src/languages/types.ts | 63 ++++++++-- src/libs/Localize/index.ts | 37 +++++- src/libs/PolicyUtils.ts | 5 +- src/libs/ReportActionsUtils.ts | 2 +- src/pages/ReportDetailsPage.tsx | 4 +- src/pages/ReportParticipantsPage.tsx | 2 +- src/pages/Search/SearchSelectedNarrow.tsx | 2 +- .../ReportActionCompose.tsx | 12 +- .../home/report/ReportDetailsExportPage.tsx | 2 +- .../FloatingActionButtonAndPopover.tsx | 2 +- src/pages/wallet/WalletStatementPage.tsx | 2 +- src/pages/workspace/WorkspaceMembersPage.tsx | 2 +- .../intacct/ExistingConnectionsPage.tsx | 4 +- .../intacct/import/SageIntacctImportPage.tsx | 2 +- .../NetSuiteExistingConnectionsPage.tsx | 4 +- .../categories/WorkspaceCategoriesPage.tsx | 2 +- .../PolicyDistanceRateDetailsPage.tsx | 2 +- .../distanceRates/PolicyDistanceRatesPage.tsx | 10 +- .../ReportFieldsListValuesPage.tsx | 2 +- .../WorkspaceReportFieldsPage.tsx | 2 +- .../workspace/tags/WorkspaceTagsPage.tsx | 2 +- .../workspace/tags/WorkspaceViewTagsPage.tsx | 2 +- .../workspace/taxes/WorkspaceTaxesPage.tsx | 2 +- 32 files changed, 273 insertions(+), 148 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 1acee187c67b..18a8c0b9e1a1 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -387,12 +387,12 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea /> )} setIsDeleteRequestModalVisible(false)} onModalHide={() => ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current)} - prompt={translate('iou.deleteConfirmation')} + prompt={translate('iou.deleteConfirmation', undefined, 1)} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} danger diff --git a/src/components/ProcessMoneyReportHoldMenu.tsx b/src/components/ProcessMoneyReportHoldMenu.tsx index 872464d8a5b0..ffc1150a454b 100644 --- a/src/components/ProcessMoneyReportHoldMenu.tsx +++ b/src/components/ProcessMoneyReportHoldMenu.tsx @@ -76,7 +76,7 @@ function ProcessMoneyReportHoldMenu({ if (nonHeldAmount) { return translate(isApprove ? 'iou.confirmApprovalAmount' : 'iou.confirmPayAmount'); } - return translate(isApprove ? 'iou.confirmApprovalAllHoldAmount' : 'iou.confirmPayAllHoldAmount', {transactionCount}); + return translate(isApprove ? 'iou.confirmApprovalAllHoldAmount' : 'iou.confirmPayAllHoldAmount', undefined, transactionCount); }, [nonHeldAmount, transactionCount, translate, isApprove]); return ( diff --git a/src/components/ReceiptAudit.tsx b/src/components/ReceiptAudit.tsx index bb704def1836..1057736621cd 100644 --- a/src/components/ReceiptAudit.tsx +++ b/src/components/ReceiptAudit.tsx @@ -22,7 +22,7 @@ function ReceiptAudit({notes, shouldShowAuditResult}: ReceiptAuditProps) { let auditText = ''; if (notes.length > 0 && shouldShowAuditResult) { - auditText = translate('iou.receiptIssuesFound', notes.length); + auditText = translate('iou.receiptIssuesFound', undefined, notes.length); } else if (!notes.length && shouldShowAuditResult) { auditText = translate('common.verified'); } diff --git a/src/components/ReportActionItem/ExportWithDropdownMenu.tsx b/src/components/ReportActionItem/ExportWithDropdownMenu.tsx index a13c0a266689..2906bee5758f 100644 --- a/src/components/ReportActionItem/ExportWithDropdownMenu.tsx +++ b/src/components/ReportActionItem/ExportWithDropdownMenu.tsx @@ -118,7 +118,7 @@ function ExportWithDropdownMenu({policy, report, connectionName}: ExportWithDrop title={translate('workspace.exportAgainModal.title')} onConfirm={confirmExport} onCancel={() => setModalStatus(null)} - prompt={translate('workspace.exportAgainModal.description', report?.reportName ?? '', connectionName)} + prompt={translate('workspace.exportAgainModal.description', {reportName: report?.reportName ?? '', connectionName})} confirmText={translate('workspace.exportAgainModal.confirmText')} cancelText={translate('workspace.exportAgainModal.cancelText')} isVisible={!!modalStatus} diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index ae6ace23c64e..c794113d0f50 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -328,11 +328,14 @@ function ReportPreview({ return {supportText: formattedMerchant}; } return { - supportText: translate('iou.expenseCount', { - count: numberOfRequests - numberOfScanningReceipts - numberOfPendingRequests, - scanningReceipts: numberOfScanningReceipts, - pendingReceipts: numberOfPendingRequests, - }), + supportText: translate( + 'iou.expenseCount', + { + scanningReceipts: numberOfScanningReceipts, + pendingReceipts: numberOfPendingRequests, + }, + numberOfRequests - numberOfScanningReceipts - numberOfPendingRequests, + ), }; }, [formattedMerchant, formattedDescription, moneyRequestComment, translate, numberOfRequests, numberOfScanningReceipts, numberOfPendingRequests]); diff --git a/src/components/Search/SearchListWithHeader.tsx b/src/components/Search/SearchListWithHeader.tsx index bd4b843bbd60..edfa55a53b26 100644 --- a/src/components/Search/SearchListWithHeader.tsx +++ b/src/components/Search/SearchListWithHeader.tsx @@ -213,8 +213,8 @@ function SearchListWithHeader( isVisible={deleteExpensesConfirmModalVisible} onConfirm={handleDeleteExpenses} onCancel={handleOnCancelConfirmModal} - title={translate('iou.deleteExpense', {count: selectedTransactionsToDelete.length})} - prompt={translate('iou.deleteConfirmation', {count: selectedTransactionsToDelete.length})} + title={translate('iou.deleteExpense', undefined, selectedTransactionsToDelete.length)} + prompt={translate('iou.deleteConfirmation', undefined, selectedTransactionsToDelete.length)} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} danger diff --git a/src/components/Search/SearchPageHeader.tsx b/src/components/Search/SearchPageHeader.tsx index bd1e053b1c7e..0f4843b52a58 100644 --- a/src/components/Search/SearchPageHeader.tsx +++ b/src/components/Search/SearchPageHeader.tsx @@ -221,7 +221,7 @@ function SearchPageHeader({ shouldAlwaysShowDropdownMenu pressOnEnter buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} - customText={translate('workspace.common.selected', {selectedNumber: selectedTransactionsKeys.length})} + customText={translate('workspace.common.selected', undefined, selectedTransactionsKeys.length)} options={headerButtonsOptions} isSplitButton={false} /> diff --git a/src/languages/en.ts b/src/languages/en.ts index b49ad50421a4..5e3b9241aae9 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1,4 +1,4 @@ -import {CONST as COMMON_CONST, Str} from 'expensify-common'; +import {CONST as COMMON_CONST} from 'expensify-common'; import {startCase} from 'lodash'; import CONST from '@src/CONST'; import type {Country} from '@src/CONST'; @@ -17,25 +17,25 @@ import type { ChangePolicyParams, ChangeTypeParams, CharacterLimitParams, - ConfirmHoldExpenseParams, ConfirmThatParams, + CustomersOrJobsLabelTranslationParams, DateShouldBeAfterParams, DateShouldBeBeforeParams, DelegateSubmitParams, DeleteActionParams, DeleteConfirmationParams, - DeleteExpenseTranslationParams, DidSplitAmountMessageParams, - DistanceRateOperationsParams, EditActionParams, ElectronicFundsParams, EnterMagicCodeParams, + ExportAgainModalDescriptionTranslationParams, ExportedToIntegrationParams, FormattedMaxLengthParams, ForwardedParams, GoBackMessageParams, GoToRoomParams, InstantSummaryParams, + LastSyncDateTranslationParams, LocalTimeParams, LoggedInAsParams, LogSizeParams, @@ -66,6 +66,7 @@ import type { ReportArchiveReasonsMergedParams, ReportArchiveReasonsPolicyDeletedParams, ReportArchiveReasonsRemovedFromPolicyParams, + ReportIntegrationMessageTranslationParams, RequestAmountParams, RequestCountParams, RequestedAmountMessageParams, @@ -80,6 +81,7 @@ import type { SignUpNewFaceCodeParams, SizeExceededParams, SplitAmountParams, + StatementPageTitleTranslationParams, StepCounterParams, StripePaidParams, TaskCreatedActionParams, @@ -496,16 +498,14 @@ export default { sendAttachment: 'Send attachment', addAttachment: 'Add attachment', writeSomething: 'Write something...', - conciergePlaceholderOptions: [ - 'Ask for help!', - 'Ask me anything!', - 'Ask me to book travel!', - 'Ask me what I can do!', - 'Ask me how to pay people!', - 'Ask me how to send an invoice!', - 'Ask me how to scan a receipt!', - 'Ask me how to get a free corporate card!', - ], + conciergePlaceholderOptions: (isSmallScreenWidth: boolean) => { + // If we are on a small width device then don't show last 3 items from conciergePlaceholderOptions + const options = ['Ask for help!', 'Ask me anything!', 'Ask me to book travel!', 'Ask me what I can do!', 'Ask me how to pay people!']; + if (!isSmallScreenWidth) { + options.push('Ask me how to send an invoice!', 'Ask me how to scan a receipt!', 'Ask me how to get a free corporate card!'); + } + return options[Math.floor(Math.random() * options.length)]; + }, blockedFromConcierge: 'Communication is barred', fileUploadFailed: 'Upload failed. File is not supported.', localTime: ({user, time}: LocalTimeParams) => `It's ${time} for ${user}`, @@ -654,7 +654,7 @@ export default { splitBill: 'Split expense', splitScan: 'Split receipt', splitDistance: 'Split distance', - paySomeone: (name: string) => `Pay ${name ?? 'someone'}`, + paySomeone: ({name}: PaySomeoneParams) => `Pay ${name ?? 'someone'}`, assignTask: 'Assign task', header: 'Quick action', trackManual: 'Track expense', @@ -700,7 +700,10 @@ export default { receiptScanning: 'Receipt scanning...', receiptScanInProgress: 'Receipt scan in progress', receiptScanInProgressDescription: 'Receipt scan in progress. Check back later or enter the details now.', - receiptIssuesFound: (count: number) => `${count === 1 ? 'Issue' : 'Issues'} found`, + receiptIssuesFound: () => ({ + one: `Issue found`, + other: () => `Issues found`, + }), fieldPending: 'Pending...', defaultRate: 'Default rate', receiptMissingDetails: 'Receipt missing details', @@ -710,12 +713,19 @@ export default { receiptStatusText: "Only you can see this receipt when it's scanning. Check back later or enter the details now.", receiptScanningFailed: 'Receipt scanning failed. Please enter the details manually.', transactionPendingDescription: 'Transaction pending. It may take a few days to post.', - expenseCount: ({count, scanningReceipts = 0, pendingReceipts = 0}: RequestCountParams) => - `${count} ${Str.pluralize('expense', 'expenses', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}${ - pendingReceipts > 0 ? `, ${pendingReceipts} pending` : '' - }`, - deleteExpense: ({count}: DeleteExpenseTranslationParams = {count: 1}) => `Delete ${Str.pluralize('expense', 'expenses', count)}`, - deleteConfirmation: ({count}: DeleteExpenseTranslationParams = {count: 1}) => `Are you sure that you want to delete ${Str.pluralize('this expense', 'these expenses', count)}?`, + expenseCount: ({scanningReceipts = 0, pendingReceipts = 0}: RequestCountParams) => ({ + zero: `0 expenses${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pending` : ''}`, + one: `1 expense${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pending` : ''}`, + other: (count: number) => `${count} expenses${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pending` : ''}`, + }), + deleteExpense: () => ({ + one: `Delete expense`, + other: () => `Delete expenses`, + }), + deleteConfirmation: () => ({ + one: `Are you sure that you want to delete this expense?`, + other: () => `Are you sure that you want to delete these expenses?`, + }), settledExpensify: 'Paid', settledElsewhere: 'Paid elsewhere', individual: 'Individual', @@ -808,12 +818,18 @@ export default { keepAll: 'Keep all', confirmApprove: 'Confirm approval amount', confirmApprovalAmount: 'Approve only compliant expenses, or approve the entire report.', - confirmApprovalAllHoldAmount: ({transactionCount}: ConfirmHoldExpenseParams) => - `${Str.pluralize('This expense is', 'These expenses are', transactionCount)} on hold. Do you want to approve anyway?`, + confirmApprovalAllHoldAmount: () => ({ + zero: `This expense is on hold. Do you want to approve anyway?`, + one: `This expense is on hold. Do you want to approve anyway?`, + other: () => `These expenses are on hold. Do you want to approve anyway?`, + }), confirmPay: 'Confirm payment amount', confirmPayAmount: "Pay what's not on hold, or pay the entire report.", - confirmPayAllHoldAmount: ({transactionCount}: ConfirmHoldExpenseParams) => - `${Str.pluralize('This expense is', 'These expenses are', transactionCount)} on hold. Do you want to pay anyway?`, + confirmPayAllHoldAmount: () => ({ + zero: `This expense is on hold. Do you want to pay anyway?`, + one: `This expense is on hold. Do you want to pay anyway?`, + other: () => `These expenses are on hold. Do you want to pay anyway?`, + }), payOnly: 'Pay only', approveOnly: 'Approve only', holdEducationalTitle: 'This expense is on', @@ -2040,7 +2056,10 @@ export default { testTransactions: 'Test transactions', issueAndManageCards: 'Issue and manage cards', reconcileCards: 'Reconcile cards', - selected: ({selectedNumber}) => `${selectedNumber} selected`, + selected: () => ({ + one: `1 selected`, + other: (count: number) => `${count} selected`, + }), settlementFrequency: 'Settlement frequency', deleteConfirmation: 'Are you sure you want to delete this workspace?', unavailable: 'Unavailable workspace', @@ -2075,7 +2094,7 @@ export default { createNewConnection: 'Create new connection', reuseExistingConnection: 'Reuse existing connection', existingConnections: 'Existing connections', - lastSyncDate: (connectionName: string, formattedDate: string) => `${connectionName} - Last synced ${formattedDate}`, + lastSyncDate: ({connectionName, formattedDate}: LastSyncDateTranslationParams) => `${connectionName} - Last synced ${formattedDate}`, }, qbo: { importDescription: 'Choose which coding configurations to import from QuickBooks Online to Expensify.', @@ -2507,7 +2526,7 @@ export default { importJobs: 'Import projects', customers: 'customers', jobs: 'projects', - label: (importFields: string[], importType: string) => `${importFields.join(' and ')}, ${importType}`, + label: ({importFields, importType}: CustomersOrJobsLabelTranslationParams) => `${importFields.join(' and ')}, ${importType}`, }, importTaxDescription: 'Import tax groups from NetSuite.', importCustomFields: { @@ -2629,7 +2648,10 @@ export default { addAUserDefinedDimension: 'Add a user-defined dimension', detailedInstructionsLink: 'View detailed instructions', detailedInstructionsRestOfSentence: ' on adding user-defined dimensions.', - userDimensionsAdded: (dimensionsCount: number) => `${dimensionsCount} ${Str.pluralize('UDD', `UDDs`, dimensionsCount)} added`, + userDimensionsAdded: () => ({ + one: `1 UDD added`, + other: (count: number) => `${count} UDDs added`, + }), mappingTitle: (mappingName: SageIntacctMappingName): string => { switch (mappingName) { case CONST.SAGE_INTACCT_CONFIG.MAPPINGS.DEPARTMENTS: @@ -3279,9 +3301,18 @@ export default { rate: 'Rate', addRate: 'Add rate', trackTax: 'Track tax', - deleteRates: ({count}: DistanceRateOperationsParams) => `Delete ${Str.pluralize('rate', 'rates', count)}`, - enableRates: ({count}: DistanceRateOperationsParams) => `Enable ${Str.pluralize('rate', 'rates', count)}`, - disableRates: ({count}: DistanceRateOperationsParams) => `Disable ${Str.pluralize('rate', 'rates', count)}`, + deleteRates: () => ({ + one: `Delete 1 rate`, + other: (count: number) => `Delete ${count} rates`, + }), + enableRates: () => ({ + one: `Enable 1 rate`, + other: (count: number) => `Enable ${count} rates`, + }), + disableRates: () => ({ + one: `Disable 1 rate`, + other: (count: number) => `Disable ${count} rates`, + }), enableRate: 'Enable rate', status: 'Status', unit: 'Unit', @@ -3289,7 +3320,10 @@ export default { changePromptMessage: ' to make that change.', defaultCategory: 'Default category', deleteDistanceRate: 'Delete distance rate', - areYouSureDelete: ({count}: DistanceRateOperationsParams) => `Are you sure you want to delete ${Str.pluralize('this rate', 'these rates', count)}?`, + areYouSureDelete: () => ({ + one: `Are you sure you want to delete 1 rate?`, + other: (count: number) => `Are you sure you want to delete ${count} rates?`, + }), }, editor: { descriptionInputLabel: 'Description', @@ -3376,7 +3410,7 @@ export default { }, exportAgainModal: { title: 'Careful!', - description: (reportName: string, connectionName: ConnectionName) => + description: ({reportName, connectionName}: ExportAgainModalDescriptionTranslationParams) => `The following reports have already been exported to ${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]}:\n\n${reportName}\n\nAre you sure you want to export them again?`, confirmText: 'Yes, export again', cancelText: 'Cancel', @@ -3530,7 +3564,7 @@ export default { deleteConfirmation: 'Are you sure you want to delete this task?', }, statementPage: { - title: (year, monthName) => `${monthName} ${year} statement`, + title: ({year, monthName}: StatementPageTitleTranslationParams) => `${monthName} ${year} statement`, generatingPDF: "We're generating your PDF right now. Please check back soon!", }, keyboardShortcutsPage: { @@ -3688,7 +3722,7 @@ export default { pending: ({label}: ExportedToIntegrationParams) => `started exporting this report to ${label}...`, }, forwarded: ({amount, currency}: ForwardedParams) => `approved ${currency}${amount}`, - integrationsMessage: (errorMessage: string, label: string) => `failed to export this report to ${label} ("${errorMessage}").`, + integrationsMessage: ({errorMessage, label}: ReportIntegrationMessageTranslationParams) => `failed to export this report to ${label} ("${errorMessage}").`, managerAttachReceipt: `added a receipt`, managerDetachReceipt: `removed a receipt`, markedReimbursed: ({amount, currency}: MarkedReimbursedParams) => `paid ${currency}${amount} elsewhere`, diff --git a/src/languages/es.ts b/src/languages/es.ts index ff06d4f4f97e..1ce4ac35586b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1,4 +1,3 @@ -import {Str} from 'expensify-common'; import CONST from '@src/CONST'; import type {ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName} from '@src/types/onyx/Policy'; import type { @@ -15,26 +14,26 @@ import type { ChangePolicyParams, ChangeTypeParams, CharacterLimitParams, - ConfirmHoldExpenseParams, ConfirmThatParams, + CustomersOrJobsLabelTranslationParams, DateShouldBeAfterParams, DateShouldBeBeforeParams, DelegateSubmitParams, DeleteActionParams, DeleteConfirmationParams, - DeleteExpenseTranslationParams, DidSplitAmountMessageParams, - DistanceRateOperationsParams, EditActionParams, ElectronicFundsParams, EnglishTranslation, EnterMagicCodeParams, + ExportAgainModalDescriptionTranslationParams, ExportedToIntegrationParams, FormattedMaxLengthParams, ForwardedParams, GoBackMessageParams, GoToRoomParams, InstantSummaryParams, + LastSyncDateTranslationParams, LocalTimeParams, LoggedInAsParams, LogSizeParams, @@ -65,6 +64,7 @@ import type { ReportArchiveReasonsMergedParams, ReportArchiveReasonsPolicyDeletedParams, ReportArchiveReasonsRemovedFromPolicyParams, + ReportIntegrationMessageTranslationParams, RequestAmountParams, RequestCountParams, RequestedAmountMessageParams, @@ -79,6 +79,7 @@ import type { SignUpNewFaceCodeParams, SizeExceededParams, SplitAmountParams, + StatementPageTitleTranslationParams, StepCounterParams, StripePaidParams, TaskCreatedActionParams, @@ -487,16 +488,13 @@ export default { sendAttachment: 'Enviar adjunto', addAttachment: 'Añadir archivo adjunto', writeSomething: 'Escribe algo...', - conciergePlaceholderOptions: [ - '¡Pide ayuda!', - '¡Pregúntame lo que sea!', - '¡Pídeme que te reserve un viaje!', - '¡Pregúntame qué puedo hacer!', - '¡Pregúntame cómo pagar a la gente!', - '¡Pregúntame cómo enviar una factura!', - '¡Pregúntame cómo escanear un recibo!', - '¡Pregúntame cómo obtener una tarjeta de crédito corporativa gratis!', - ], + conciergePlaceholderOptions: (isSmallScreenWidth: boolean) => { + const options = ['¡Pide ayuda!', '¡Pregúntame lo que sea!', '¡Pídeme que te reserve un viaje!', '¡Pregúntame qué puedo hacer!', '¡Pregúntame cómo pagar a la gente!']; + if (!isSmallScreenWidth) { + options.push('¡Pregúntame cómo enviar una factura!', '¡Pregúntame cómo escanear un recibo!', '¡Pregúntame cómo obtener una tarjeta de crédito corporativa gratis!'); + } + return options[Math.floor(Math.random() * options.length)]; + }, blockedFromConcierge: 'Comunicación no permitida', fileUploadFailed: 'Subida fallida. El archivo no es compatible.', localTime: ({user, time}: LocalTimeParams) => `Son las ${time} para ${user}`, @@ -649,7 +647,7 @@ export default { splitBill: 'Dividir gasto', splitScan: 'Dividir recibo', splitDistance: 'Dividir distancia', - paySomeone: (name: string) => `Pagar a ${name ?? 'alguien'}`, + paySomeone: ({name}: PaySomeoneParams) => `Pagar a ${name ?? 'alguien'}`, assignTask: 'Assignar tarea', header: 'Acción rápida', trackManual: 'Crear gasto', @@ -692,7 +690,10 @@ export default { pendingMatchWithCreditCardDescription: 'Recibo pendiente de adjuntar con la transacción de la tarjeta. Márcalo como efectivo para cancelar.', markAsCash: 'Marcar como efectivo', routePending: 'Ruta pendiente...', - receiptIssuesFound: (count: number) => `${count === 1 ? 'Problema encontrado' : 'Problemas encontrados'}`, + receiptIssuesFound: () => ({ + one: `Problema encontrado`, + other: () => `Problemas encontrados`, + }), fieldPending: 'Pendiente...', receiptScanning: 'Escaneando recibo...', receiptScanInProgress: 'Escaneado de recibo en proceso', @@ -705,13 +706,19 @@ export default { receiptStatusText: 'Solo tú puedes ver este recibo cuando se está escaneando. Vuelve más tarde o introduce los detalles ahora.', receiptScanningFailed: 'El escaneo de recibo ha fallado. Introduce los detalles manualmente.', transactionPendingDescription: 'Transacción pendiente. Puede tardar unos días en contabilizarse.', - expenseCount: ({count, scanningReceipts = 0, pendingReceipts = 0}: RequestCountParams) => - `${count} ${Str.pluralize('gasto', 'gastos', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}${ - pendingReceipts > 0 ? `, ${pendingReceipts} pendiente` : '' - }`, - - deleteExpense: ({count}: DeleteExpenseTranslationParams = {count: 1}) => `Eliminar ${Str.pluralize('gasto', 'gastos', count)}`, - deleteConfirmation: ({count}: DeleteExpenseTranslationParams = {count: 1}) => `¿Estás seguro de que quieres eliminar ${Str.pluralize('esta solicitud', 'estas solicitudes', count)}?`, + expenseCount: ({scanningReceipts = 0, pendingReceipts = 0}: RequestCountParams) => ({ + zero: `0 gasto${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pendiente` : ''}`, + one: `1 gasto${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pendiente` : ''}`, + other: (count: number) => `${count} gastos${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pendiente` : ''}`, + }), + deleteExpense: () => ({ + one: `Eliminar gasto`, + other: () => `Eliminar gastos`, + }), + deleteConfirmation: () => ({ + one: `¿Estás seguro de que quieres eliminar esta solicitud?`, + other: () => `¿Estás seguro de que quieres eliminar estas solicitudes?`, + }), settledExpensify: 'Pagado', settledElsewhere: 'Pagado de otra forma', individual: 'Individual', @@ -804,20 +811,18 @@ export default { keepAll: 'Mantener todos', confirmApprove: 'Confirmar importe a aprobar', confirmApprovalAmount: 'Aprueba sólo los gastos conformes, o aprueba todo el informe.', - confirmApprovalAllHoldAmount: ({transactionCount}: ConfirmHoldExpenseParams) => - `${Str.pluralize('Este gasto está bloqueado', 'Estos gastos están bloqueados', transactionCount)}. ¿Quieres ${Str.pluralize( - 'aprobar', - 'aprobarlos', - transactionCount, - )} de todos modos?`, + confirmApprovalAllHoldAmount: () => ({ + zero: `Ningún gasto está bloqueado. ¿Quieres aprobar todo el informe?`, + one: `Este gasto está bloqueado. ¿Quieres aprobarlo de todos modos?`, + other: () => `Estos gastos están bloqueados. ¿Quieres aprobarlos de todos modos?`, + }), confirmPay: 'Confirmar importe de pago', confirmPayAmount: 'Paga lo que no está bloqueado, o paga el informe completo.', - confirmPayAllHoldAmount: ({transactionCount}: ConfirmHoldExpenseParams) => - `${Str.pluralize('Este gasto está bloqueado', 'Estos gastos están bloqueados', transactionCount)}. ¿Quieres ${Str.pluralize( - 'pagar', - 'pagarlo', - transactionCount, - )} de todos modos?`, + confirmPayAllHoldAmount: () => ({ + zero: `Ningún gasto está bloqueado. ¿Quieres pagar todo el informe?`, + one: `Este gasto está bloqueado. ¿Quieres pagarlo de todos modos?`, + other: () => `Estos gastos están bloqueados. ¿Quieres pagarlos de todos modos?`, + }), payOnly: 'Solo pagar', approveOnly: 'Solo aprobar', hold: 'Bloquear', @@ -2074,7 +2079,10 @@ export default { testTransactions: 'Transacciones de prueba', issueAndManageCards: 'Emitir y gestionar tarjetas', reconcileCards: 'Reconciliar tarjetas', - selected: ({selectedNumber}) => `${selectedNumber} seleccionados`, + selected: () => ({ + one: `1 seleccionado`, + other: (count: number) => `${count} seleccionados`, + }), settlementFrequency: 'Frecuencia de liquidación', deleteConfirmation: '¿Estás seguro de que quieres eliminar este espacio de trabajo?', unavailable: 'Espacio de trabajo no disponible', @@ -2110,7 +2118,7 @@ export default { createNewConnection: 'Crear una nueva conexión', reuseExistingConnection: 'Reutilizar la conexión existente', existingConnections: 'Conexiones existentes', - lastSyncDate: (connectionName: string, formattedDate: string) => `${connectionName} - Última sincronización ${formattedDate}`, + lastSyncDate: ({connectionName, formattedDate}: LastSyncDateTranslationParams) => `${connectionName} - Última sincronización ${formattedDate}`, }, qbo: { importDescription: 'Elige que configuraciónes de codificación son importadas desde QuickBooks Online a Expensify.', @@ -2556,7 +2564,7 @@ export default { importJobs: 'Importar proyectos', customers: 'clientes', jobs: 'proyectos', - label: (importFields: string[], importType: string) => `${importFields.join(' y ')}, ${importType}`, + label: ({importFields, importType}: CustomersOrJobsLabelTranslationParams) => `${importFields.join(' y ')}, ${importType}`, }, importTaxDescription: 'Importar grupos de impuestos desde NetSuite.', importCustomFields: { @@ -2678,7 +2686,10 @@ export default { addAUserDefinedDimension: 'Añadir una dimensión definida por el usuario', detailedInstructionsLink: 'Ver instrucciones detalladas', detailedInstructionsRestOfSentence: ' para añadir dimensiones definidas por el usuario.', - userDimensionsAdded: (dimensionsCount: number) => `${dimensionsCount} ${Str.pluralize('UDD', `UDDs`, dimensionsCount)} añadido`, + userDimensionsAdded: () => ({ + one: `1 UDD añadido`, + other: (count: number) => `${count} UDDs añadido`, + }), mappingTitle: (mappingName: SageIntacctMappingName): string => { switch (mappingName) { case CONST.SAGE_INTACCT_CONFIG.MAPPINGS.DEPARTMENTS: @@ -3333,9 +3344,18 @@ export default { rate: 'Tasa', addRate: 'Agregar tasa', trackTax: 'Impuesto de seguimiento', - deleteRates: ({count}: DistanceRateOperationsParams) => `Eliminar ${Str.pluralize('tasa', 'tasas', count)}`, - enableRates: ({count}: DistanceRateOperationsParams) => `Activar ${Str.pluralize('tasa', 'tasas', count)}`, - disableRates: ({count}: DistanceRateOperationsParams) => `Desactivar ${Str.pluralize('tasa', 'tasas', count)}`, + deleteRates: () => ({ + one: `Eliminar 1 tasa`, + other: (count: number) => `Eliminar ${count} tasas`, + }), + enableRates: () => ({ + one: `Activar 1 tasa`, + other: (count: number) => `Activar ${count} tasas`, + }), + disableRates: () => ({ + one: `Desactivar 1 tasa`, + other: (count: number) => `Desactivar ${count} tasas`, + }), enableRate: 'Activar tasa', status: 'Estado', unit: 'Unidad', @@ -3343,7 +3363,10 @@ export default { changePromptMessage: ' para hacer ese cambio.', defaultCategory: 'Categoría predeterminada', deleteDistanceRate: 'Eliminar tasa de distancia', - areYouSureDelete: ({count}: DistanceRateOperationsParams) => `¿Estás seguro de que quieres eliminar ${Str.pluralize('esta tasa', 'estas tasas', count)}?`, + areYouSureDelete: () => ({ + one: `¿Estás seguro de que quieres eliminar 1 tasa?`, + other: (count: number) => `¿Estás seguro de que quieres eliminar ${count} tasas?`, + }), }, editor: { nameInputLabel: 'Nombre', @@ -3432,7 +3455,7 @@ export default { exportAgainModal: { title: '¡Cuidado!', - description: (reportName: string, connectionName: ConnectionName) => + description: ({reportName, connectionName}: ExportAgainModalDescriptionTranslationParams) => `Los siguientes informes ya se han exportado a ${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]}:\n\n${reportName}\n\n¿Estás seguro de que deseas exportarlos de nuevo?`, confirmText: 'Sí, exportar de nuevo', cancelText: 'Cancelar', @@ -3587,7 +3610,7 @@ export default { deleteConfirmation: '¿Estás seguro de que quieres eliminar esta tarea?', }, statementPage: { - title: (year, monthName) => `Estado de cuenta de ${monthName} ${year}`, + title: ({year, monthName}: StatementPageTitleTranslationParams) => `Estado de cuenta de ${monthName} ${year}`, generatingPDF: 'Estamos generando tu PDF ahora mismo. ¡Por favor, vuelve más tarde!', }, keyboardShortcutsPage: { @@ -3746,7 +3769,7 @@ export default { pending: ({label}: ExportedToIntegrationParams) => `comenzó a exportar este informe a ${label}...`, }, forwarded: ({amount, currency}: ForwardedParams) => `aprobado ${currency}${amount}`, - integrationsMessage: (errorMessage: string, label: string) => `no se pudo exportar este informe a ${label} ("${errorMessage}").`, + integrationsMessage: ({errorMessage, label}: ReportIntegrationMessageTranslationParams) => `no se pudo exportar este informe a ${label} ("${errorMessage}").`, managerAttachReceipt: `agregó un recibo`, managerDetachReceipt: `quitó un recibo`, markedReimbursed: ({amount, currency}: MarkedReimbursedParams) => `pagó ${currency}${amount} en otro lugar`, diff --git a/src/languages/types.ts b/src/languages/types.ts index 24117f257d8f..62c96beb323e 100644 --- a/src/languages/types.ts +++ b/src/languages/types.ts @@ -1,5 +1,5 @@ import type {OnyxInputOrEntry, ReportAction} from '@src/types/onyx'; -import type {Unit} from '@src/types/onyx/Policy'; +import type {ConnectionName, Unit} from '@src/types/onyx/Policy'; import type {ViolationDataType} from '@src/types/onyx/TransactionViolation'; import type en from './en'; @@ -96,7 +96,6 @@ type ReportArchiveReasonsPolicyDeletedParams = { }; type RequestCountParams = { - count: number; scanningReceipts: number; pendingReceipts: number; }; @@ -251,9 +250,21 @@ type PaySomeoneParams = {name?: string}; type TaskCreatedActionParams = {title: string}; +type PluralFormPhase = { + zero?: string; + one: string; + two?: string; + few?: (count: number) => string; + many?: (count: number) => string; + other: (count: number) => string; +}; + /* Translation Object types */ // eslint-disable-next-line @typescript-eslint/no-explicit-any -type TranslationBaseValue = string | string[] | ((...args: any[]) => string); +type TranslationPluralPhaseValue = (arg?: any) => PluralFormPhase; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type TranslationSingularFunctionValue = (arg?: any) => string; +type TranslationBaseValue = string | TranslationPluralPhaseValue | TranslationSingularFunctionValue; type TranslationBase = {[key: string]: TranslationBaseValue | TranslationBase}; @@ -261,7 +272,7 @@ type TranslationBase = {[key: string]: TranslationBaseValue | TranslationBase}; // Flattens an object and returns concatenations of all the keys of nested objects type FlattenObject = { // eslint-disable-next-line @typescript-eslint/no-explicit-any - [TKey in keyof TObject]: TObject[TKey] extends (...args: any[]) => any + [TKey in keyof TObject]: TObject[TKey] extends (arg?: any) => any ? `${TPrefix}${TKey & string}` : // eslint-disable-next-line @typescript-eslint/no-explicit-any TObject[TKey] extends any[] @@ -289,6 +300,11 @@ type TranslationFlatObject = { [TKey in TranslationPaths]: TranslateType; }; +type PluralTranslationFlatObject = Pick< + TranslationFlatObject, + {[K in keyof TranslationFlatObject]: TranslationFlatObject[K] extends TranslationPluralPhaseValue ? K : never}[keyof TranslationFlatObject] +>; + type TermsParams = {amount: string}; type ElectronicFundsParams = {percentage: string; amount: string}; @@ -297,12 +313,8 @@ type LogSizeParams = {size: number}; type HeldRequestParams = {comment: string}; -type DistanceRateOperationsParams = {count: number}; - type ReimbursementRateParams = {unit: Unit}; -type ConfirmHoldExpenseParams = {transactionCount: number}; - type ChangeFieldParams = {oldValue?: string; newValue: string; fieldName: string}; type ChangePolicyParams = {fromPolicy: string; toPolicy: string}; @@ -344,8 +356,29 @@ type RemoveMembersWarningPrompt = { ownerName: string; }; -type DeleteExpenseTranslationParams = { - count: number; +type LastSyncDateTranslationParams = { + connectionName: string; + formattedDate: string; +}; + +type CustomersOrJobsLabelTranslationParams = { + importFields: string[]; + importType: string; +}; + +type ExportAgainModalDescriptionTranslationParams = { + reportName: string; + connectionName: ConnectionName; +}; + +type StatementPageTitleTranslationParams = { + year: string | number; + monthName: string; +}; + +type ReportIntegrationMessageTranslationParams = { + errorMessage: string; + label: string; }; export type { @@ -359,14 +392,12 @@ export type { BeginningOfChatHistoryDomainRoomPartOneParams, CanceledRequestParams, CharacterLimitParams, - ConfirmHoldExpenseParams, ConfirmThatParams, DateShouldBeAfterParams, DateShouldBeBeforeParams, DeleteActionParams, DeleteConfirmationParams, DidSplitAmountMessageParams, - DistanceRateOperationsParams, EditActionParams, ElectronicFundsParams, EnglishTranslation, @@ -423,9 +454,11 @@ export type { ThreadSentMoneyReportNameParams, ToValidateLoginParams, TransferParams, + PluralFormPhase, TranslationBase, TranslationFlatObject, TranslationPaths, + PluralTranslationFlatObject, UntilTimeParams, UpdatedTheDistanceParams, UpdatedTheRequestParams, @@ -468,5 +501,9 @@ export type { StripePaidParams, UnapprovedParams, RemoveMembersWarningPrompt, - DeleteExpenseTranslationParams, + LastSyncDateTranslationParams, + CustomersOrJobsLabelTranslationParams, + ExportAgainModalDescriptionTranslationParams, + StatementPageTitleTranslationParams, + ReportIntegrationMessageTranslationParams, }; diff --git a/src/libs/Localize/index.ts b/src/libs/Localize/index.ts index c9eef3170245..f1b705398067 100644 --- a/src/libs/Localize/index.ts +++ b/src/libs/Localize/index.ts @@ -6,7 +6,7 @@ import type {MessageElementBase, MessageTextElement} from '@libs/MessageElement' import Config from '@src/CONFIG'; import CONST from '@src/CONST'; import translations from '@src/languages/translations'; -import type {TranslationFlatObject, TranslationPaths} from '@src/languages/types'; +import type {PluralFormPhase, TranslationFlatObject, TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Locale} from '@src/types/onyx'; import LocaleListener from './LocaleListener'; @@ -45,8 +45,8 @@ function init() { }, {}); } -type PhraseParameters = T extends (...args: infer A) => string ? A : never[]; -type Phrase = TranslationFlatObject[TKey] extends (...args: infer A) => unknown ? (...args: A) => string : string; +type PhraseParameters = T extends (arg: infer A) => string ? [A] : T extends (arg: infer A) => PluralFormPhase ? [A, number] : never[]; +type Phrase = TranslationFlatObject[TKey]; /** * Map to store translated values for each locale. @@ -70,6 +70,23 @@ const translationCache = new Map, Map, Map]>), ); +function handlePluralForm(translatedPhrase: PluralFormPhase, pluralForm: Intl.LDMLPluralRule, count: number) { + switch (pluralForm) { + case 'zero': + return translatedPhrase.zero; + case 'one': + return translatedPhrase.one; + case 'two': + return translatedPhrase.two; + case 'few': + return translatedPhrase.few?.(count); + case 'many': + return translatedPhrase.many?.(count); + default: + return translatedPhrase.other(count); + } +} + /** * Helper function to get the translated string for given * locale and phrase. This function is used to avoid @@ -106,11 +123,21 @@ function getTranslatedPhrase( return valueFromCache; } - const translatedPhrase = translations?.[language]?.[phraseKey] as Phrase; + const translatedPhrase = translations?.[language]?.[phraseKey]; if (translatedPhrase) { if (typeof translatedPhrase === 'function') { - return translatedPhrase(...phraseParameters); + const calledTranslatedPhrase = translatedPhrase(phraseParameters[0]); + if (typeof calledTranslatedPhrase === 'string') { + return calledTranslatedPhrase; + } + const count = phraseParameters[1] ?? 0; + const pluralForm = new Intl.PluralRules(language, {type: 'ordinal'}).select(count); + if (pluralForm in calledTranslatedPhrase) { + return handlePluralForm(calledTranslatedPhrase, pluralForm, count) ?? ''; + } + Log.alert(`Plural form ${pluralForm} is not found for ${phraseKey}, using 'other' form`); + return calledTranslatedPhrase.other(count); } // We set the translated value in the cache only for the phrases without parameters. diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index fe53a7bcd5ce..c3410fbd6516 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -649,7 +649,10 @@ function getCustomersOrJobsLabelNetSuite(policy: Policy | undefined, translate: importFields.push(translate('workspace.netsuite.import.customersOrJobs.jobs')); } - const importedValueLabel = translate(`workspace.netsuite.import.customersOrJobs.label`, importFields, translate(`workspace.accounting.importTypes.${importedValue}`).toLowerCase()); + const importedValueLabel = translate(`workspace.netsuite.import.customersOrJobs.label`, { + importFields, + importType: translate(`workspace.accounting.importTypes.${importedValue}`).toLowerCase(), + }); return importedValueLabel.charAt(0).toUpperCase() + importedValueLabel.slice(1); } diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 73784873201a..f4683abf6100 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1248,7 +1248,7 @@ function getMessageOfOldDotReportAction(oldDotAction: PartialReportAction | OldD case CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE: { const {result, label} = originalMessage; const errorMessage = result?.messages?.join(', ') ?? ''; - return Localize.translateLocal('report.actions.type.integrationsMessage', errorMessage, label); + return Localize.translateLocal('report.actions.type.integrationsMessage', {errorMessage, label}); } case CONST.REPORT.ACTIONS.TYPE.MANAGER_ATTACH_RECEIPT: return Localize.translateLocal('report.actions.type.managerAttachReceipt'); diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 4e82900372b9..5e8c311a79e4 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -763,7 +763,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD shouldEnableNewFocusManagement /> setIsDeleteModalVisible(false)} @@ -779,7 +779,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current, true); } }} - prompt={caseID === CASES.DEFAULT ? translate('task.deleteConfirmation') : translate('iou.deleteConfirmation')} + prompt={caseID === CASES.DEFAULT ? translate('task.deleteConfirmation') : translate('iou.deleteConfirmation', undefined, 1)} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} danger diff --git a/src/pages/ReportParticipantsPage.tsx b/src/pages/ReportParticipantsPage.tsx index 15dd063ec6ee..300122db9be5 100755 --- a/src/pages/ReportParticipantsPage.tsx +++ b/src/pages/ReportParticipantsPage.tsx @@ -268,7 +268,7 @@ function ReportParticipantsPage({report, personalDetails, session}: ReportPartic shouldAlwaysShowDropdownMenu pressOnEnter - customText={translate('workspace.common.selected', {selectedNumber: selectedMembers.length})} + customText={translate('workspace.common.selected', undefined, selectedMembers.length)} buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} onPress={() => null} options={bulkActionsButtonOptions} diff --git a/src/pages/Search/SearchSelectedNarrow.tsx b/src/pages/Search/SearchSelectedNarrow.tsx index 1cc34d6bf53a..039c54dc609a 100644 --- a/src/pages/Search/SearchSelectedNarrow.tsx +++ b/src/pages/Search/SearchSelectedNarrow.tsx @@ -50,7 +50,7 @@ function SearchSelectedNarrow({options, itemsLength}: SearchSelectedNarrowProps) onPress={openMenu} ref={buttonRef} style={[styles.w100, styles.ph5]} - text={translate('workspace.common.selected', {selectedNumber: itemsLength})} + text={translate('workspace.common.selected', undefined, itemsLength)} isContentCentered iconRight={Expensicons.DownArrow} isDisabled={options.length === 0} diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index 6ff163f6ec37..403b7864102f 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -195,13 +195,6 @@ function ReportActionCompose({ const userBlockedFromConcierge = useMemo(() => User.isBlockedFromConcierge(blockedFromConcierge), [blockedFromConcierge]); const isBlockedFromConcierge = useMemo(() => includesConcierge && userBlockedFromConcierge, [includesConcierge, userBlockedFromConcierge]); - // If we are on a small width device then don't show last 3 items from conciergePlaceholderOptions - const conciergePlaceholderRandomIndex = useMemo( - () => Math.floor(Math.random() * (translate('reportActionCompose.conciergePlaceholderOptions').length - (isSmallScreenWidth ? 4 : 1) + 1)), - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - [], - ); - // Placeholder to display in the chat input. const inputPlaceholder = useMemo(() => { if (includesConcierge) { @@ -209,11 +202,12 @@ function ReportActionCompose({ return translate('reportActionCompose.blockedFromConcierge'); } - return translate('reportActionCompose.conciergePlaceholderOptions')[conciergePlaceholderRandomIndex]; + return translate('reportActionCompose.conciergePlaceholderOptions', isSmallScreenWidth); } return translate('reportActionCompose.writeSomething'); - }, [includesConcierge, translate, userBlockedFromConcierge, conciergePlaceholderRandomIndex]); + // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps + }, [includesConcierge, translate, userBlockedFromConcierge]); const focus = () => { if (composerRef.current === null) { diff --git a/src/pages/home/report/ReportDetailsExportPage.tsx b/src/pages/home/report/ReportDetailsExportPage.tsx index 99b7305cc7a9..d6861bd54dd0 100644 --- a/src/pages/home/report/ReportDetailsExportPage.tsx +++ b/src/pages/home/report/ReportDetailsExportPage.tsx @@ -120,7 +120,7 @@ function ReportDetailsExportPage({route}: ReportDetailsExportPageProps) { title={translate('workspace.exportAgainModal.title')} onConfirm={confirmExport} onCancel={() => setModalStatus(null)} - prompt={translate('workspace.exportAgainModal.description', report?.reportName ?? '', connectionName)} + prompt={translate('workspace.exportAgainModal.description', {reportName: report?.reportName ?? '', connectionName})} confirmText={translate('workspace.exportAgainModal.confirmText')} cancelText={translate('workspace.exportAgainModal.cancelText')} isVisible={!!modalStatus} diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index cde3750fc37f..ab18013d6b23 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -212,7 +212,7 @@ function FloatingActionButtonAndPopover( } if (quickAction?.action === CONST.QUICK_ACTIONS.SEND_MONEY && quickActionAvatars.length > 0) { const name: string = ReportUtils.getDisplayNameForParticipant(+(quickActionAvatars[0]?.id ?? -1), true) ?? ''; - return translate('quickAction.paySomeone', name); + return translate('quickAction.paySomeone', {name}); } const titleKey = getQuickActionTitle(quickAction?.action ?? ('' as QuickActionName)); return titleKey ? translate(titleKey) : ''; diff --git a/src/pages/wallet/WalletStatementPage.tsx b/src/pages/wallet/WalletStatementPage.tsx index 0db72877bd2e..54b601a00350 100644 --- a/src/pages/wallet/WalletStatementPage.tsx +++ b/src/pages/wallet/WalletStatementPage.tsx @@ -70,7 +70,7 @@ function WalletStatementPage({walletStatement, route}: WalletStatementPageProps) const year = yearMonth?.substring(0, 4) || getYear(new Date()); const month = yearMonth?.substring(4) || getMonth(new Date()); const monthName = format(new Date(Number(year), Number(month) - 1), CONST.DATE.MONTH_FORMAT); - const title = translate('statementPage.title', year, monthName); + const title = translate('statementPage.title', {year, monthName}); const url = `${CONFIG.EXPENSIFY.EXPENSIFY_URL}statement.php?period=${yearMonth}${themePreference === CONST.THEME.DARK ? '&isDarkMode=true' : ''}`; return ( diff --git a/src/pages/workspace/WorkspaceMembersPage.tsx b/src/pages/workspace/WorkspaceMembersPage.tsx index adbf5a664c82..8b2ca4e09ca1 100644 --- a/src/pages/workspace/WorkspaceMembersPage.tsx +++ b/src/pages/workspace/WorkspaceMembersPage.tsx @@ -503,7 +503,7 @@ function WorkspaceMembersPage({personalDetails, invitedEmailsToAccountIDsDraft, shouldAlwaysShowDropdownMenu pressOnEnter - customText={translate('workspace.common.selected', {selectedNumber: selectedEmployees.length})} + customText={translate('workspace.common.selected', undefined, selectedEmployees.length)} buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} onPress={() => null} options={getBulkActionsButtonOptions()} diff --git a/src/pages/workspace/accounting/intacct/ExistingConnectionsPage.tsx b/src/pages/workspace/accounting/intacct/ExistingConnectionsPage.tsx index c55e46083470..3475d726ba84 100644 --- a/src/pages/workspace/accounting/intacct/ExistingConnectionsPage.tsx +++ b/src/pages/workspace/accounting/intacct/ExistingConnectionsPage.tsx @@ -30,7 +30,9 @@ function ExistingConnectionsPage({route}: ExistingConnectionsPageProps) { key: policy.id, icon: policy.avatarURL ? policy.avatarURL : ReportUtils.getDefaultWorkspaceAvatar(policy.name), iconType: policy.avatarURL ? CONST.ICON_TYPE_AVATAR : CONST.ICON_TYPE_WORKSPACE, - description: date ? translate('workspace.common.lastSyncDate', CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY.intacct, date) : translate('workspace.accounting.intacct'), + description: date + ? translate('workspace.common.lastSyncDate', {connectionName: CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY.intacct, formattedDate: date}) + : translate('workspace.accounting.intacct'), onPress: () => { copyExistingPolicyConnection(policy.id, policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT); Navigation.dismissModal(); diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx index 543d3f4d0154..958e35c5b572 100644 --- a/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx +++ b/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx @@ -128,7 +128,7 @@ function SageIntacctImportPage({policy}: WithPolicyProps) { 0 - ? translate('workspace.intacct.userDimensionsAdded', sageIntacctConfig?.mappings?.dimensions?.length) + ? translate('workspace.intacct.userDimensionsAdded', undefined, sageIntacctConfig?.mappings?.dimensions?.length) : undefined } description={translate('workspace.intacct.userDefinedDimensions')} diff --git a/src/pages/workspace/accounting/netsuite/NetSuiteTokenInput/NetSuiteExistingConnectionsPage.tsx b/src/pages/workspace/accounting/netsuite/NetSuiteTokenInput/NetSuiteExistingConnectionsPage.tsx index ef98625a64e2..5fdca30600c2 100644 --- a/src/pages/workspace/accounting/netsuite/NetSuiteTokenInput/NetSuiteExistingConnectionsPage.tsx +++ b/src/pages/workspace/accounting/netsuite/NetSuiteTokenInput/NetSuiteExistingConnectionsPage.tsx @@ -30,7 +30,9 @@ function NetSuiteExistingConnectionsPage({route}: ExistingConnectionsPageProps) key: policy.id, icon: policy.avatarURL ? policy.avatarURL : ReportUtils.getDefaultWorkspaceAvatar(policy.name), iconType: policy.avatarURL ? CONST.ICON_TYPE_AVATAR : CONST.ICON_TYPE_WORKSPACE, - description: date ? translate('workspace.common.lastSyncDate', CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY.netsuite, date) : translate('workspace.accounting.netsuite'), + description: date + ? translate('workspace.common.lastSyncDate', {connectionName: CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY.netsuite, formattedDate: date}) + : translate('workspace.accounting.netsuite'), onPress: () => { copyExistingPolicyConnection(policy.id, policyID, CONST.POLICY.CONNECTIONS.NAME.NETSUITE); Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING.getRoute(policyID)); diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index 174251a80d5f..12f76fe15abb 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -224,7 +224,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { shouldAlwaysShowDropdownMenu pressOnEnter buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} - customText={translate('workspace.common.selected', {selectedNumber: selectedCategoriesArray.length})} + customText={translate('workspace.common.selected', undefined, selectedCategoriesArray.length)} options={options} isSplitButton={false} style={[shouldUseNarrowLayout && styles.flexGrow1, shouldUseNarrowLayout && styles.mb3]} diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRateDetailsPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRateDetailsPage.tsx index 00204d1e40c7..85e602228149 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRateDetailsPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRateDetailsPage.tsx @@ -194,7 +194,7 @@ function PolicyDistanceRateDetailsPage({policy, route}: PolicyDistanceRateDetail isVisible={isDeleteModalVisible} onConfirm={deleteRate} onCancel={() => setIsDeleteModalVisible(false)} - prompt={translate('workspace.distanceRates.areYouSureDelete', {count: 1})} + prompt={translate('workspace.distanceRates.areYouSureDelete', undefined, 1)} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} danger diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx index 1ef1319973a1..4749c3483571 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx @@ -200,7 +200,7 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps) const getBulkActionsButtonOptions = () => { const options: Array> = [ { - text: translate('workspace.distanceRates.deleteRates', {count: selectedDistanceRates.length}), + text: translate('workspace.distanceRates.deleteRates', undefined, selectedDistanceRates.length), value: CONST.POLICY.BULK_ACTION_TYPES.DELETE, icon: Expensicons.Trashcan, onSelected: () => (canDisableOrDeleteSelectedRates ? setIsDeleteModalVisible(true) : setIsWarningModalVisible(true)), @@ -210,7 +210,7 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps) const enabledRates = selectedDistanceRates.filter((rate) => rate.enabled); if (enabledRates.length > 0) { options.push({ - text: translate('workspace.distanceRates.disableRates', {count: enabledRates.length}), + text: translate('workspace.distanceRates.disableRates', undefined, enabledRates.length), value: CONST.POLICY.BULK_ACTION_TYPES.DISABLE, icon: Expensicons.DocumentSlash, onSelected: () => (canDisableOrDeleteSelectedRates ? disableRates() : setIsWarningModalVisible(true)), @@ -220,7 +220,7 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps) const disabledRates = selectedDistanceRates.filter((rate) => !rate.enabled); if (disabledRates.length > 0) { options.push({ - text: translate('workspace.distanceRates.enableRates', {count: disabledRates.length}), + text: translate('workspace.distanceRates.enableRates', undefined, disabledRates.length), value: CONST.POLICY.BULK_ACTION_TYPES.ENABLE, icon: Expensicons.Document, onSelected: enableRates, @@ -257,7 +257,7 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps) shouldAlwaysShowDropdownMenu pressOnEnter - customText={translate('workspace.common.selected', {selectedNumber: selectedDistanceRates.length})} + customText={translate('workspace.common.selected', undefined, selectedDistanceRates.length)} buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} onPress={() => null} options={getBulkActionsButtonOptions()} @@ -332,7 +332,7 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps) isVisible={isDeleteModalVisible} onConfirm={deleteRates} onCancel={() => setIsDeleteModalVisible(false)} - prompt={translate('workspace.distanceRates.areYouSureDelete', {count: selectedDistanceRates.length})} + prompt={translate('workspace.distanceRates.areYouSureDelete', undefined, selectedDistanceRates.length)} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} danger diff --git a/src/pages/workspace/reportFields/ReportFieldsListValuesPage.tsx b/src/pages/workspace/reportFields/ReportFieldsListValuesPage.tsx index adbe33397950..0d5a6e617aec 100644 --- a/src/pages/workspace/reportFields/ReportFieldsListValuesPage.tsx +++ b/src/pages/workspace/reportFields/ReportFieldsListValuesPage.tsx @@ -249,7 +249,7 @@ function ReportFieldsListValuesPage({ shouldAlwaysShowDropdownMenu pressOnEnter buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} - customText={translate('workspace.common.selected', {selectedNumber: selectedValuesArray.length})} + customText={translate('workspace.common.selected', undefined, selectedValuesArray.length)} options={options} isSplitButton={false} style={[isSmallScreenWidth && styles.flexGrow1, isSmallScreenWidth && styles.mb3]} diff --git a/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx b/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx index f4e3b01145da..4b231f1f2c5f 100644 --- a/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx +++ b/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx @@ -164,7 +164,7 @@ function WorkspaceReportFieldsPage({ shouldAlwaysShowDropdownMenu pressOnEnter buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} - customText={translate('workspace.common.selected', {selectedNumber: selectedReportFields.length})} + customText={translate('workspace.common.selected', undefined, selectedReportFields.length)} options={options} isSplitButton={false} style={[shouldUseNarrowLayout && styles.flexGrow1, shouldUseNarrowLayout && styles.mb3]} diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index cf9952720fc9..dc0dab1634b0 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -276,7 +276,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) { pressOnEnter isSplitButton={false} buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} - customText={translate('workspace.common.selected', {selectedNumber: selectedTagsArray.length})} + customText={translate('workspace.common.selected', undefined, selectedTagsArray.length)} options={options} style={[isSmallScreenWidth && styles.flexGrow1, isSmallScreenWidth && styles.mb3]} /> diff --git a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx index 9ac1fc7583ae..02a9ba0fe0c2 100644 --- a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx @@ -202,7 +202,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) { pressOnEnter isSplitButton={false} buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} - customText={translate('workspace.common.selected', {selectedNumber: selectedTagsArray.length})} + customText={translate('workspace.common.selected', undefined, selectedTagsArray.length)} options={options} style={[isSmallScreenWidth && styles.flexGrow1, isSmallScreenWidth && styles.mb3]} /> diff --git a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx index edd2ef4e3a65..f40b2fc054b9 100644 --- a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx +++ b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx @@ -235,7 +235,7 @@ function WorkspaceTaxesPage({ onPress={() => {}} options={dropdownMenuOptions} buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} - customText={translate('workspace.common.selected', {selectedNumber: selectedTaxesIDs.length})} + customText={translate('workspace.common.selected', undefined, selectedTaxesIDs.length)} shouldAlwaysShowDropdownMenu pressOnEnter isSplitButton={false} From e7df141dd5b4a843ddd128da78d06085a67c28be Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jul 2024 16:54:25 +0530 Subject: [PATCH 0004/1209] Fix lint --- src/components/AddressForm.tsx | 2 +- src/components/ArchivedReportFooter.tsx | 37 +++++++++++++++++++------ tests/unit/TranslateTest.ts | 11 ++------ 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/components/AddressForm.tsx b/src/components/AddressForm.tsx index 7ca4cc3273ca..d6ba5813a101 100644 --- a/src/components/AddressForm.tsx +++ b/src/components/AddressForm.tsx @@ -126,7 +126,7 @@ function AddressForm({ } } } else if (!CONST.GENERIC_ZIP_CODE_REGEX.test(values?.zipPostCode?.trim()?.toUpperCase() ?? '')) { - errors.zipPostCode = translate('privatePersonalDetails.error.incorrectZipFormat'); + errors.zipPostCode = translate('privatePersonalDetails.error.incorrectZipFormat', undefined); } return errors; diff --git a/src/components/ArchivedReportFooter.tsx b/src/components/ArchivedReportFooter.tsx index 35f5aeecb5a4..7e0121a3ae4f 100644 --- a/src/components/ArchivedReportFooter.tsx +++ b/src/components/ArchivedReportFooter.tsx @@ -53,14 +53,35 @@ function ArchivedReportFooter({report, reportClosedAction, personalDetails = {}} policyName = lodashEscape(policyName); } - const text = shouldRenderHTML - ? translate(`reportArchiveReasons.${archiveReason}`, { - displayName: `${displayName}`, - oldDisplayName: `${oldDisplayName}`, - policyName: `${policyName}`, - shouldUseYou: actorPersonalDetails?.accountID === getCurrentUserAccountID(), - }) - : translate(`reportArchiveReasons.${archiveReason}`); + let text; + switch (archiveReason) { + case CONST.REPORT.ARCHIVE_REASON.ACCOUNT_CLOSED: + text = translate(`reportArchiveReasons.${archiveReason}`, { + displayName: `${displayName}`, + }); + break; + case CONST.REPORT.ARCHIVE_REASON.ACCOUNT_MERGED: + text = translate(`reportArchiveReasons.${archiveReason}`, { + displayName: `${displayName}`, + oldDisplayName: `${oldDisplayName}`, + }); + break; + case CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY: + text = translate(`reportArchiveReasons.${archiveReason}`, { + displayName: `${displayName}`, + policyName: `${policyName}`, + shouldUseYou: actorPersonalDetails?.accountID === getCurrentUserAccountID(), + }); + break; + case CONST.REPORT.ARCHIVE_REASON.POLICY_DELETED: + text = translate(`reportArchiveReasons.${archiveReason}`, { + policyName: `${policyName}`, + }); + break; + default: + text = translate(`reportArchiveReasons.${archiveReason}`); + break; + } return ( { expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey4' as TranslationPaths)).toBe('testKey4'); asMutable(CONFIG).IS_IN_PRODUCTION = ORIGINAL_IS_IN_PRODUCTION; }); - - it('Test when translation value is a function', () => { - const expectedValue = 'With variable Test Variable'; - const testVariable = 'Test Variable'; - // @ts-expect-error - TranslationPaths doesn't include testKeyGroup.testFunction as a valid key - expect(Localize.translate(CONST.LOCALES.EN, 'testKeyGroup.testFunction' as TranslationPaths, {testVariable})).toBe(expectedValue); - }); }); describe('Translation Keys', () => { @@ -126,7 +119,7 @@ describe('flattenObject', () => { none: 'No description', }, content: func, - messages: ['Hello', 'Hi', 'Sup!'], + messages: 'Hello!', }, }, }; @@ -141,7 +134,7 @@ describe('flattenObject', () => { 'complex.report.title.task': 'Task', 'complex.report.description.none': 'No description', 'complex.report.content': func, - 'complex.report.messages': ['Hello', 'Hi', 'Sup!'], + 'complex.report.messages': 'Hello!', }); }); }); From dbc34e6ee66d91bd0c9835a8099315d41827ca18 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal <58412969+shubham1206agra@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:10:43 +0530 Subject: [PATCH 0005/1209] Apply suggestions from code review Co-authored-by: Jayesh Mangwani <35371050+jayeshmangwani@users.noreply.github.com> --- src/languages/en.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 5e3b9241aae9..80e37460ac05 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3302,16 +3302,16 @@ export default { addRate: 'Add rate', trackTax: 'Track tax', deleteRates: () => ({ - one: `Delete 1 rate`, - other: (count: number) => `Delete ${count} rates`, + one: 'Delete rate', + other: () => 'Delete rates', }), enableRates: () => ({ - one: `Enable 1 rate`, - other: (count: number) => `Enable ${count} rates`, + one: 'Enable rate', + other: () => 'Enable rates', }), disableRates: () => ({ - one: `Disable 1 rate`, - other: (count: number) => `Disable ${count} rates`, + one: 'Disable rate', + other: () => 'Disable rates', }), enableRate: 'Enable rate', status: 'Status', @@ -3321,8 +3321,8 @@ export default { defaultCategory: 'Default category', deleteDistanceRate: 'Delete distance rate', areYouSureDelete: () => ({ - one: `Are you sure you want to delete 1 rate?`, - other: (count: number) => `Are you sure you want to delete ${count} rates?`, + one: 'Are you sure you want to delete this rate?', + other: () => 'Are you sure you want to delete these rates?', }), }, editor: { From 7f91f9be8ce90c02b2980225267ed120f45cce7c Mon Sep 17 00:00:00 2001 From: Shubham Agrawal <58412969+shubham1206agra@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:14:16 +0530 Subject: [PATCH 0006/1209] Apply suggestions from code review --- src/languages/es.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 1ce4ac35586b..0ae384b5b075 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3345,16 +3345,16 @@ export default { addRate: 'Agregar tasa', trackTax: 'Impuesto de seguimiento', deleteRates: () => ({ - one: `Eliminar 1 tasa`, - other: (count: number) => `Eliminar ${count} tasas`, + one: 'Eliminar tasa', + other: () => 'Eliminar tasas', }), enableRates: () => ({ - one: `Activar 1 tasa`, - other: (count: number) => `Activar ${count} tasas`, + one: 'Activar 1 tasa', + other: () => 'Activar tasas', }), disableRates: () => ({ - one: `Desactivar 1 tasa`, - other: (count: number) => `Desactivar ${count} tasas`, + one: 'Desactivar tasa', + other: () => 'Desactivar tasas', }), enableRate: 'Activar tasa', status: 'Estado', @@ -3364,8 +3364,8 @@ export default { defaultCategory: 'Categoría predeterminada', deleteDistanceRate: 'Eliminar tasa de distancia', areYouSureDelete: () => ({ - one: `¿Estás seguro de que quieres eliminar 1 tasa?`, - other: (count: number) => `¿Estás seguro de que quieres eliminar ${count} tasas?`, + one: '¿Estás seguro de que quieres eliminar esta tasa?', + other: () => '¿Estás seguro de que quieres eliminar estas tasas?', }), }, editor: { From c8dd8d1e696031b4c438c7ac607776c62f3a19ad Mon Sep 17 00:00:00 2001 From: Shubham Agrawal <58412969+shubham1206agra@users.noreply.github.com> Date: Mon, 29 Jul 2024 08:19:44 +0530 Subject: [PATCH 0007/1209] Apply suggestions from code review --- .../home/report/ReportActionCompose/ReportActionCompose.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index 77e8f366d866..275fe000fe79 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -202,7 +202,7 @@ function ReportActionCompose({ return translate('reportActionCompose.blockedFromConcierge'); } - return translate('reportActionCompose.conciergePlaceholderOptions', isSmallScreenWidth); + return translate('reportActionCompose.conciergePlaceholderOptions', shouldUseNarrowLayout); } return translate('reportActionCompose.writeSomething'); From 3a15ab360099f7427680f2ca6327a84338eea4f2 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 30 Jul 2024 18:11:49 +0530 Subject: [PATCH 0008/1209] Fixed unused type --- src/languages/types.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/languages/types.ts b/src/languages/types.ts index 62c96beb323e..611deac1e854 100644 --- a/src/languages/types.ts +++ b/src/languages/types.ts @@ -300,11 +300,6 @@ type TranslationFlatObject = { [TKey in TranslationPaths]: TranslateType; }; -type PluralTranslationFlatObject = Pick< - TranslationFlatObject, - {[K in keyof TranslationFlatObject]: TranslationFlatObject[K] extends TranslationPluralPhaseValue ? K : never}[keyof TranslationFlatObject] ->; - type TermsParams = {amount: string}; type ElectronicFundsParams = {percentage: string; amount: string}; @@ -458,7 +453,6 @@ export type { TranslationBase, TranslationFlatObject, TranslationPaths, - PluralTranslationFlatObject, UntilTimeParams, UpdatedTheDistanceParams, UpdatedTheRequestParams, From fd0b5e7175b1be67111891cc67130ffd3e536419 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 30 Jul 2024 18:27:46 +0530 Subject: [PATCH 0009/1209] Fixed lint --- src/pages/Search/SearchFiltersDatePage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Search/SearchFiltersDatePage.tsx b/src/pages/Search/SearchFiltersDatePage.tsx index 9ac9973c8ca2..ae11e972dc20 100644 --- a/src/pages/Search/SearchFiltersDatePage.tsx +++ b/src/pages/Search/SearchFiltersDatePage.tsx @@ -47,7 +47,7 @@ function SearchFiltersDatePage() { Date: Tue, 30 Jul 2024 19:19:32 +0530 Subject: [PATCH 0010/1209] Fixed lint --- src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index e87a5bb71e3d..f1961dd7b449 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -35,8 +35,8 @@ import type { GoBackMessageParams, GoToRoomParams, InstantSummaryParams, - LastSyncDateTranslationParams, IssueVirtualCardParams, + LastSyncDateTranslationParams, LocalTimeParams, LoggedInAsParams, LogSizeParams, diff --git a/src/languages/es.ts b/src/languages/es.ts index 488cbbca626a..f44850067036 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -33,8 +33,8 @@ import type { GoBackMessageParams, GoToRoomParams, InstantSummaryParams, - LastSyncDateTranslationParams, IssueVirtualCardParams, + LastSyncDateTranslationParams, LocalTimeParams, LoggedInAsParams, LogSizeParams, From 5eed7b5482abfeef2dc723ec9797c04944ce688d Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 1 Aug 2024 18:00:10 +0530 Subject: [PATCH 0011/1209] Apply suggestions --- src/languages/en.ts | 1 - src/languages/es.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index bc91fa1ab428..ec03c97d8948 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -823,7 +823,6 @@ export default { confirmApprove: 'Confirm approval amount', confirmApprovalAmount: 'Approve only compliant expenses, or approve the entire report.', confirmApprovalAllHoldAmount: () => ({ - zero: `This expense is on hold. Do you want to approve anyway?`, one: `This expense is on hold. Do you want to approve anyway?`, other: () => `These expenses are on hold. Do you want to approve anyway?`, }), diff --git a/src/languages/es.ts b/src/languages/es.ts index 3133d6446db2..4a0b72ad237b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -816,7 +816,6 @@ export default { confirmApprove: 'Confirmar importe a aprobar', confirmApprovalAmount: 'Aprueba sólo los gastos conformes, o aprueba todo el informe.', confirmApprovalAllHoldAmount: () => ({ - zero: `Ningún gasto está bloqueado. ¿Quieres aprobar todo el informe?`, one: `Este gasto está bloqueado. ¿Quieres aprobarlo de todos modos?`, other: () => `Estos gastos están bloqueados. ¿Quieres aprobarlos de todos modos?`, }), From 426d50e80e2809e4b6e0b42a643574bf0e51eb53 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 1 Aug 2024 18:01:53 +0530 Subject: [PATCH 0012/1209] Apply suggestions --- src/components/ArchivedReportFooter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ArchivedReportFooter.tsx b/src/components/ArchivedReportFooter.tsx index 7e0121a3ae4f..eeee6c68b73f 100644 --- a/src/components/ArchivedReportFooter.tsx +++ b/src/components/ArchivedReportFooter.tsx @@ -53,7 +53,7 @@ function ArchivedReportFooter({report, reportClosedAction, personalDetails = {}} policyName = lodashEscape(policyName); } - let text; + let text: string; switch (archiveReason) { case CONST.REPORT.ARCHIVE_REASON.ACCOUNT_CLOSED: text = translate(`reportArchiveReasons.${archiveReason}`, { From 158b4c9bd0a56333bf6134d5772468447fd37fe0 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 5 Aug 2024 22:45:35 +0530 Subject: [PATCH 0013/1209] Polyfill plural rules for hermes --- src/languages/es.ts | 2 +- src/libs/IntlPolyfill/index.android.ts | 4 ++++ src/libs/IntlPolyfill/index.ios.ts | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 27d4b40380ed..a2d51f58cd89 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3388,7 +3388,7 @@ export default { other: () => 'Eliminar tasas', }), enableRates: () => ({ - one: 'Activar 1 tasa', + one: 'Activar tasa', other: () => 'Activar tasas', }), disableRates: () => ({ diff --git a/src/libs/IntlPolyfill/index.android.ts b/src/libs/IntlPolyfill/index.android.ts index 7a21ae26bfa4..0f852457e3db 100644 --- a/src/libs/IntlPolyfill/index.android.ts +++ b/src/libs/IntlPolyfill/index.android.ts @@ -11,6 +11,10 @@ const intlPolyfill: IntlPolyfill = () => { require('@formatjs/intl-locale/polyfill'); + require('@formatjs/intl-pluralrules/polyfill'); + require('@formatjs/intl-pluralrules/locale-data/en'); + require('@formatjs/intl-pluralrules/locale-data/es'); + polyfillListFormat(); }; diff --git a/src/libs/IntlPolyfill/index.ios.ts b/src/libs/IntlPolyfill/index.ios.ts index 569b666eb434..0ee189b4d329 100644 --- a/src/libs/IntlPolyfill/index.ios.ts +++ b/src/libs/IntlPolyfill/index.ios.ts @@ -16,6 +16,8 @@ const intlPolyfill: IntlPolyfill = () => { // Required to polyfill NumberFormat on iOS // see: https://github.com/facebook/hermes/issues/1172#issuecomment-1776156538 require('@formatjs/intl-pluralrules/polyfill'); + require('@formatjs/intl-pluralrules/locale-data/en'); + require('@formatjs/intl-pluralrules/locale-data/es'); polyfillNumberFormat(); // Required to polyfill DateTimeFormat on iOS From 2c7a93778e27c7e6faa9b5357abbfc87801a8528 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 5 Aug 2024 22:51:47 +0530 Subject: [PATCH 0014/1209] Adjusting position of code --- src/libs/IntlPolyfill/index.ios.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/IntlPolyfill/index.ios.ts b/src/libs/IntlPolyfill/index.ios.ts index 0ee189b4d329..3a41790aa8b6 100644 --- a/src/libs/IntlPolyfill/index.ios.ts +++ b/src/libs/IntlPolyfill/index.ios.ts @@ -13,11 +13,12 @@ const intlPolyfill: IntlPolyfill = () => { require('@formatjs/intl-locale/polyfill'); - // Required to polyfill NumberFormat on iOS - // see: https://github.com/facebook/hermes/issues/1172#issuecomment-1776156538 require('@formatjs/intl-pluralrules/polyfill'); require('@formatjs/intl-pluralrules/locale-data/en'); require('@formatjs/intl-pluralrules/locale-data/es'); + + // Required to polyfill NumberFormat on iOS + // see: https://github.com/facebook/hermes/issues/1172#issuecomment-1776156538 polyfillNumberFormat(); // Required to polyfill DateTimeFormat on iOS From 4d3087bb7117dd46d304065ff99b2f9514a55d4e Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Wed, 7 Aug 2024 08:05:33 +0700 Subject: [PATCH 0015/1209] update archive feature --- src/libs/SidebarUtils.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index eae047d3eb7f..5abc9f355e2a 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -283,7 +283,7 @@ function getOptionData({ hasParentAccess: undefined, isIOUReportOwner: null, isChatRoom: false, - isArchivedRoom: false, + private_isArchived: undefined, shouldShowSubscript: false, isPolicyExpenseChat: false, isMoneyRequestReport: false, @@ -306,8 +306,7 @@ function getOptionData({ result.isTaskReport = ReportUtils.isTaskReport(report); result.isInvoiceReport = ReportUtils.isInvoiceReport(report); result.parentReportAction = parentReportAction; - const reportNameValuePairs = ReportUtils.getReportNameValuePairs(report?.reportID); - result.isArchivedRoom = ReportUtils.isArchivedRoom(report, reportNameValuePairs); + result.private_isArchived = report.private_isArchived; result.isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); result.isExpenseRequest = ReportUtils.isExpenseRequest(report); result.isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report); @@ -395,8 +394,8 @@ function getOptionData({ const isThreadMessage = ReportUtils.isThread(report) && lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT && lastAction?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; - - if ((result.isChatRoom || result.isPolicyExpenseChat || result.isThread || result.isTaskReport || isThreadMessage) && !result.isArchivedRoom) { + const reportNameValuePairs = ReportUtils.getReportNameValuePairs(report?.reportID); + if ((result.isChatRoom || result.isPolicyExpenseChat || result.isThread || result.isTaskReport || isThreadMessage) && !ReportUtils.isArchivedRoom(report, reportNameValuePairs)) { const lastActionName = lastAction?.actionName ?? report.lastActionType; if (ReportActionsUtils.isRenamedAction(lastAction)) { From 8eccb7b8d2eb29c4321aff594dc7d7fd26a57f99 Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Wed, 7 Aug 2024 08:23:12 +0700 Subject: [PATCH 0016/1209] address lint error --- src/libs/SidebarUtils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 5abc9f355e2a..c12baaa3c5d3 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -283,6 +283,7 @@ function getOptionData({ hasParentAccess: undefined, isIOUReportOwner: null, isChatRoom: false, + // eslint-disable-next-line @typescript-eslint/naming-convention private_isArchived: undefined, shouldShowSubscript: false, isPolicyExpenseChat: false, @@ -306,6 +307,7 @@ function getOptionData({ result.isTaskReport = ReportUtils.isTaskReport(report); result.isInvoiceReport = ReportUtils.isInvoiceReport(report); result.parentReportAction = parentReportAction; + // eslint-disable-next-line @typescript-eslint/naming-convention result.private_isArchived = report.private_isArchived; result.isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); result.isExpenseRequest = ReportUtils.isExpenseRequest(report); From a12bf41f900c4ff8fe78b2381fd64784ed46fc03 Mon Sep 17 00:00:00 2001 From: Rayane Djouah <77965000+rayane-djouah@users.noreply.github.com> Date: Thu, 8 Aug 2024 08:35:34 +0100 Subject: [PATCH 0017/1209] Fix: The pressed state of option menu items uses a very dark BG color --- src/components/MenuItem.tsx | 1 + src/styles/utils/index.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index 8af6cd492c03..4025e4cabc04 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -536,6 +536,7 @@ function MenuItem( onPressOut={ControlSelection.unblock} onSecondaryInteraction={onSecondaryInteraction} wrapperStyle={outerWrapperStyle} + activeOpacity={0.8} style={({pressed}) => [ containerStyle, diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index ed76abd484d0..872b5ee52458 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1290,7 +1290,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ getButtonBackgroundColorStyle: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuItem = false): ViewStyle => { switch (buttonState) { case CONST.BUTTON_STATES.PRESSED: - return {backgroundColor: theme.buttonPressedBG}; + return isMenuItem ? {backgroundColor: theme.buttonHoveredBG} : {backgroundColor: theme.buttonPressedBG}; case CONST.BUTTON_STATES.ACTIVE: return isMenuItem ? {backgroundColor: theme.border} : {backgroundColor: theme.buttonHoveredBG}; case CONST.BUTTON_STATES.DISABLED: From 2428dfac03e32a62f735c6d829072764e361d4e1 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 8 Aug 2024 16:54:27 +0530 Subject: [PATCH 0018/1209] Applying suggestion --- src/components/AddressForm.tsx | 2 +- src/libs/Localize/index.ts | 2 +- src/pages/Search/SearchFiltersDatePage.tsx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/AddressForm.tsx b/src/components/AddressForm.tsx index d6ba5813a101..7ca4cc3273ca 100644 --- a/src/components/AddressForm.tsx +++ b/src/components/AddressForm.tsx @@ -126,7 +126,7 @@ function AddressForm({ } } } else if (!CONST.GENERIC_ZIP_CODE_REGEX.test(values?.zipPostCode?.trim()?.toUpperCase() ?? '')) { - errors.zipPostCode = translate('privatePersonalDetails.error.incorrectZipFormat', undefined); + errors.zipPostCode = translate('privatePersonalDetails.error.incorrectZipFormat'); } return errors; diff --git a/src/libs/Localize/index.ts b/src/libs/Localize/index.ts index f1b705398067..70db13c32851 100644 --- a/src/libs/Localize/index.ts +++ b/src/libs/Localize/index.ts @@ -45,7 +45,7 @@ function init() { }, {}); } -type PhraseParameters = T extends (arg: infer A) => string ? [A] : T extends (arg: infer A) => PluralFormPhase ? [A, number] : never[]; +type PhraseParameters = T extends (arg?: infer A) => string ? [A?] : T extends (arg: infer A) => string ? [A] : T extends (arg: infer A) => PluralFormPhase ? [A, number] : never[]; type Phrase = TranslationFlatObject[TKey]; /** diff --git a/src/pages/Search/SearchFiltersDatePage.tsx b/src/pages/Search/SearchFiltersDatePage.tsx index e2a465f6fa9e..4bc95aa21351 100644 --- a/src/pages/Search/SearchFiltersDatePage.tsx +++ b/src/pages/Search/SearchFiltersDatePage.tsx @@ -53,7 +53,7 @@ function SearchFiltersDatePage() { Date: Thu, 8 Aug 2024 21:12:35 +0530 Subject: [PATCH 0019/1209] Adjusting code --- src/languages/en.ts | 1 - src/languages/es.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 5bcdfdc1cb14..bccd8bdfba18 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -731,7 +731,6 @@ export default { invalidDomainError: 'You have entered an invalid domain. To continue, please enter a valid domain.', publicDomainError: 'You have entered a public domain. To continue, please enter a private domain.', expenseCount: ({scanningReceipts = 0, pendingReceipts = 0}: RequestCountParams) => ({ - zero: `0 expenses${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pending` : ''}`, one: `1 expense${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pending` : ''}`, other: (count: number) => `${count} expenses${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pending` : ''}`, }), diff --git a/src/languages/es.ts b/src/languages/es.ts index bfab43641f85..61cd8baba543 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -724,7 +724,6 @@ export default { invalidDomainError: 'Ha introducido un dominio no válido. Para continuar, introduzca un dominio válido.', publicDomainError: 'Ha introducido un dominio público. Para continuar, introduzca un dominio privado.', expenseCount: ({scanningReceipts = 0, pendingReceipts = 0}: RequestCountParams) => ({ - zero: `0 gasto${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pendiente` : ''}`, one: `1 gasto${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pendiente` : ''}`, other: (count: number) => `${count} gastos${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}${pendingReceipts > 0 ? `, ${pendingReceipts} pendiente` : ''}`, }), From cc7564ef969920814f8c5bdeb7d011ce462e9ded Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Tue, 13 Aug 2024 16:30:34 +0700 Subject: [PATCH 0020/1209] apply the new update --- src/libs/OptionsListUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index b9be3ffac761..98dcf123f53e 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -2332,7 +2332,7 @@ function getHeaderMessageForNonUserList(hasSelectableOptions: boolean, searchVal * Helper method to check whether an option can show tooltip or not */ function shouldOptionShowTooltip(option: ReportUtils.OptionData): boolean { - return (!option.isChatRoom || !!option.isThread) && !option.isArchivedRoom; + return (!option.isChatRoom || !!option.isThread) && !ReportUtils.isArchivedRoom(option, ReportUtils.getReportNameValuePairs(option?.reportID)); } /** From 33ed8e97d029481660daeebf724d759f7ea9e5ea Mon Sep 17 00:00:00 2001 From: Rayane Djouah <77965000+rayane-djouah@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:20:03 +0100 Subject: [PATCH 0021/1209] Update button pressed state background color style in BaseMiniContextMenuItem --- src/components/BaseMiniContextMenuItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BaseMiniContextMenuItem.tsx b/src/components/BaseMiniContextMenuItem.tsx index 6e1a1e0fd229..fa0fdb45153f 100644 --- a/src/components/BaseMiniContextMenuItem.tsx +++ b/src/components/BaseMiniContextMenuItem.tsx @@ -79,7 +79,7 @@ function BaseMiniContextMenuItem( role={CONST.ROLE.BUTTON} style={({hovered, pressed}) => [ styles.reportActionContextMenuMiniButton, - StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, isDelayButtonStateComplete)), + StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, isDelayButtonStateComplete), true), isDelayButtonStateComplete && styles.cursorDefault, ]} > From 56db4fb818f29b11b111161a875df9c7dee48456 Mon Sep 17 00:00:00 2001 From: Stevie LaFortune Date: Wed, 14 Aug 2024 10:02:04 -0500 Subject: [PATCH 0022/1209] Update _routes.yml Adding new hub for NewExpensify for billing and subscriptions --- docs/_data/_routes.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/_data/_routes.yml b/docs/_data/_routes.yml index 85ffbb30c360..2d876700580d 100644 --- a/docs/_data/_routes.yml +++ b/docs/_data/_routes.yml @@ -138,3 +138,9 @@ platforms: title: Settings icon: /assets/images/gears.svg description: Manage profile settings and notifications. + + - href: billing-and-subscriptions + title: Expensify Billing & Subscriptions + icon: /assets/images/subscription-annual.svg + description: Review Expensify's subscription options, plan types, and payment methods. + From eba4b8ddf59cf71c20af489f0b52df1783af9820 Mon Sep 17 00:00:00 2001 From: dominictb Date: Fri, 16 Aug 2024 01:58:54 +0700 Subject: [PATCH 0023/1209] fix User is not task's author or task's assignee has ability to complete the task --- src/components/ReportActionItem/TaskPreview.tsx | 2 +- src/components/ReportActionItem/TaskView.tsx | 3 ++- src/components/TaskHeaderActionButton.tsx | 2 +- src/libs/actions/Task.ts | 8 ++++++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index ca1324a31fa7..0fe498590d17 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -99,7 +99,7 @@ function TaskPreview({taskReport, taskReportID, action, contextMenuAnchor, chatR style={[styles.mr2]} containerStyle={[styles.taskCheckbox]} isChecked={isTaskCompleted} - disabled={!Task.canModifyTask(taskReport, currentUserPersonalDetails.accountID)} + disabled={!Task.canModifyTask(taskReport, currentUserPersonalDetails.accountID) || !Task.canActionTask(taskReport, currentUserPersonalDetails.accountID)} onPress={Session.checkIfActionIsAllowed(() => { if (isTaskCompleted) { Task.reopenTask(taskReport); diff --git a/src/components/ReportActionItem/TaskView.tsx b/src/components/ReportActionItem/TaskView.tsx index 941e7cd5c610..2822e34a3d04 100644 --- a/src/components/ReportActionItem/TaskView.tsx +++ b/src/components/ReportActionItem/TaskView.tsx @@ -56,6 +56,7 @@ function TaskView({report, ...props}: TaskViewProps) { const isCompleted = ReportUtils.isCompletedTaskReport(report); const isOpen = ReportUtils.isOpenTaskReport(report); const canModifyTask = Task.canModifyTask(report, props.currentUserPersonalDetails.accountID); + const canActionTask = Task.canActionTask(report, props.currentUserPersonalDetails.accountID); const disableState = !canModifyTask; const isDisableInteractive = !canModifyTask || !isOpen; const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; @@ -113,7 +114,7 @@ function TaskView({report, ...props}: TaskViewProps) { containerBorderRadius={8} caretSize={16} accessibilityLabel={taskTitle || translate('task.task')} - disabled={!canModifyTask} + disabled={!canModifyTask || !canActionTask} />