From dcc9ac9045009cb51b70a7029b4962371afe3a6c Mon Sep 17 00:00:00 2001 From: dominictb Date: Fri, 21 Jun 2024 17:44:36 +0700 Subject: [PATCH 001/119] fix: delete money request if failed to create chat Signed-off-by: dominictb --- .../ReportActionItem/MoneyRequestView.tsx | 5 + src/libs/actions/IOU.ts | 211 +++++++++++++++++- 2 files changed, 205 insertions(+), 11 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index dfcc1d363e72..8c520052f295 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -391,6 +391,11 @@ function MoneyRequestView({ if (!transaction?.transactionID) { return; } + if (report?.errorFields?.createChat && parentReportAction) { + const urlToNavigateBack = IOU.cleanUpMoneyRequest(transaction.transactionID, parentReportAction, true); + Navigation.goBack(urlToNavigateBack); + return; + } Transaction.clearError(transaction.transactionID); ReportActions.clearAllRelatedReportActionErrors(report.reportID, parentReportAction); }} diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 59fca7e502c3..d775b5ccb4f8 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5265,7 +5265,14 @@ function updateMoneyRequestAmountAndCurrency({ API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_AMOUNT_AND_CURRENCY, params, onyxData); } -function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { +/** + * + * @param transactionID - The transactionID of IOU + * @param reportAction - The reportAction of the transaction in the IOU report + * @param isSingleTransactionView - whether we are in the transaction thread report + * @return the url to navigate back once the money request is deleted + */ +function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { // STEP 1: Get all collections we're updating const iouReportID = reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? reportAction.originalMessage.IOUReportID : '-1'; const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`] ?? null; @@ -5352,6 +5359,196 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor updatedReportPreviewAction.childMoneyRequestCount = reportPreviewAction.childMoneyRequestCount - 1; } + let urlToNavigateBack: ReturnType | undefined; + + // STEP 7: Navigate the user depending on which page they are on and which resources were deleted + if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { + // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. + urlToNavigateBack = ROUTES.REPORT_WITH_ID.getRoute(iouReport.reportID); + } + + if (iouReport?.chatReportID && shouldDeleteIOUReport) { + // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. + urlToNavigateBack = ROUTES.REPORT_WITH_ID.getRoute(iouReport.chatReportID); + } + + return { + shouldDeleteTransactionThread, + shouldDeleteIOUReport, + updatedReportAction, + updatedIOUReport, + updatedReportPreviewAction, + transactionThreadID, + transactionThread, + chatReport, + transaction, + transactionViolations, + reportPreviewAction, + iouReport, + urlToNavigateBack, + }; +} + +/** + * + * @param transactionID - The transactionID of IOU + * @param reportAction - The reportAction of the transaction in the IOU report + * @param isSingleTransactionView - whether we are in the transaction thread report + * @return the url to navigate back once the money request is deleted + */ +function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { + const { + shouldDeleteTransactionThread, + shouldDeleteIOUReport, + updatedReportAction, + updatedIOUReport, + updatedReportPreviewAction, + transactionThreadID, + chatReport, + iouReport, + reportPreviewAction, + urlToNavigateBack, + } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); + + // build Onyx data + + // delete transaction + const onyxUpdates: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`, + value: { + [reportAction.reportActionID]: shouldDeleteIOUReport + ? null + : { + pendingAction: null, + }, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, + value: { + [reportPreviewAction?.reportActionID ?? '-1']: { + pendingAction: null, + errors: null, + }, + }, + }, + ]; + + if (Permissions.canUseViolations(betas)) { + onyxUpdates.push({ + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, + value: null, + }); + } + + if (shouldDeleteTransactionThread) { + onyxUpdates.push( + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadID}`, + value: null, + }, + ); + } + + onyxUpdates.push( + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`, + value: updatedReportAction, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`, + value: updatedIOUReport, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, + value: { + [reportPreviewAction?.reportActionID ?? '-1']: updatedReportPreviewAction, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, + value: ReportUtils.getOutstandingChildRequest(updatedIOUReport), + }, + ); + + if (!shouldDeleteIOUReport && updatedReportPreviewAction.childMoneyRequestCount === 0) { + onyxUpdates.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, + value: { + hasOutstandingChildRequest: false, + }, + }); + } + + if (shouldDeleteIOUReport) { + onyxUpdates.push( + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, + value: { + hasOutstandingChildRequest: false, + iouReportID: null, + lastMessageText: ReportActionsUtils.getLastVisibleMessage(iouReport?.chatReportID ?? '-1', {[reportPreviewAction?.reportActionID ?? '-1']: null})?.lastMessageText, + lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(iouReport?.chatReportID ?? '-1', {[reportPreviewAction?.reportActionID ?? '-1']: null})?.created, + }, + }, + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`, + value: null, + }, + ); + } + + Onyx.update(onyxUpdates); + + return urlToNavigateBack; +} + +/** + * + * @param transactionID - The transactionID of IOU + * @param reportAction - The reportAction of the transaction in the IOU report + * @param isSingleTransactionView - whether we are in the transaction thread report + * @return the url to navigate back once the money request is deleted + */ +function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { + const { + shouldDeleteTransactionThread, + shouldDeleteIOUReport, + updatedReportAction, + updatedIOUReport, + updatedReportPreviewAction, + transactionThreadID, + transactionThread, + chatReport, + transaction, + transactionViolations, + iouReport, + reportPreviewAction, + urlToNavigateBack, + } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); + // STEP 5: Build Onyx data const optimisticData: OnyxUpdate[] = [ { @@ -5557,16 +5754,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor API.write(WRITE_COMMANDS.DELETE_MONEY_REQUEST, parameters, {optimisticData, successData, failureData}); CachedPDFPaths.clearByKey(transactionID); - // STEP 7: Navigate the user depending on which page they are on and which resources were deleted - if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { - // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. - return ROUTES.REPORT_WITH_ID.getRoute(iouReport.reportID); - } - - if (iouReport?.chatReportID && shouldDeleteIOUReport) { - // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. - return ROUTES.REPORT_WITH_ID.getRoute(iouReport.chatReportID); - } + return urlToNavigateBack; } function deleteTrackExpense(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { @@ -6983,6 +7171,7 @@ export { completeSplitBill, createDistanceRequest, createDraftTransaction, + cleanUpMoneyRequest, deleteMoneyRequest, deleteTrackExpense, detachReceipt, From ed0b37e566f9276575588859dce8104257f08809 Mon Sep 17 00:00:00 2001 From: dominictb Date: Fri, 21 Jun 2024 18:47:12 +0700 Subject: [PATCH 002/119] fix: add function to swap err message for local translation Signed-off-by: dominictb --- src/components/LocaleContextProvider.tsx | 8 +++++++- .../ReportActionItem/MoneyRequestView.tsx | 18 +++++++++++++----- src/libs/Localize/index.ts | 19 ++++++++++++++++++- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/components/LocaleContextProvider.tsx b/src/components/LocaleContextProvider.tsx index e0e30d14d2a2..f57a477b929e 100644 --- a/src/components/LocaleContextProvider.tsx +++ b/src/components/LocaleContextProvider.tsx @@ -30,6 +30,8 @@ type LocaleContextProps = { /** Returns translated string for given locale and phrase */ translate: (phraseKey: TKey, ...phraseParameters: Localize.PhraseParameters>) => string; + swapForTranslation: (message: string, messageLocale: Locale) => string; + /** Formats number formatted according to locale and options */ numberFormat: (number: number, options?: Intl.NumberFormatOptions) => string; @@ -69,6 +71,7 @@ const LocaleContext = createContext({ toLocaleDigit: () => '', toLocaleOrdinal: () => '', fromLocaleDigit: () => '', + swapForTranslation: () => '', preferredLocale: CONST.LOCALES.DEFAULT, }); @@ -105,9 +108,12 @@ function LocaleContextProvider({preferredLocale, currentUserPersonalDetails = {} const fromLocaleDigit = useMemo(() => (localeDigit) => LocaleDigitUtils.fromLocaleDigit(locale, localeDigit), [locale]); + const swapForTranslation = useMemo(() => (message, messageLocale) => Localize.swapForTranslation(locale, message, messageLocale), [locale]); + const contextValue = useMemo( () => ({ translate, + swapForTranslation, numberFormat, datetimeToRelative, datetimeToCalendarTime, @@ -118,7 +124,7 @@ function LocaleContextProvider({preferredLocale, currentUserPersonalDetails = {} fromLocaleDigit, preferredLocale: locale, }), - [translate, numberFormat, datetimeToRelative, datetimeToCalendarTime, updateLocale, formatPhoneNumber, toLocaleDigit, toLocaleOrdinal, fromLocaleDigit, locale], + [translate, swapForTranslation, numberFormat, datetimeToRelative, datetimeToCalendarTime, updateLocale, formatPhoneNumber, toLocaleDigit, toLocaleOrdinal, fromLocaleDigit, locale], ); return {children}; diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 8c520052f295..0ca400fe7122 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -100,7 +100,7 @@ function MoneyRequestView({ const styles = useThemeStyles(); const session = useSession(); const {isOffline} = useNetwork(); - const {translate, toLocaleDigit} = useLocalize(); + const {translate, toLocaleDigit, swapForTranslation} = useLocalize(); const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); const parentReportAction = parentReportActions?.[report.parentReportActionID ?? '-1'] ?? null; @@ -336,10 +336,18 @@ function MoneyRequestView({ const shouldShowNotesViolations = !isReceiptBeingScanned && canUseViolations && ReportUtils.isPaidGroupPolicy(report); const shouldShowReceiptHeader = isReceiptAllowed && (shouldShowReceiptEmptyState || hasReceipt); - const errors = { - ...(transaction?.errorFields?.route ?? transaction?.errors), - ...parentReportAction?.errors, - }; + const errors = useMemo(() => { + const combinedErrors = { + ...(transaction?.errorFields?.route ?? transaction?.errors), + ...parentReportAction?.errors, + }; + return Object.fromEntries( + Object.entries(combinedErrors).map(([key, value]) => + // swap for translation for each error message + [key, swapForTranslation(value as string, 'en')] + ), + ); + }, [transaction?.errorFields?.route, transaction?.errors, parentReportAction?.errors, swapForTranslation]); const tagList = policyTagLists.map(({name, orderWeight}, index) => { const tagError = getErrorForField( diff --git a/src/libs/Localize/index.ts b/src/libs/Localize/index.ts index c9eef3170245..fb0b21e5c150 100644 --- a/src/libs/Localize/index.ts +++ b/src/libs/Localize/index.ts @@ -225,5 +225,22 @@ function getDevicePreferredLocale(): Locale { return RNLocalize.findBestAvailableLanguage([CONST.LOCALES.EN, CONST.LOCALES.ES])?.languageTag ?? CONST.LOCALES.DEFAULT; } -export {translate, translateLocal, formatList, formatMessageElementList, getDevicePreferredLocale}; +/** + * This function match the message in the translation mapping and return the translation. + * @param locale - The locale to translate the message to. + * @param message - The message to translate. + * @param messageLocale - The locale of the message. + * @returns {string} - translation of the message or the original message if no translation found + */ +function swapForTranslation(locale: Locale, message: string, messageLocale: Locale): string { + const language = messageLocale.substring(0, 2) as 'en' | 'es'; + const matchedTranslationEntry = Object.entries(translations[language]).find(([, value]) => value === message) as [TranslationPaths, string] | undefined; + if (!matchedTranslationEntry) { + return message; + } + + return translate(locale, matchedTranslationEntry[0]); +} + +export {translate, translateLocal, formatList, formatMessageElementList, getDevicePreferredLocale, swapForTranslation}; export type {PhraseParameters, Phrase}; From 7936055bb58e7f55284ffd0b505619ba2aa3453a Mon Sep 17 00:00:00 2001 From: dominictb Date: Sat, 22 Jun 2024 15:29:08 +0700 Subject: [PATCH 003/119] fix: lint and prettier --- src/components/ReportActionItem/MoneyRequestView.tsx | 6 +++--- src/libs/Localize/index.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 3b9b2c2be183..b3aa40989ea8 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -355,9 +355,9 @@ function MoneyRequestView({ ...parentReportAction?.errors, }; return Object.fromEntries( - Object.entries(combinedErrors).map(([key, value]) => + Object.entries(combinedErrors).map(([key, value]) => // swap for translation for each error message - [key, swapForTranslation(value as string, 'en')] + [key, swapForTranslation(value as string, 'en')], ), ); }, [transaction?.errorFields?.route, transaction?.errors, parentReportAction?.errors, swapForTranslation]); @@ -417,7 +417,7 @@ function MoneyRequestView({ Navigation.goBack(urlToNavigateBack); return; } - + if (Object.values(transaction?.errors ?? {})?.find((error) => ErrorUtils.isReceiptError(error))) { deleteTransaction(parentReport, parentReportAction); } diff --git a/src/libs/Localize/index.ts b/src/libs/Localize/index.ts index fb0b21e5c150..d90d1ba75c09 100644 --- a/src/libs/Localize/index.ts +++ b/src/libs/Localize/index.ts @@ -230,7 +230,7 @@ function getDevicePreferredLocale(): Locale { * @param locale - The locale to translate the message to. * @param message - The message to translate. * @param messageLocale - The locale of the message. - * @returns {string} - translation of the message or the original message if no translation found + * @returns - translation of the message or the original message if no translation found */ function swapForTranslation(locale: Locale, message: string, messageLocale: Locale): string { const language = messageLocale.substring(0, 2) as 'en' | 'es'; From 68c4ca74fdf1468154394eaef66cca2ab7c4c22e Mon Sep 17 00:00:00 2001 From: dominictb Date: Mon, 24 Jun 2024 16:37:49 +0700 Subject: [PATCH 004/119] fix: check optimistic report before cleaning up money request Signed-off-by: dominictb --- src/components/ReportActionItem/MoneyRequestView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index b3aa40989ea8..456bbd2c6721 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -412,7 +412,7 @@ function MoneyRequestView({ if (!transaction?.transactionID) { return; } - if (report?.errorFields?.createChat && parentReportAction) { + if ((report?.errorFields?.createChat || report.isOptimisticReport) && parentReportAction) { const urlToNavigateBack = IOU.cleanUpMoneyRequest(transaction.transactionID, parentReportAction, true); Navigation.goBack(urlToNavigateBack); return; From 083c790b9df02433d5d471b3c8752b875d353f34 Mon Sep 17 00:00:00 2001 From: dominictb Date: Mon, 24 Jun 2024 16:45:26 +0700 Subject: [PATCH 005/119] chore: add translation Signed-off-by: dominictb --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index cced280d97df..a6793b8a9bac 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -754,6 +754,7 @@ export default { atLeastTwoDifferentWaypoints: 'Please enter at least two different addresses.', splitExpenseMultipleParticipantsErrorMessage: 'An expense cannot be split between a workspace and other members. Please update your selection.', invalidMerchant: 'Please enter a correct merchant.', + workspaceNotAccessible: 'The workspace is no longer accessible. Please try again on a different workspace.', }, waitingOnEnabledWallet: ({submitterDisplayName}: WaitingOnBankAccountParams) => `started settling up. Payment is on hold until ${submitterDisplayName} enables their wallet.`, enableWallet: 'Enable Wallet', diff --git a/src/languages/es.ts b/src/languages/es.ts index 2471450ad8d0..2c8986889e18 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -750,6 +750,7 @@ export default { atLeastTwoDifferentWaypoints: 'Por favor, introduce al menos dos direcciones diferentes.', splitExpenseMultipleParticipantsErrorMessage: 'Solo puedes dividir un gasto entre un único espacio de trabajo o con usuarios individuales. Por favor, actualiza tu selección.', invalidMerchant: 'Por favor, introduce un comerciante correcto.', + workspaceNotAccessible: 'El espacio de trabajo ya no está accesible. Por favor, intente de nuevo en un espacio de trabajo diferente.', }, waitingOnEnabledWallet: ({submitterDisplayName}: WaitingOnBankAccountParams) => `inició el pago, pero no se procesará hasta que ${submitterDisplayName} active tu billetera`, enableWallet: 'Habilitar Billetera', From 5951c3804c658619d05bff50fd1b788cb0571062 Mon Sep 17 00:00:00 2001 From: dominictb Date: Mon, 24 Jun 2024 16:52:44 +0700 Subject: [PATCH 006/119] fix: lint Signed-off-by: dominictb --- src/components/ReportActionItem/MoneyRequestView.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 456bbd2c6721..3d16ab720722 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -412,7 +412,8 @@ function MoneyRequestView({ if (!transaction?.transactionID) { return; } - if ((report?.errorFields?.createChat || report.isOptimisticReport) && parentReportAction) { + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + if ((!!report?.errorFields?.createChat || !!report.isOptimisticReport) && parentReportAction) { const urlToNavigateBack = IOU.cleanUpMoneyRequest(transaction.transactionID, parentReportAction, true); Navigation.goBack(urlToNavigateBack); return; From b3833834aff35d25ccd08619dbcb9906ababf444 Mon Sep 17 00:00:00 2001 From: dominictb Date: Wed, 26 Jun 2024 19:00:08 +0700 Subject: [PATCH 007/119] fix: improve translation key swapping logic Signed-off-by: dominictb --- src/components/LocaleContextProvider.tsx | 4 ++-- .../ReportActionItem/MoneyRequestView.tsx | 2 +- src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- src/languages/msgTranslationKeySwapMapping.ts | 8 ++++++++ src/libs/Localize/index.ts | 13 ++++++------- 6 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 src/languages/msgTranslationKeySwapMapping.ts diff --git a/src/components/LocaleContextProvider.tsx b/src/components/LocaleContextProvider.tsx index f57a477b929e..4a7d6061fdbc 100644 --- a/src/components/LocaleContextProvider.tsx +++ b/src/components/LocaleContextProvider.tsx @@ -30,7 +30,7 @@ type LocaleContextProps = { /** Returns translated string for given locale and phrase */ translate: (phraseKey: TKey, ...phraseParameters: Localize.PhraseParameters>) => string; - swapForTranslation: (message: string, messageLocale: Locale) => string; + swapForTranslation: (message: string) => string; /** Formats number formatted according to locale and options */ numberFormat: (number: number, options?: Intl.NumberFormatOptions) => string; @@ -108,7 +108,7 @@ function LocaleContextProvider({preferredLocale, currentUserPersonalDetails = {} const fromLocaleDigit = useMemo(() => (localeDigit) => LocaleDigitUtils.fromLocaleDigit(locale, localeDigit), [locale]); - const swapForTranslation = useMemo(() => (message, messageLocale) => Localize.swapForTranslation(locale, message, messageLocale), [locale]); + const swapForTranslation = useMemo(() => (message) => Localize.swapForTranslation(locale, message), [locale]); const contextValue = useMemo( () => ({ diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 59c1eca207a7..3a3f7736fb72 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -357,7 +357,7 @@ function MoneyRequestView({ return Object.fromEntries( Object.entries(combinedErrors).map(([key, value]) => // swap for translation for each error message - [key, swapForTranslation(value as string, 'en')], + [key, swapForTranslation(value as string)], ), ); }, [transaction?.errorFields?.route, transaction?.errors, parentReportAction?.errors, swapForTranslation]); diff --git a/src/languages/en.ts b/src/languages/en.ts index 8194037ef194..0e75bfc37c60 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -754,7 +754,7 @@ export default { atLeastTwoDifferentWaypoints: 'Please enter at least two different addresses.', splitExpenseMultipleParticipantsErrorMessage: 'An expense cannot be split between a workspace and other members. Please update your selection.', invalidMerchant: 'Please enter a correct merchant.', - workspaceNotAccessible: 'The workspace is no longer accessible. Please try again on a different workspace.', + workspaceNotAccessible: 'The workspace you selected is no longer accessible, possibly because it has been deleted or you no longer have access to it.', }, waitingOnEnabledWallet: ({submitterDisplayName}: WaitingOnBankAccountParams) => `started settling up. Payment is on hold until ${submitterDisplayName} enables their wallet.`, enableWallet: 'Enable Wallet', diff --git a/src/languages/es.ts b/src/languages/es.ts index 0b8ce0d6c31e..a69ebe085325 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -750,7 +750,7 @@ export default { atLeastTwoDifferentWaypoints: 'Por favor, introduce al menos dos direcciones diferentes.', splitExpenseMultipleParticipantsErrorMessage: 'Solo puedes dividir un gasto entre un único espacio de trabajo o con usuarios individuales. Por favor, actualiza tu selección.', invalidMerchant: 'Por favor, introduce un comerciante correcto.', - workspaceNotAccessible: 'El espacio de trabajo ya no está accesible. Por favor, intente de nuevo en un espacio de trabajo diferente.', + workspaceNotAccessible: 'El espacio de trabajo que seleccionaste ya no está accesible, posiblemente porque ha sido eliminado o ya no tienes acceso a él.', }, waitingOnEnabledWallet: ({submitterDisplayName}: WaitingOnBankAccountParams) => `inició el pago, pero no se procesará hasta que ${submitterDisplayName} active su billetera`, enableWallet: 'Habilitar Billetera', diff --git a/src/languages/msgTranslationKeySwapMapping.ts b/src/languages/msgTranslationKeySwapMapping.ts new file mode 100644 index 000000000000..6a9a9b336538 --- /dev/null +++ b/src/languages/msgTranslationKeySwapMapping.ts @@ -0,0 +1,8 @@ +const mapping: Record = { + // eslint-disable-next-line @typescript-eslint/naming-convention + 'The workspace is no longer accessible. Please try again on a different workspace.': 'iou.error.workspaceNotAccessible', + // eslint-disable-next-line @typescript-eslint/naming-convention + 'Unexpected error submitting this expense. Please try again later.': 'iou.error.genericCreateFailureMessage', +}; + +export default mapping; diff --git a/src/libs/Localize/index.ts b/src/libs/Localize/index.ts index d90d1ba75c09..5d19b19d5bae 100644 --- a/src/libs/Localize/index.ts +++ b/src/libs/Localize/index.ts @@ -5,6 +5,7 @@ import Log from '@libs/Log'; import type {MessageElementBase, MessageTextElement} from '@libs/MessageElement'; import Config from '@src/CONFIG'; import CONST from '@src/CONST'; +import msgTranslationKeySwapMapping from '@src/languages/msgTranslationKeySwapMapping'; import translations from '@src/languages/translations'; import type {TranslationFlatObject, TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -232,14 +233,12 @@ function getDevicePreferredLocale(): Locale { * @param messageLocale - The locale of the message. * @returns - translation of the message or the original message if no translation found */ -function swapForTranslation(locale: Locale, message: string, messageLocale: Locale): string { - const language = messageLocale.substring(0, 2) as 'en' | 'es'; - const matchedTranslationEntry = Object.entries(translations[language]).find(([, value]) => value === message) as [TranslationPaths, string] | undefined; - if (!matchedTranslationEntry) { - return message; +function swapForTranslation(locale: Locale, message: string): string { + const translationKey: string | undefined = msgTranslationKeySwapMapping[message]; + if (translationKey) { + return translate(locale, translationKey as TranslationPaths); } - - return translate(locale, matchedTranslationEntry[0]); + return message; } export {translate, translateLocal, formatList, formatMessageElementList, getDevicePreferredLocale, swapForTranslation}; From 65bd81d8f95a0a4bbcc9d718e3813b535ccb268d Mon Sep 17 00:00:00 2001 From: dominictb Date: Fri, 28 Jun 2024 09:41:09 +0700 Subject: [PATCH 008/119] fix: comment --- src/libs/Localize/index.ts | 1 - src/libs/actions/IOU.ts | 14 ++++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/libs/Localize/index.ts b/src/libs/Localize/index.ts index 5d19b19d5bae..87764fb73aeb 100644 --- a/src/libs/Localize/index.ts +++ b/src/libs/Localize/index.ts @@ -230,7 +230,6 @@ function getDevicePreferredLocale(): Locale { * This function match the message in the translation mapping and return the translation. * @param locale - The locale to translate the message to. * @param message - The message to translate. - * @param messageLocale - The locale of the message. * @returns - translation of the message or the original message if no translation found */ function swapForTranslation(locale: Locale, message: string): string { diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index f72d82fd5ae1..6b397f39e725 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5369,7 +5369,8 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT let urlToNavigateBack: ReturnType | undefined; - // STEP 7: Navigate the user depending on which page they are on and which resources were deleted + // STEP 5: Calculate what is the url that we will navigate user back + // This depends on which page they are on and which resources were deleted if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. urlToNavigateBack = ROUTES.REPORT_WITH_ID.getRoute(iouReport.reportID); @@ -5420,7 +5421,7 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo // build Onyx data - // delete transaction + // Onyx operations to delete the transaction, update the IOU report action and chat report action const onyxUpdates: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.SET, @@ -5450,6 +5451,7 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo }, ]; + // added the operation to delete associated transaction violations if (Permissions.canUseViolations(betas)) { onyxUpdates.push({ onyxMethod: Onyx.METHOD.SET, @@ -5458,6 +5460,7 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo }); } + // added the operation to delete transaction thread if (shouldDeleteTransactionThread) { onyxUpdates.push( { @@ -5473,6 +5476,7 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo ); } + // added operations to update IOU report and chat report onyxUpdates.push( { onyxMethod: Onyx.METHOD.MERGE, @@ -5541,6 +5545,7 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo * @return the url to navigate back once the money request is deleted */ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { + // STEP 1: Calculate and prepare the data const { shouldDeleteTransactionThread, shouldDeleteIOUReport, @@ -5557,7 +5562,8 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor urlToNavigateBack, } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); - // STEP 5: Build Onyx data + // STEP 2: Build Onyx data + // The logic mostly resembles the cleanUpMoneyRequest function const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.SET, @@ -5758,7 +5764,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor reportActionID: reportAction.reportActionID, }; - // STEP 6: Make the API request + // STEP 3: Make the API request API.write(WRITE_COMMANDS.DELETE_MONEY_REQUEST, parameters, {optimisticData, successData, failureData}); CachedPDFPaths.clearByKey(transactionID); From 041bed4abe7222837fe7d858167eca7c6c84a5d5 Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 4 Jul 2024 11:49:38 +0700 Subject: [PATCH 009/119] fix: set errors and IOUTransactionID to null when deleting report action of IOU report in cleanUpMoneyRequest function Signed-off-by: dominictb --- src/libs/actions/IOU.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 6d6f2a0c3112..6b1b3351b3ac 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1,6 +1,6 @@ import {format} from 'date-fns'; import {fastMerge, Str} from 'expensify-common'; -import type {OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate} from 'react-native-onyx'; +import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import ReceiptGeneric from '@assets/images/receipt-generic.png'; @@ -5317,11 +5317,11 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT }, ], originalMessage: { - IOUTransactionID: undefined, + IOUTransactionID: null, }, - errors: undefined, + errors: null, }, - } as OnyxTypes.ReportActions; + } as NullishDeep; const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1', updatedReportAction); const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1', updatedReportAction).lastMessageText; From 41768f415f9c61bcc279469e9988c0915728b36a Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 4 Jul 2024 15:08:50 +0700 Subject: [PATCH 010/119] fix: typescript issue Signed-off-by: dominictb --- src/libs/actions/IOU.ts | 59 +++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 6b1b3351b3ac..2d749392a226 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1,8 +1,3 @@ -import {format} from 'date-fns'; -import {fastMerge, Str} from 'expensify-common'; -import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; -import type {ValueOf} from 'type-fest'; import ReceiptGeneric from '@assets/images/receipt-generic.png'; import * as API from '@libs/API'; import type { @@ -26,14 +21,14 @@ import type { TrackExpenseParams, UpdateMoneyRequestParams, } from '@libs/API/parameters'; -import {WRITE_COMMANDS} from '@libs/API/types'; +import { WRITE_COMMANDS } from '@libs/API/types'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import DateUtils from '@libs/DateUtils'; import DistanceRequestUtils from '@libs/DistanceRequestUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; import * as FileUtils from '@libs/fileDownload/FileUtils'; import * as IOUUtils from '@libs/IOUUtils'; -import {toLocaleDigit} from '@libs/LocaleDigitUtils'; +import { toLocaleDigit } from '@libs/LocaleDigitUtils'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import * as Localize from '@libs/Localize'; import Navigation from '@libs/Navigation/Navigation'; @@ -42,24 +37,29 @@ import Permissions from '@libs/Permissions'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import type {OptimisticChatReport, OptimisticCreatedReportAction, OptimisticIOUReportAction, TransactionDetails} from '@libs/ReportUtils'; +import type { OptimisticChatReport, OptimisticCreatedReportAction, OptimisticIOUReportAction, TransactionDetails } from '@libs/ReportUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; -import type {IOUAction, IOUType} from '@src/CONST'; +import type { IOUAction, IOUType } from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; -import type {Participant, Split} from '@src/types/onyx/IOU'; -import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; -import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import type { Participant, Split } from '@src/types/onyx/IOU'; +import type { ErrorFields, Errors } from '@src/types/onyx/OnyxCommon'; +import type { PaymentMethodType } from '@src/types/onyx/OriginalMessage'; import type ReportAction from '@src/types/onyx/ReportAction'; -import type {OnyxData} from '@src/types/onyx/Request'; -import type {Comment, Receipt, ReceiptSource, Routes, SplitShares, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction'; +import type { OnyxData } from '@src/types/onyx/Request'; +import type { Comment, Receipt, ReceiptSource, Routes, SplitShares, TransactionChanges, WaypointCollection } from '@src/types/onyx/Transaction'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import { isEmptyObject } from '@src/types/utils/EmptyObject'; +import { format } from 'date-fns'; +import { fastMerge, Str } from 'expensify-common'; +import type { OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate } from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import type { ValueOf } from 'type-fest'; import * as CachedPDFPaths from './CachedPDFPaths'; import * as Category from './Policy/Category'; import * as Policy from './Policy/Policy'; @@ -5321,7 +5321,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT }, errors: null, }, - } as NullishDeep; + } as unknown as OnyxTypes.ReportActions; const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1', updatedReportAction); const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1', updatedReportAction).lastMessageText; @@ -7209,31 +7209,37 @@ function getIOURequestPolicyID(transaction: OnyxEntry, re } export { + adjustRemainingSplitShares, approveMoneyRequest, canApproveIOU, - canIOUBePaid, cancelPayment, + canIOUBePaid, + cleanUpMoneyRequest, clearMoneyRequest, completeSplitBill, createDistanceRequest, createDraftTransaction, - cleanUpMoneyRequest, deleteMoneyRequest, deleteTrackExpense, detachReceipt, + dismissHoldUseExplanation, editMoneyRequest, + getIOURequestPolicyID, initMoneyRequest, navigateToStartStepIfScanFileCannotBeRead, - payMoneyRequest, payInvoice, + payMoneyRequest, putOnHold, replaceReceipt, requestMoney, + resetSplitShares, savePreferredPaymentMethod, + sendInvoice, sendMoneyElsewhere, sendMoneyWithWallet, setCustomUnitRateID, setDraftSplitTransaction, + setIndividualShare, setMoneyRequestAmount, setMoneyRequestBillable, setMoneyRequestCategory, @@ -7245,16 +7251,11 @@ export { setMoneyRequestParticipantsFromReport, setMoneyRequestPendingFields, setMoneyRequestReceipt, - setSplitPayer, setMoneyRequestTag, setMoneyRequestTaxAmount, setMoneyRequestTaxRate, - dismissHoldUseExplanation, - updateMoneyRequestDate, + setSplitPayer, setSplitShares, - resetSplitShares, - setIndividualShare, - adjustRemainingSplitShares, splitBill, splitBillAndOpenReport, startMoneyRequest, @@ -7266,13 +7267,13 @@ export { updateMoneyRequestAmountAndCurrency, updateMoneyRequestBillable, updateMoneyRequestCategory, + updateMoneyRequestDate, updateMoneyRequestDescription, updateMoneyRequestDistance, updateMoneyRequestMerchant, updateMoneyRequestTag, updateMoneyRequestTaxAmount, - updateMoneyRequestTaxRate, - sendInvoice, - getIOURequestPolicyID, + updateMoneyRequestTaxRate }; -export type {GPSPoint as GpsPoint, IOURequestType}; +export type { GPSPoint as GpsPoint, IOURequestType }; + From 2ea8354452ee4a922213afead5deb44221ca2a96 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 9 Jul 2024 14:20:55 +0200 Subject: [PATCH 011/119] reset suggestions --- src/components/AutoCompleteSuggestions/types.ts | 3 +++ src/components/EmojiSuggestions.tsx | 5 +++++ src/components/MentionSuggestions.tsx | 14 +++++++++++++- .../report/ReportActionCompose/SuggestionEmoji.tsx | 1 + .../ReportActionCompose/SuggestionMention.tsx | 1 + 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/components/AutoCompleteSuggestions/types.ts b/src/components/AutoCompleteSuggestions/types.ts index 48bb6b713032..b60407e70beb 100644 --- a/src/components/AutoCompleteSuggestions/types.ts +++ b/src/components/AutoCompleteSuggestions/types.ts @@ -42,6 +42,9 @@ type AutoCompleteSuggestionsProps = { /** Measures the parent container's position and dimensions. Also add a cursor coordinates */ measureParentContainerAndReportCursor?: (props: MeasureParentContainerAndCursorCallback) => void; + + /** Reset the emoji suggestions */ + resetSuggestions: () => void; }; export type {AutoCompleteSuggestionsProps, RenderSuggestionMenuItemProps, MeasureParentContainerAndCursorCallback, MeasureParentContainerAndCursor}; diff --git a/src/components/EmojiSuggestions.tsx b/src/components/EmojiSuggestions.tsx index 3781507b544c..a2996482be6a 100644 --- a/src/components/EmojiSuggestions.tsx +++ b/src/components/EmojiSuggestions.tsx @@ -34,6 +34,9 @@ type EmojiSuggestionsProps = { /** Measures the parent container's position and dimensions. Also add cursor coordinates */ measureParentContainerAndReportCursor: (callback: MeasureParentContainerAndCursorCallback) => void; + + /** Reset the emoji suggestions */ + resetSuggestions: () => void; }; /** @@ -49,6 +52,7 @@ function EmojiSuggestions({ preferredSkinToneIndex, highlightedEmojiIndex = 0, measureParentContainerAndReportCursor = () => {}, + resetSuggestions, }: EmojiSuggestionsProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -93,6 +97,7 @@ function EmojiSuggestions({ isSuggestionPickerLarge={isEmojiPickerLarge} accessibilityLabelExtractor={keyExtractor} measureParentContainerAndReportCursor={measureParentContainerAndReportCursor} + resetSuggestions={resetSuggestions} /> ); } diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index 1142a90c87d1..bdc19316d491 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -55,6 +55,9 @@ type MentionSuggestionsProps = { /** Measures the parent container's position and dimensions. Also add cursor coordinates */ measureParentContainerAndReportCursor: (callback: MeasureParentContainerAndCursorCallback) => void; + + /** Reset the emoji suggestions */ + resetSuggestions: () => void; }; /** @@ -62,7 +65,15 @@ type MentionSuggestionsProps = { */ const keyExtractor = (item: Mention) => item.alternateText; -function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSelect, isMentionPickerLarge, measureParentContainerAndReportCursor = () => {}}: MentionSuggestionsProps) { +function MentionSuggestions({ + prefix, + mentions, + highlightedMentionIndex = 0, + onSelect, + isMentionPickerLarge, + measureParentContainerAndReportCursor = () => {}, + resetSuggestions, +}: MentionSuggestionsProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -149,6 +160,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe isSuggestionPickerLarge={isMentionPickerLarge} accessibilityLabelExtractor={keyExtractor} measureParentContainerAndReportCursor={measureParentContainerAndReportCursor} + resetSuggestions={resetSuggestions} /> ); } diff --git a/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx b/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx index bf71937a9e9a..695b931af600 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx +++ b/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx @@ -222,6 +222,7 @@ function SuggestionEmoji( preferredSkinToneIndex={preferredSkinTone} isEmojiPickerLarge={!!isAutoSuggestionPickerLarge} measureParentContainerAndReportCursor={measureParentContainerAndReportCursor} + resetSuggestions={resetSuggestions} /> ); } diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx b/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx index a103e8271044..eca6202c8bff 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx @@ -435,6 +435,7 @@ function SuggestionMention( onSelect={insertSelectedMention} isMentionPickerLarge={!!isAutoSuggestionPickerLarge} measureParentContainerAndReportCursor={measureParentContainerAndReportCursor} + resetSuggestions={resetSuggestions} /> ); } From d00604b0fc3568e5046ae70941e40a7909aa1553 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 9 Jul 2024 15:56:25 +0200 Subject: [PATCH 012/119] TransparentOverlay --- .../TransparentOverlay/index.tsx | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx diff --git a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx new file mode 100644 index 000000000000..cc684b760c40 --- /dev/null +++ b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx @@ -0,0 +1,40 @@ +import React, {useCallback} from 'react'; +import {View} from 'react-native'; +import type {GestureResponderEvent} from 'react-native'; +import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; +import useThemeStyles from '@hooks/useThemeStyles'; +import CONST from '@src/CONST'; + +type TransparentOverlayProps = { + resetSuggestions: () => void; +}; +type OnPressHandler = (event: GestureResponderEvent) => void; + +function TransparentOverlay({resetSuggestions}: TransparentOverlayProps) { + const styles = useThemeStyles(); + + const onResetSuggestions: OnPressHandler = useCallback( + (event: GestureResponderEvent) => { + event?.preventDefault(); + resetSuggestions(); + }, + [resetSuggestions], + ); + return ( + { + e?.preventDefault(); + }} + style={styles.fullScreen} + > + + + ); +} + +export default TransparentOverlay; From f01a12b87ca61fff64f865dac0f4a2de0db9914b Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 9 Jul 2024 15:56:46 +0200 Subject: [PATCH 013/119] use TransparentOverlay WEB --- .../AutoCompleteSuggestionsPortal/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.tsx b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.tsx index 2d1d533c2859..1d56ab2cced4 100644 --- a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.tsx +++ b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.tsx @@ -5,6 +5,7 @@ import {View} from 'react-native'; import BaseAutoCompleteSuggestions from '@components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions'; import useStyleUtils from '@hooks/useStyleUtils'; import getBottomSuggestionPadding from './getBottomSuggestionPadding'; +import TransparentOverlay from './TransparentOverlay'; import type {AutoCompleteSuggestionsPortalProps} from './types'; /** @@ -31,7 +32,10 @@ function AutoCompleteSuggestionsPortal({left = 0, width = 0, bottom !!width && bodyElement && ReactDOM.createPortal( - {componentToRender}, + <> + + {componentToRender} + , bodyElement, ) ); From cb2e97e504f762fb412483c041cd29b81fb987b8 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 9 Jul 2024 15:57:04 +0200 Subject: [PATCH 014/119] use TransparentOverlay on mobile --- .../AutoCompleteSuggestionsPortal/index.native.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.native.tsx b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.native.tsx index 9848d77e479e..d30d97044fc0 100644 --- a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.native.tsx +++ b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.native.tsx @@ -4,6 +4,7 @@ import {View} from 'react-native'; import BaseAutoCompleteSuggestions from '@components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions'; import useStyleUtils from '@hooks/useStyleUtils'; import getBottomSuggestionPadding from './getBottomSuggestionPadding'; +import TransparentOverlay from './TransparentOverlay'; import type {AutoCompleteSuggestionsPortalProps} from './types'; function AutoCompleteSuggestionsPortal({left = 0, width = 0, bottom = 0, ...props}: AutoCompleteSuggestionsPortalProps) { @@ -16,6 +17,7 @@ function AutoCompleteSuggestionsPortal({left = 0, width = 0, bottom return ( + {/* eslint-disable-next-line react/jsx-props-no-spreading */} From 3022ba6c4a70ca8051100f38d2e4f24f3ff678f5 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 9 Jul 2024 15:57:21 +0200 Subject: [PATCH 015/119] update AutoCompleteSuggestions --- .../AutoCompleteSuggestions/index.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/components/AutoCompleteSuggestions/index.tsx b/src/components/AutoCompleteSuggestions/index.tsx index f1c7fb505921..6de2aaae1bf6 100644 --- a/src/components/AutoCompleteSuggestions/index.tsx +++ b/src/components/AutoCompleteSuggestions/index.tsx @@ -34,6 +34,13 @@ function isEnoughSpaceAbove({y, cursorCoordinates, scrollValue, contentHeight, t return y + (cursorCoordinates.y - scrollValue) > contentHeight + topInset + CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_BOX_MAX_SAFE_DISTANCE; } +const initialContainerState = { + width: 0, + left: 0, + bottom: 0, + cursorCoordinates: {x: 0, y: 0}, +}; + /** * On the mobile-web platform, when long-pressing on auto-complete suggestions, * we need to prevent focus shifting to avoid blurring the main input (which makes the suggestions picker close and fires the onSelect callback). @@ -48,12 +55,7 @@ function AutoCompleteSuggestions({measureParentContainerAndReportCu const prevLeftValue = React.useRef(0); const {windowHeight, windowWidth, isSmallScreenWidth} = useWindowDimensions(); const [suggestionHeight, setSuggestionHeight] = React.useState(0); - const [containerState, setContainerState] = React.useState({ - width: 0, - left: 0, - bottom: 0, - cursorCoordinates: {x: 0, y: 0}, - }); + const [containerState, setContainerState] = React.useState(initialContainerState); const StyleUtils = useStyleUtils(); const insets = useSafeAreaInsets(); const {keyboardHeight} = useKeyboardState(); @@ -80,6 +82,11 @@ function AutoCompleteSuggestions({measureParentContainerAndReportCu return; } + if (!windowHeight || !windowWidth || !suggestionsLength) { + setContainerState(initialContainerState); + return; + } + measureParentContainerAndReportCursor(({x, y, width, scrollValue, cursorCoordinates}: MeasureParentContainerAndCursor) => { const xCoordinatesOfCursor = x + cursorCoordinates.x; const leftValueForBigScreen = From 28eb075f20f9f6e198d0755c32d331774e371cc4 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Wed, 10 Jul 2024 10:13:40 +0200 Subject: [PATCH 016/119] onPointerDown type --- .../TransparentOverlay/index.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx index cc684b760c40..ae320c54da43 100644 --- a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx +++ b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx @@ -8,21 +8,23 @@ import CONST from '@src/CONST'; type TransparentOverlayProps = { resetSuggestions: () => void; }; + type OnPressHandler = (event: GestureResponderEvent) => void; function TransparentOverlay({resetSuggestions}: TransparentOverlayProps) { const styles = useThemeStyles(); - const onResetSuggestions: OnPressHandler = useCallback( - (event: GestureResponderEvent) => { + const onResetSuggestions = useCallback( + (event) => { event?.preventDefault(); resetSuggestions(); }, [resetSuggestions], ); + return ( { + onPointerDown={(e) => { e?.preventDefault(); }} style={styles.fullScreen} From 7471681bb21c3ddc80183e03acb47a223d50f09a Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Wed, 10 Jul 2024 11:01:14 +0200 Subject: [PATCH 017/119] lint --- .../TransparentOverlay/index.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx index ae320c54da43..1fcb9a432c5b 100644 --- a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx +++ b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx @@ -1,6 +1,7 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; -import type {GestureResponderEvent} from 'react-native'; +import type {PointerEvent} from 'react-native'; +import type PressableProps from '@components/Pressable/GenericPressable/types'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; @@ -9,12 +10,12 @@ type TransparentOverlayProps = { resetSuggestions: () => void; }; -type OnPressHandler = (event: GestureResponderEvent) => void; +type OnPressHandler = PressableProps['onPress']; function TransparentOverlay({resetSuggestions}: TransparentOverlayProps) { const styles = useThemeStyles(); - const onResetSuggestions = useCallback( + const onResetSuggestions = useCallback>( (event) => { event?.preventDefault(); resetSuggestions(); @@ -22,11 +23,13 @@ function TransparentOverlay({resetSuggestions}: TransparentOverlayProps) { [resetSuggestions], ); + const handlePointerDown = useCallback((e: PointerEvent) => { + e?.preventDefault(); + }, []); + return ( { - e?.preventDefault(); - }} + onPointerDown={handlePointerDown} style={styles.fullScreen} > Date: Wed, 10 Jul 2024 17:26:33 +0700 Subject: [PATCH 018/119] fix: resolve typescript issues Signed-off-by: dominictb --- src/libs/actions/IOU.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 3b7c6e10d4b4..a2621bb6d160 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5308,6 +5308,7 @@ function updateMoneyRequestAmountAndCurrency({ */ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { // STEP 1: Get all collections we're updating + const allReports = ReportConnection.getAllReports(); const iouReportID = ReportActionsUtils.isMoneyRequestAction(reportAction) ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUReportID : '-1'; const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`] ?? null; const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReport?.chatReportID}`]; From 21eafea9e61f81ae96a85970df95b5ee27e5160f Mon Sep 17 00:00:00 2001 From: dominictb Date: Wed, 10 Jul 2024 17:53:37 +0700 Subject: [PATCH 019/119] fix: prettier Signed-off-by: dominictb --- src/libs/actions/IOU.ts | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index a2621bb6d160..262688d6889c 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1,3 +1,8 @@ +import {format} from 'date-fns'; +import {fastMerge, Str} from 'expensify-common'; +import type {OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import type {ValueOf} from 'type-fest'; import ReceiptGeneric from '@assets/images/receipt-generic.png'; import * as API from '@libs/API'; import type { @@ -22,14 +27,14 @@ import type { UnapproveExpenseReportParams, UpdateMoneyRequestParams, } from '@libs/API/parameters'; -import { WRITE_COMMANDS } from '@libs/API/types'; +import {WRITE_COMMANDS} from '@libs/API/types'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import DateUtils from '@libs/DateUtils'; import DistanceRequestUtils from '@libs/DistanceRequestUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; import * as FileUtils from '@libs/fileDownload/FileUtils'; import * as IOUUtils from '@libs/IOUUtils'; -import { toLocaleDigit } from '@libs/LocaleDigitUtils'; +import {toLocaleDigit} from '@libs/LocaleDigitUtils'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import * as Localize from '@libs/Localize'; import Navigation from '@libs/Navigation/Navigation'; @@ -44,24 +49,19 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; -import type { IOUAction, IOUType } from '@src/CONST'; +import type {IOUAction, IOUType} from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; -import type { Participant, Split } from '@src/types/onyx/IOU'; -import type { ErrorFields, Errors } from '@src/types/onyx/OnyxCommon'; -import type { PaymentMethodType } from '@src/types/onyx/OriginalMessage'; +import type {Participant, Split} from '@src/types/onyx/IOU'; +import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; +import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type ReportAction from '@src/types/onyx/ReportAction'; -import type { OnyxData } from '@src/types/onyx/Request'; -import type { Comment, Receipt, ReceiptSource, Routes, SplitShares, TransactionChanges, WaypointCollection } from '@src/types/onyx/Transaction'; +import type {OnyxData} from '@src/types/onyx/Request'; +import type {Comment, Receipt, ReceiptSource, Routes, SplitShares, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import { isEmptyObject } from '@src/types/utils/EmptyObject'; -import { format } from 'date-fns'; -import { fastMerge, Str } from 'expensify-common'; -import type { OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate } from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; -import type { ValueOf } from 'type-fest'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import * as CachedPDFPaths from './CachedPDFPaths'; import * as Category from './Policy/Category'; import * as Policy from './Policy/Policy'; @@ -7389,7 +7389,6 @@ export { updateMoneyRequestMerchant, updateMoneyRequestTag, updateMoneyRequestTaxAmount, - updateMoneyRequestTaxRate + updateMoneyRequestTaxRate, }; -export type { GPSPoint as GpsPoint, IOURequestType }; - +export type {GPSPoint as GpsPoint, IOURequestType}; From 4d24b64839e9b5cace1edc2de78f61e09ff2dc33 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Thu, 11 Jul 2024 14:15:12 +0200 Subject: [PATCH 020/119] clean after merge --- src/pages/home/report/ReportActionItemMessageEdit.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index 40e9a4c6bf41..1148934a1135 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -196,7 +196,7 @@ function ReportActionItemMessageEdit( } // Show the main composer when the focused message is deleted from another client - // to prevent the main composer stays hidden until we swtich to another chat. + // to prevent the main composer stays hidden until we switch to another chat. setShouldShowComposeInputKeyboardAware(true); }; }, @@ -403,8 +403,7 @@ function ReportActionItemMessageEdit( } containerRef.current.measureInWindow(callback); }, - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - [isFocused], + [], ); const measureParentContainerAndReportCursor = useCallback( @@ -428,10 +427,8 @@ function ReportActionItemMessageEdit( useEffect(() => { // We use the tag to store the native ID of the text input. Later, we use it in onSelectionChange to pick up the proper text input data. - // eslint-disable-next-line react-compiler/react-compiler tag.value = findNodeHandle(textInputRef.current) ?? -1; - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, []); + }, [tag]); useFocusedInputHandler( { onSelectionChange: (event) => { From 7bf9646e143f31a215cd9935d2beb92d20a8cad3 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Thu, 11 Jul 2024 14:28:26 +0200 Subject: [PATCH 021/119] bring back react-compiler lint --- src/pages/home/report/ReportActionItemMessageEdit.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index 1148934a1135..ad142c08a26a 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -427,6 +427,7 @@ function ReportActionItemMessageEdit( useEffect(() => { // We use the tag to store the native ID of the text input. Later, we use it in onSelectionChange to pick up the proper text input data. + // eslint-disable-next-line react-compiler/react-compiler tag.value = findNodeHandle(textInputRef.current) ?? -1; }, [tag]); useFocusedInputHandler( From 36388523234577a53accc0b00653e90868b94f1e Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Thu, 11 Jul 2024 14:40:59 +0200 Subject: [PATCH 022/119] lint --- .../home/report/ReportActionItemMessageEdit.tsx | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index ad142c08a26a..fbb8c7252164 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -396,15 +396,12 @@ function ReportActionItemMessageEdit( [deleteDraft, hideSuggestionMenu, isKeyboardShown, isSmallScreenWidth, publishDraft], ); - const measureContainer = useCallback( - (callback: MeasureInWindowOnSuccessCallback) => { - if (!containerRef.current) { - return; - } - containerRef.current.measureInWindow(callback); - }, - [], - ); + const measureContainer = useCallback((callback: MeasureInWindowOnSuccessCallback) => { + if (!containerRef.current) { + return; + } + containerRef.current.measureInWindow(callback); + }, []); const measureParentContainerAndReportCursor = useCallback( (callback: MeasureParentContainerAndCursorCallback) => { From 3f66c546cf47c7ce1caa01e6f14bd11ff51b35a9 Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 11 Jul 2024 20:31:28 +0700 Subject: [PATCH 023/119] fix Deleted task is shown briefly and then disappears from conversation page --- src/libs/actions/Task.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 0a7244bde1e5..5df361a973c2 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -929,7 +929,7 @@ function deleteTask(report: OnyxEntry) { // If the task report is the last visible action in the parent report, we should navigate back to the parent report const shouldDeleteTaskReport = !ReportActionsUtils.doesReportHaveVisibleActions(report.reportID ?? '-1'); const optimisticReportAction: Partial = { - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + pendingAction: shouldDeleteTaskReport ? CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE : CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, previousMessage: parentReportAction?.message, message: [ { From 4bb68935f4df0bdf894a00b76803d3cdf21cf198 Mon Sep 17 00:00:00 2001 From: James Dean Date: Thu, 11 Jul 2024 07:25:16 -0700 Subject: [PATCH 024/119] Update en.ts --- src/languages/en.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 348b0d36b5fe..7743147ddc11 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2219,7 +2219,7 @@ export default { }, }, noAccountsFound: 'No accounts found', - noAccountsFoundDescription: 'Add the account in Xero and sync the connection again.', + noAccountsFoundDescription: 'Please add the account in Xero and sync the connection again.', }, sageIntacct: { preferredExporter: 'Preferred exporter', @@ -2243,39 +2243,39 @@ export default { }, }, reimbursableExpenses: { - label: 'Export reimbursable expenses as', - description: 'Reimbursable expenses will export as expense reports to Sage Intacct. Bills will export as vendor bills.', + label: 'Export out-of-pocket expenses as', + description: 'Set how out-of-pocket expenses export to Sage Intacct.', values: { - [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT]: 'Expense reports', - [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bills', + [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT]: 'Expense report', + [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bill', }, }, nonReimbursableExpenses: { - label: 'Export non-reimbursable expenses as', + label: 'Export company cards as', description: - 'Non-reimbursable expenses will export to Sage Intacct as either credit card transactions or vendor bills and credit the account selected below. Learn more about assigning cards to individual accounts.', + 'Set how company card purchases export to Sage Intacct.', values: { - [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE]: 'Credit card transactions', - [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bills', + [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE]: 'Credit card', + [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bill', }, }, creditCardAccount: 'Credit card account', defaultVendor: 'Default vendor', defaultVendorDescription: (isReimbursable: boolean): string => `Set a default vendor that will apply to ${isReimbursable ? '' : 'non-'}reimbursable expenses that don't have a matching vendor in Sage Intacct.`, - exportDescription: 'Configure how data in Expensify gets exported to Sage Intacct.', + exportDescription: 'Configure how Expensify data exports to Sage Intacct.', exportPreferredExporterNote: 'The preferred exporter can be any workspace admin, but must also be a Domain Admin if you set different export accounts for individual company cards in Domain Settings.', exportPreferredExporterSubNote: 'Once set, the preferred exporter will see reports for export in their account.', noAccountsFound: 'No accounts found', - noAccountsFoundDescription: `Add the account in Sage Intacct and sync the connection again.`, + noAccountsFoundDescription: `Please add the account in Sage Intacct and sync the connection again.`, autoSync: 'Auto-sync', - autoSyncDescription: 'Sync Sage Intacct and Expensify automatically, every day.', + autoSyncDescription: 'Expensify will automatically sync with Sage Intacct every day.', inviteEmployees: 'Invite employees', inviteEmployeesDescription: 'Import Sage Intacct employee records and invite employees to this workspace. Your approval workflow will default to manager approval and can be furthered configured on the Members page.', syncReimbursedReports: 'Sync reimbursed reports', - syncReimbursedReportsDescription: 'When a report is reimbursed using Expensify ACH, the corresponding puchase bill will be created in the Sage Intacct account below.', + syncReimbursedReportsDescription: 'Any time a report is paid using Expensify ACH, the corresponding bill payment will be created in the Sage Intacct account below.', paymentAccount: 'Sage Intacct payment account', }, netsuite: { From 6d6bcd21ca9fb30d8fa44059b160014cba717668 Mon Sep 17 00:00:00 2001 From: James Dean Date: Thu, 11 Jul 2024 07:45:58 -0700 Subject: [PATCH 025/119] Update en.ts --- src/languages/en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 7743147ddc11..73183d667bff 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2172,7 +2172,7 @@ export default { exportDescription: 'Configure how Expensify data exports to Xero.', exportCompanyCard: 'Export company card expenses as', purchaseBill: 'Purchase bill', - exportDeepDiveCompanyCard: 'Each exported expense posts as a bank transaction to the Xero bank account below, and transaction dates will match the dates on your bank statement.', + exportDeepDiveCompanyCard: 'Exported expenses will post as bank transactions to the Xero bank account below, and transaction dates will match the dates on your bank statement.', bankTransactions: 'Bank transactions', xeroBankAccount: 'Xero bank account', xeroBankAccountDescription: 'Choose where expenses will post as bank transactions.', From 455a73d4d7b61d432aceb0cac7111ee25e1d6374 Mon Sep 17 00:00:00 2001 From: James Dean Date: Thu, 11 Jul 2024 07:49:42 -0700 Subject: [PATCH 026/119] Update en.ts --- src/languages/en.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 73183d667bff..4d9d1c30c69f 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2454,7 +2454,7 @@ export default { }, import: { expenseCategories: 'Expense categories', - expenseCategoriesDescription: 'NetSuite expense categories import into Expensify as categories.', + expenseCategoriesDescription: 'Your NetSuite expense categories will import into Expensify as categories.', crossSubsidiaryCustomers: 'Cross-subsidiary customer/projects', importFields: { departments: { @@ -2590,7 +2590,7 @@ export default { toggleImportTitleFirstPart: 'Choose how to handle Sage Intacct ', toggleImportTitleSecondPart: ' in Expensify.', expenseTypes: 'Expense types', - expenseTypesDescription: 'Sage Intacct expense types import into Expensify as categories.', + expenseTypesDescription: 'Your Sage Intacct expense types will import into Expensify as categories.', importTaxDescription: 'Import purchase tax rate from Sage Intacct.', userDefinedDimensions: 'User-defined dimensions', addUserDefinedDimension: 'Add user-defined dimension', From f1eaa5aada5f86f4ed3fdd7aba33bc8b417c1731 Mon Sep 17 00:00:00 2001 From: James Dean Date: Thu, 11 Jul 2024 08:00:20 -0700 Subject: [PATCH 027/119] Update en.ts --- src/languages/en.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 4d9d1c30c69f..e1358593ec3a 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2246,8 +2246,8 @@ export default { label: 'Export out-of-pocket expenses as', description: 'Set how out-of-pocket expenses export to Sage Intacct.', values: { - [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT]: 'Expense report', - [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bill', + [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT]: 'Expense reports', + [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bills', }, }, nonReimbursableExpenses: { @@ -2255,8 +2255,8 @@ export default { description: 'Set how company card purchases export to Sage Intacct.', values: { - [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE]: 'Credit card', - [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bill', + [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE]: 'Credit cards', + [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bills', }, }, creditCardAccount: 'Credit card account', From a1b42d87c1ed782fe3b17d3efe9635914f9deb38 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 12 Jul 2024 11:42:38 +0700 Subject: [PATCH 028/119] fix billable on scan split bill --- src/libs/API/parameters/CompleteSplitBillParams.ts | 1 + src/libs/actions/IOU.ts | 2 ++ src/pages/iou/SplitBillDetailsPage.tsx | 3 +++ 3 files changed, 6 insertions(+) diff --git a/src/libs/API/parameters/CompleteSplitBillParams.ts b/src/libs/API/parameters/CompleteSplitBillParams.ts index a1731d32fcc4..67ca011b70d9 100644 --- a/src/libs/API/parameters/CompleteSplitBillParams.ts +++ b/src/libs/API/parameters/CompleteSplitBillParams.ts @@ -10,6 +10,7 @@ type CompleteSplitBillParams = { splits: string; taxCode?: string; taxAmount?: number; + billable?: boolean; }; export default CompleteSplitBillParams; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index d72e7d5c83ba..1e1fa2394fd4 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -4961,6 +4961,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA tag: transactionTag, taxCode: transactionTaxCode, taxAmount: transactionTaxAmount, + billable: transactionBillable, } = ReportUtils.getTransactionDetails(updatedTransaction) ?? {}; const parameters: CompleteSplitBillParams = { @@ -4975,6 +4976,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA splits: JSON.stringify(splits), taxCode: transactionTaxCode, taxAmount: transactionTaxAmount, + billable: transactionBillable, }; API.write(WRITE_COMMANDS.COMPLETE_SPLIT_BILL, parameters, {optimisticData, successData, failureData}); diff --git a/src/pages/iou/SplitBillDetailsPage.tsx b/src/pages/iou/SplitBillDetailsPage.tsx index d31c67624bd2..24bac1a0dde8 100644 --- a/src/pages/iou/SplitBillDetailsPage.tsx +++ b/src/pages/iou/SplitBillDetailsPage.tsx @@ -146,6 +146,9 @@ function SplitBillDetailsPage({personalDetails, report, route, reportActions, tr isPolicyExpenseChat={ReportUtils.isPolicyExpenseChat(report)} policyID={ReportUtils.isPolicyExpenseChat(report) ? report?.policyID : undefined} action={isEditingSplitBill ? CONST.IOU.ACTION.EDIT : CONST.IOU.ACTION.CREATE} + onToggleBillable={(billable) => { + IOU.setDraftSplitTransaction(transaction?.transactionID ?? '-1', {billable}); + }} /> )} From 3730797ef95fa21d21bd4600bcc0ca07a29bd21f Mon Sep 17 00:00:00 2001 From: dominictb Date: Fri, 12 Jul 2024 16:36:18 +0700 Subject: [PATCH 029/119] fix: update comments and clean up implementation Signed-off-by: dominictb --- .../ReportActionItem/MoneyRequestView.tsx | 4 +- src/libs/ReportActionsUtils.ts | 100 +++++++++--------- src/libs/actions/IOU.ts | 76 ++++++------- 3 files changed, 88 insertions(+), 92 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 3a3f7736fb72..2a2f565dfdb4 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -412,8 +412,8 @@ function MoneyRequestView({ if (!transaction?.transactionID) { return; } - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - if ((!!report?.errorFields?.createChat || !!report.isOptimisticReport) && parentReportAction) { + const isCreateChatErrored = !!report?.errorFields?.createChat; + if ((isCreateChatErrored || !!report.isOptimisticReport) && parentReportAction) { const urlToNavigateBack = IOU.cleanUpMoneyRequest(transaction.transactionID, parentReportAction, true); Navigation.goBack(urlToNavigateBack); return; diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 3f8acd0e06fe..e96c59592a37 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1,7 +1,7 @@ import {fastMerge} from 'expensify-common'; import _ from 'lodash'; import lodashFindLast from 'lodash/findLast'; -import type {OnyxCollection, OnyxCollectionInputValue, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; +import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; @@ -10,8 +10,8 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {OnyxInputOrEntry} from '@src/types/onyx'; import type {JoinWorkspaceResolution} from '@src/types/onyx/OriginalMessage'; import type Report from '@src/types/onyx/Report'; -import type {Message, OldDotReportAction, OriginalMessage, ReportActions} from '@src/types/onyx/ReportAction'; import type ReportAction from '@src/types/onyx/ReportAction'; +import type {Message, OldDotReportAction, OriginalMessage, ReportActions} from '@src/types/onyx/ReportAction'; import type ReportActionName from '@src/types/onyx/ReportActionName'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import DateUtils from './DateUtils'; @@ -663,10 +663,12 @@ function replaceBaseURLInPolicyChangeLogAction(reportAction: ReportAction): Repo return updatedReportAction; } -function getLastVisibleAction(reportID: string, actionsToMerge: OnyxCollection | OnyxCollectionInputValue = {}): OnyxEntry { +function getLastVisibleAction(reportID: string, actionsToMerge: Record | null> = {}): OnyxEntry { let reportActions: Array = []; if (!_.isEmpty(actionsToMerge)) { - reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge ?? {}, true)); + reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge ?? {}, true)) as Array< + ReportAction | null | undefined + >; } else { reportActions = Object.values(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}); } @@ -680,7 +682,7 @@ function getLastVisibleAction(reportID: string, actionsToMerge: OnyxCollection | OnyxCollectionInputValue = {}, + actionsToMerge: Record | null> = {}, reportAction: OnyxInputOrEntry | undefined = undefined, ): LastVisibleMessage { const lastVisibleAction = reportAction ?? getLastVisibleAction(reportID, actionsToMerge); @@ -1397,90 +1399,90 @@ function getTrackExpenseActionableWhisper(transactionID: string, chatReportID: s } export { + doesReportHaveVisibleActions, extractLinksFromMessageHtml, + getActionableMentionWhisperMessage, + getAllReportActions, + getCombinedReportActions, getDismissedViolationMessageText, - getOneTransactionThreadReportID, + getFilteredForOneTransactionView, + getFirstVisibleReportActionID, + getIOUActionForReportID, getIOUReportIDFromReportActionPreview, getLastClosedReportAction, getLastVisibleAction, getLastVisibleMessage, getLatestReportActionFromOnyxData, getLinkedTransactionID, + getMemberChangeMessageFragment, + getMemberChangeMessagePlainText, + getMessageOfOldDotReportAction, getMostRecentIOURequestActionID, getMostRecentReportActionLastModified, getNumberOfMoneyRequests, + getOneTransactionThreadReportID, + getOriginalMessage, getParentReportAction, getReportAction, + getReportActionHtml, + getReportActionMessage, getReportActionMessageText, - getWhisperedTo, - isApprovedOrSubmittedReportAction, + getReportActionText, getReportPreviewAction, getSortedReportActions, - getCombinedReportActions, getSortedReportActionsForDisplay, + getTextFromHtml, + getTrackExpenseActionableWhisper, + getWhisperedTo, + hasRequestFromCurrentAccount, + isActionOfType, + isActionableJoinRequest, + isActionableJoinRequestPending, + isActionableMentionWhisper, + isActionableReportMentionWhisper, + isActionableTrackExpense, + isAddCommentAction, + isApprovedOrSubmittedReportAction, + isChronosOOOListAction, + isClosedAction, isConsecutiveActionMadeByPreviousActor, isCreatedAction, isCreatedTaskReportAction, + isCurrentActionUnread, isDeletedAction, isDeletedParentAction, + isLinkedTransactionHeld, + isMemberChangeAction, isMessageDeleted, isModifiedExpenseAction, isMoneyRequestAction, isNotifiableReportAction, + isOldDotReportAction, + isPayAction, isPendingRemove, - isReversedTransaction, + isPolicyChangeLogAction, + isReimbursementDeQueuedAction, + isReimbursementQueuedAction, + isRenamedAction, isReportActionAttachment, isReportActionDeprecated, isReportPreviewAction, + isResolvedActionTrackExpense, + isReversedTransaction, + isRoomChangeLogAction, isSentMoneyReportAction, isSplitBillAction, - isTrackExpenseAction, - isPayAction, isTaskAction, - doesReportHaveVisibleActions, isThreadParentMessage, + isTrackExpenseAction, isTransactionThread, + isTripPreview, isWhisperAction, isWhisperActionTargetedToOthers, - isReimbursementQueuedAction, - shouldReportActionBeVisible, shouldHideNewMarker, + shouldReportActionBeVisible, shouldReportActionBeVisibleAsLastAction, - hasRequestFromCurrentAccount, - getFirstVisibleReportActionID, - isMemberChangeAction, - getMemberChangeMessageFragment, - isOldDotReportAction, - getTrackExpenseActionableWhisper, - getMessageOfOldDotReportAction, - getMemberChangeMessagePlainText, - isReimbursementDeQueuedAction, - isActionableMentionWhisper, - isActionableReportMentionWhisper, - getActionableMentionWhisperMessage, - isCurrentActionUnread, - isActionableJoinRequest, - isActionableJoinRequestPending, - getReportActionText, - getReportActionHtml, - getReportActionMessage, - getOriginalMessage, - isActionOfType, - isActionableTrackExpense, - getAllReportActions, - isLinkedTransactionHeld, wasActionTakenByCurrentUser, - isResolvedActionTrackExpense, - isClosedAction, - isRenamedAction, - isRoomChangeLogAction, - isChronosOOOListAction, - isAddCommentAction, - isPolicyChangeLogAction, - getTextFromHtml, - isTripPreview, - getIOUActionForReportID, - getFilteredForOneTransactionView, }; export type {LastVisibleMessage}; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 262688d6889c..cf9c8c8a901b 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1,8 +1,3 @@ -import {format} from 'date-fns'; -import {fastMerge, Str} from 'expensify-common'; -import type {OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; -import type {ValueOf} from 'type-fest'; import ReceiptGeneric from '@assets/images/receipt-generic.png'; import * as API from '@libs/API'; import type { @@ -27,14 +22,14 @@ import type { UnapproveExpenseReportParams, UpdateMoneyRequestParams, } from '@libs/API/parameters'; -import {WRITE_COMMANDS} from '@libs/API/types'; +import { WRITE_COMMANDS } from '@libs/API/types'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import DateUtils from '@libs/DateUtils'; import DistanceRequestUtils from '@libs/DistanceRequestUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; import * as FileUtils from '@libs/fileDownload/FileUtils'; import * as IOUUtils from '@libs/IOUUtils'; -import {toLocaleDigit} from '@libs/LocaleDigitUtils'; +import { toLocaleDigit } from '@libs/LocaleDigitUtils'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import * as Localize from '@libs/Localize'; import Navigation from '@libs/Navigation/Navigation'; @@ -44,24 +39,29 @@ import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportConnection from '@libs/ReportConnection'; -import type {OptimisticChatReport, OptimisticCreatedReportAction, OptimisticIOUReportAction, TransactionDetails} from '@libs/ReportUtils'; +import type { OptimisticChatReport, OptimisticCreatedReportAction, OptimisticIOUReportAction, TransactionDetails } from '@libs/ReportUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; -import type {IOUAction, IOUType} from '@src/CONST'; +import type { IOUAction, IOUType } from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; -import type {Participant, Split} from '@src/types/onyx/IOU'; -import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; -import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import type { Participant, Split } from '@src/types/onyx/IOU'; +import type { ErrorFields, Errors } from '@src/types/onyx/OnyxCommon'; +import type { PaymentMethodType } from '@src/types/onyx/OriginalMessage'; import type ReportAction from '@src/types/onyx/ReportAction'; -import type {OnyxData} from '@src/types/onyx/Request'; -import type {Comment, Receipt, ReceiptSource, Routes, SplitShares, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction'; +import type { OnyxData } from '@src/types/onyx/Request'; +import type { Comment, Receipt, ReceiptSource, Routes, SplitShares, TransactionChanges, WaypointCollection } from '@src/types/onyx/Transaction'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import { isEmptyObject } from '@src/types/utils/EmptyObject'; +import { format } from 'date-fns'; +import { fastMerge, Str } from 'expensify-common'; +import type { NullishDeep, OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate } from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import type { ValueOf } from 'type-fest'; import * as CachedPDFPaths from './CachedPDFPaths'; import * as Category from './Policy/Category'; import * as Policy from './Policy/Policy'; @@ -5347,7 +5347,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT }, errors: null, }, - } as unknown as OnyxTypes.ReportActions; + } as Record>; const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1', updatedReportAction); const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1', updatedReportAction).lastMessageText; @@ -5400,20 +5400,19 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT updatedReportPreviewAction.childMoneyRequestCount = reportPreviewAction.childMoneyRequestCount - 1; } - let urlToNavigateBack: ReturnType | undefined; - - // STEP 5: Calculate what is the url that we will navigate user back + // STEP 5: Calculate the url that the user will be navigated back to // This depends on which page they are on and which resources were deleted + let reportIDToNavigateBack: string | undefined; if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { - // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. - urlToNavigateBack = ROUTES.REPORT_WITH_ID.getRoute(iouReport.reportID); + reportIDToNavigateBack = iouReport.reportID; } if (iouReport?.chatReportID && shouldDeleteIOUReport) { - // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. - urlToNavigateBack = ROUTES.REPORT_WITH_ID.getRoute(iouReport.chatReportID); + reportIDToNavigateBack = iouReport.chatReportID; } + const urlToNavigateBack = reportIDToNavigateBack ? ROUTES.REPORT_WITH_ID.getRoute(reportIDToNavigateBack) : undefined; + return { shouldDeleteTransactionThread, shouldDeleteIOUReport, @@ -5472,17 +5471,21 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo }, }, }, - { + ]; + + if (reportPreviewAction?.reportActionID) { + onyxUpdates.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, value: { - [reportPreviewAction?.reportActionID ?? '-1']: { + [reportPreviewAction.reportActionID]: { + ...updatedReportPreviewAction, pendingAction: null, errors: null, }, }, - }, - ]; + }); + } // added the operation to delete associated transaction violations if (Permissions.canUseViolations(betas)) { @@ -5521,13 +5524,6 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`, value: updatedIOUReport, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, - value: { - [reportPreviewAction?.reportActionID ?? '-1']: updatedReportPreviewAction, - }, - }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, @@ -7325,9 +7321,7 @@ function getIOURequestPolicyID(transaction: OnyxEntry, re export { adjustRemainingSplitShares, - approveMoneyRequest, - unapproveExpenseReport, - canApproveIOU, + approveMoneyRequest, canApproveIOU, cancelPayment, canIOUBePaid, cleanUpMoneyRequest, @@ -7377,8 +7371,7 @@ export { startMoneyRequest, startSplitBill, submitReport, - trackExpense, - unholdRequest, + trackExpense, unapproveExpenseReport, unholdRequest, updateDistanceRequestRate, updateMoneyRequestAmountAndCurrency, updateMoneyRequestBillable, @@ -7389,6 +7382,7 @@ export { updateMoneyRequestMerchant, updateMoneyRequestTag, updateMoneyRequestTaxAmount, - updateMoneyRequestTaxRate, + updateMoneyRequestTaxRate }; -export type {GPSPoint as GpsPoint, IOURequestType}; +export type { GPSPoint as GpsPoint, IOURequestType }; + From f0fee93bd3c394ce89e57fb280be14a820be3934 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 15 Jul 2024 15:23:04 +0700 Subject: [PATCH 030/119] fix: There are two error messages when trying to proceed without a limit --- src/pages/workspace/card/issueNew/LimitStep.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/workspace/card/issueNew/LimitStep.tsx b/src/pages/workspace/card/issueNew/LimitStep.tsx index cc65a987bd62..5f97db54ff21 100644 --- a/src/pages/workspace/card/issueNew/LimitStep.tsx +++ b/src/pages/workspace/card/issueNew/LimitStep.tsx @@ -81,6 +81,7 @@ function LimitStep() { formID={ONYXKEYS.FORMS.ISSUE_NEW_EXPENSIFY_CARD_FORM} // TODO: change the submitButtonText to 'common.confirm' when editing and navigate to ConfirmationStep submitButtonText={translate('common.next')} + shouldHideFixErrorsAlert onSubmit={submit} style={[styles.flex1]} submitButtonStyles={[styles.mh5, styles.mt0]} From 1e2723d8fe43029990a4ee57e349ae1bdc07da36 Mon Sep 17 00:00:00 2001 From: James Dean Date: Mon, 15 Jul 2024 12:05:50 -0700 Subject: [PATCH 031/119] Update es.ts --- src/languages/es.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index d1229c92f64c..0813faf391ba 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2284,19 +2284,19 @@ export default { }, }, reimbursableExpenses: { - label: 'Gastos reembolsables de exportación como', - description: 'Los gastos reembolsables se exportarán como informes de gastos a Sage Intacct. Las facturas se exportarán como facturas de proveedores.', + label: 'Exportar gastos de bolsillo como', + description: 'Establezca cómo se exportan los gastos de bolsillo a Sage Intacct.', values: { [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT]: 'Informes de gastos', [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Facturas de proveedores', }, }, nonReimbursableExpenses: { - label: 'Exportar gastos no reembolsables como', + label: 'Exportar tarjetas de empresa como', description: - 'Los gastos no reembolsables se exportarán a Sage Intacct como transacciones de tarjetas de crédito o facturas de proveedores y se abonarán en la cuenta seleccionada a continuación. Más información sobre la asignación de tarjetas a cuentas individuales.', + 'Establece cómo se exportan las compras con tarjeta de empresa a Sage Intacct.', values: { - [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE]: 'Transacciones con tarjeta de crédito', + [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE]: 'Tarjetas de crédito', [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Facturas de proveedores', }, }, From 6fc0ae28f220995605b0de4f9ebc83c43908de36 Mon Sep 17 00:00:00 2001 From: Puneet Lath Date: Mon, 15 Jul 2024 15:33:40 -0500 Subject: [PATCH 032/119] Assign optimistic onboarding tasks to user --- src/libs/actions/Report.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 1c863d485fbe..d591cf8a0006 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3221,7 +3221,7 @@ function completeOnboarding( : task.description; const currentTask = ReportUtils.buildOptimisticTaskReport( actorAccountID, - undefined, + currentUserAccountID, targetChatReportID, task.title, taskDescription, From 4b79f389683dbc31f72d4636836959ca7e3e39f1 Mon Sep 17 00:00:00 2001 From: dominictb Date: Tue, 16 Jul 2024 09:12:24 +0700 Subject: [PATCH 033/119] fix: revert "swapForTranslation" change Signed-off-by: dominictb --- src/components/LocaleContextProvider.tsx | 8 +------- .../ReportActionItem/MoneyRequestView.tsx | 18 +++++------------- src/languages/msgTranslationKeySwapMapping.ts | 8 -------- src/libs/Localize/index.ts | 17 +---------------- 4 files changed, 7 insertions(+), 44 deletions(-) delete mode 100644 src/languages/msgTranslationKeySwapMapping.ts diff --git a/src/components/LocaleContextProvider.tsx b/src/components/LocaleContextProvider.tsx index 24e27d1715b5..322a68ffe32a 100644 --- a/src/components/LocaleContextProvider.tsx +++ b/src/components/LocaleContextProvider.tsx @@ -30,8 +30,6 @@ type LocaleContextProps = { /** Returns translated string for given locale and phrase */ translate: (phraseKey: TKey, ...phraseParameters: Localize.PhraseParameters>) => string; - swapForTranslation: (message: string) => string; - /** Formats number formatted according to locale and options */ numberFormat: (number: number, options?: Intl.NumberFormatOptions) => string; @@ -71,7 +69,6 @@ const LocaleContext = createContext({ toLocaleDigit: () => '', toLocaleOrdinal: () => '', fromLocaleDigit: () => '', - swapForTranslation: () => '', preferredLocale: CONST.LOCALES.DEFAULT, }); @@ -108,12 +105,9 @@ function LocaleContextProvider({preferredLocale, currentUserPersonalDetails, chi const fromLocaleDigit = useMemo(() => (localeDigit) => LocaleDigitUtils.fromLocaleDigit(locale, localeDigit), [locale]); - const swapForTranslation = useMemo(() => (message) => Localize.swapForTranslation(locale, message), [locale]); - const contextValue = useMemo( () => ({ translate, - swapForTranslation, numberFormat, datetimeToRelative, datetimeToCalendarTime, @@ -124,7 +118,7 @@ function LocaleContextProvider({preferredLocale, currentUserPersonalDetails, chi fromLocaleDigit, preferredLocale: locale, }), - [translate, swapForTranslation, numberFormat, datetimeToRelative, datetimeToCalendarTime, updateLocale, formatPhoneNumber, toLocaleDigit, toLocaleOrdinal, fromLocaleDigit, locale], + [translate, numberFormat, datetimeToRelative, datetimeToCalendarTime, updateLocale, formatPhoneNumber, toLocaleDigit, toLocaleOrdinal, fromLocaleDigit, locale], ); return {children}; diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index a00577fbdf8c..16d20853aa09 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -114,7 +114,7 @@ function MoneyRequestView({ const styles = useThemeStyles(); const session = useSession(); const {isOffline} = useNetwork(); - const {translate, toLocaleDigit, swapForTranslation} = useLocalize(); + const {translate, toLocaleDigit} = useLocalize(); const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${parentReport?.parentReportID}`, { selector: (chatReportValue) => chatReportValue && {reportID: chatReportValue.reportID, errorFields: chatReportValue.errorFields}, @@ -355,18 +355,10 @@ function MoneyRequestView({ !isReceiptBeingScanned && hasReceipt && !!(receiptViolations.length || didReceiptScanSucceed) && !!canUseViolations && ReportUtils.isPaidGroupPolicy(report); const shouldShowReceiptAudit = isReceiptAllowed && (shouldShowReceiptEmptyState || hasReceipt); - const errors = useMemo(() => { - const combinedErrors = { - ...(transaction?.errorFields?.route ?? transaction?.errors), - ...parentReportAction?.errors, - }; - return Object.fromEntries( - Object.entries(combinedErrors).map(([key, value]) => - // swap for translation for each error message - [key, swapForTranslation(value as string)], - ), - ); - }, [transaction?.errorFields?.route, transaction?.errors, parentReportAction?.errors, swapForTranslation]); + const errors = { + ...(transaction?.errorFields?.route ?? transaction?.errors), + ...parentReportAction?.errors, + }; const tagList = policyTagLists.map(({name, orderWeight}, index) => { const tagError = getErrorForField( diff --git a/src/languages/msgTranslationKeySwapMapping.ts b/src/languages/msgTranslationKeySwapMapping.ts deleted file mode 100644 index 6a9a9b336538..000000000000 --- a/src/languages/msgTranslationKeySwapMapping.ts +++ /dev/null @@ -1,8 +0,0 @@ -const mapping: Record = { - // eslint-disable-next-line @typescript-eslint/naming-convention - 'The workspace is no longer accessible. Please try again on a different workspace.': 'iou.error.workspaceNotAccessible', - // eslint-disable-next-line @typescript-eslint/naming-convention - 'Unexpected error submitting this expense. Please try again later.': 'iou.error.genericCreateFailureMessage', -}; - -export default mapping; diff --git a/src/libs/Localize/index.ts b/src/libs/Localize/index.ts index 87764fb73aeb..c9eef3170245 100644 --- a/src/libs/Localize/index.ts +++ b/src/libs/Localize/index.ts @@ -5,7 +5,6 @@ import Log from '@libs/Log'; import type {MessageElementBase, MessageTextElement} from '@libs/MessageElement'; import Config from '@src/CONFIG'; import CONST from '@src/CONST'; -import msgTranslationKeySwapMapping from '@src/languages/msgTranslationKeySwapMapping'; import translations from '@src/languages/translations'; import type {TranslationFlatObject, TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -226,19 +225,5 @@ function getDevicePreferredLocale(): Locale { return RNLocalize.findBestAvailableLanguage([CONST.LOCALES.EN, CONST.LOCALES.ES])?.languageTag ?? CONST.LOCALES.DEFAULT; } -/** - * This function match the message in the translation mapping and return the translation. - * @param locale - The locale to translate the message to. - * @param message - The message to translate. - * @returns - translation of the message or the original message if no translation found - */ -function swapForTranslation(locale: Locale, message: string): string { - const translationKey: string | undefined = msgTranslationKeySwapMapping[message]; - if (translationKey) { - return translate(locale, translationKey as TranslationPaths); - } - return message; -} - -export {translate, translateLocal, formatList, formatMessageElementList, getDevicePreferredLocale, swapForTranslation}; +export {translate, translateLocal, formatList, formatMessageElementList, getDevicePreferredLocale}; export type {PhraseParameters, Phrase}; From 6822a4fb99ec6379eb990cc74949f454ed767f9d Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Tue, 16 Jul 2024 11:59:34 +0200 Subject: [PATCH 034/119] Add Export CSV and handle offline for all actions --- src/CONST.ts | 1 + src/components/DecisionModal.tsx | 2 +- .../Search/SearchListWithHeader.tsx | 20 +++++- src/components/Search/SearchPageHeader.tsx | 64 +++++++++++++++++-- src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../ExportSearchItemsToCSVParams.ts | 10 +++ src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 2 + src/libs/actions/Search.ts | 30 ++++++++- src/libs/fileDownload/index.ts | 9 ++- src/libs/fileDownload/types.ts | 4 +- 12 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 src/libs/API/parameters/ExportSearchItemsToCSVParams.ts diff --git a/src/CONST.ts b/src/CONST.ts index 7fb0d320c43a..fcac06aeb630 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5220,6 +5220,7 @@ const CONST = { SUBMIT: 'submit', APPROVE: 'approve', PAY: 'pay', + EXPORT: 'export', }, SYNTAX_OPERATORS: { AND: 'and', diff --git a/src/components/DecisionModal.tsx b/src/components/DecisionModal.tsx index 065099867e14..a9bd0b204d79 100644 --- a/src/components/DecisionModal.tsx +++ b/src/components/DecisionModal.tsx @@ -21,7 +21,7 @@ type DecisionModalProps = { secondOptionText: string; /** onSubmit callback fired after clicking on first button */ - onFirstOptionSubmit: () => void; + onFirstOptionSubmit?: () => void; /** onSubmit callback fired after clicking on second button */ onSecondOptionSubmit: () => void; diff --git a/src/components/Search/SearchListWithHeader.tsx b/src/components/Search/SearchListWithHeader.tsx index 283b68bf17af..8a8970341a70 100644 --- a/src/components/Search/SearchListWithHeader.tsx +++ b/src/components/Search/SearchListWithHeader.tsx @@ -1,6 +1,7 @@ import type {ForwardedRef} from 'react'; import React, {forwardRef, useCallback, useEffect, useMemo, useState} from 'react'; import ConfirmModal from '@components/ConfirmModal'; +import DecisionModal from '@components/DecisionModal'; import * as Expensicons from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; import Modal from '@components/Modal'; @@ -53,6 +54,8 @@ function SearchListWithHeader( const [selectedItems, setSelectedItems] = useState({}); const [selectedItemsToDelete, setSelectedItemsToDelete] = useState([]); const [deleteExpensesConfirmModalVisible, setDeleteExpensesConfirmModalVisible] = useState(false); + const [offlineModalVisible, setOfflineModalVisible] = useState(false); + const [selectedReports, setSelectedReports] = useState([]); const handleOnSelectDeleteOption = (itemsToDelete: string[]) => { setSelectedItemsToDelete(itemsToDelete); @@ -100,6 +103,7 @@ function SearchListWithHeader( if (item.transactions.every((transaction) => selectedItems[transaction.keyForList]?.isSelected)) { const reducedSelectedItems: SelectedTransactions = {...selectedItems}; + setSelectedReports([...selectedReports.filter((reportID) => reportID !== item.reportID)]); item.transactions.forEach((transaction) => { delete reducedSelectedItems[transaction.keyForList]; @@ -109,12 +113,15 @@ function SearchListWithHeader( return; } + if (item.reportID) { + setSelectedReports([...selectedReports, item.reportID]); + } setSelectedItems({ ...selectedItems, ...Object.fromEntries(item.transactions.map(mapTransactionItemToSelectedEntry)), }); }, - [selectedItems], + [selectedItems, selectedReports], ); const openBottomModal = (item: TransactionListItemType | ReportListItemType | null) => { @@ -178,6 +185,8 @@ function SearchListWithHeader( onSelectDeleteOption={handleOnSelectDeleteOption} isMobileSelectionModeActive={isMobileSelectionModeActive} setIsMobileSelectionModeActive={setIsMobileSelectionModeActive} + selectedReports={selectedReports} + setOfflineModalOpen={() => setOfflineModalVisible(true)} /> // eslint-disable-next-line react/jsx-props-no-spreading @@ -201,6 +210,15 @@ function SearchListWithHeader( cancelText={translate('common.cancel')} danger /> + setOfflineModalVisible(false)} + secondOptionText={translate('common.buttonConfirm')} + isVisible={offlineModalVisible} + onClose={() => setOfflineModalVisible(false)} + /> void; hash: number; onSelectDeleteOption?: (itemsToDelete: string[]) => void; isMobileSelectionModeActive?: boolean; setIsMobileSelectionModeActive?: (isMobileSelectionModeActive: boolean) => void; + setOfflineModalOpen?: () => void; }; type SearchHeaderOptionValue = DeepValueOf | undefined; -function SearchPageHeader({query, selectedItems = {}, hash, clearSelectedItems, onSelectDeleteOption, isMobileSelectionModeActive, setIsMobileSelectionModeActive}: SearchPageHeaderProps) { +function SearchPageHeader({ + query, + selectedItems = {}, + hash, + clearSelectedItems, + onSelectDeleteOption, + isMobileSelectionModeActive, + setIsMobileSelectionModeActive, + setOfflineModalOpen, + selectedReports, +}: SearchPageHeaderProps) { const {translate} = useLocalize(); const theme = useTheme(); const styles = useThemeStyles(); const {isOffline} = useNetwork(); + const {activeWorkspaceID} = useActiveWorkspace(); const {isSmallScreenWidth} = useResponsiveLayout(); const headerContent: {[key in SearchQuery]: {icon: IconAsset; title: string}} = { all: {icon: Illustrations.MoneyReceipts, title: translate('common.expenses')}, @@ -46,12 +60,27 @@ function SearchPageHeader({query, selectedItems = {}, hash, clearSelectedItems, const selectedItemsKeys = Object.keys(selectedItems ?? []); const headerButtonsOptions = useMemo(() => { - const options: Array> = []; - if (selectedItemsKeys.length === 0) { - return options; + return []; } + const options: Array> = [ + { + icon: Expensicons.Download, + text: translate('common.download'), + value: CONST.SEARCH.BULK_ACTION_TYPES.EXPORT, + shouldCloseModalOnSelect: true, + onSelected: () => { + if (isOffline) { + setOfflineModalOpen?.(); + return; + } + clearSelectedItems?.(); + SearchActions.exportSearchItemsToCSV(query, selectedReports, selectedItemsKeys, [activeWorkspaceID ?? '']); + }, + }, + ]; + const itemsToDelete = Object.keys(selectedItems ?? {}).filter((id) => selectedItems[id].canDelete); if (itemsToDelete.length > 0) { @@ -60,7 +89,14 @@ function SearchPageHeader({query, selectedItems = {}, hash, clearSelectedItems, text: translate('search.bulkActions.delete'), value: CONST.SEARCH.BULK_ACTION_TYPES.DELETE, shouldCloseModalOnSelect: true, - onSelected: () => onSelectDeleteOption?.(itemsToDelete), + onSelected: () => { + if (isOffline) { + setOfflineModalOpen?.(); + return; + } + + onSelectDeleteOption?.(itemsToDelete); + }, }); } @@ -71,7 +107,13 @@ function SearchPageHeader({query, selectedItems = {}, hash, clearSelectedItems, icon: Expensicons.Stopwatch, text: translate('search.bulkActions.hold'), value: CONST.SEARCH.BULK_ACTION_TYPES.HOLD, + shouldCloseModalOnSelect: true, onSelected: () => { + if (isOffline) { + setOfflineModalOpen?.(); + return; + } + clearSelectedItems?.(); if (isMobileSelectionModeActive) { setIsMobileSelectionModeActive?.(false); @@ -88,7 +130,13 @@ function SearchPageHeader({query, selectedItems = {}, hash, clearSelectedItems, icon: Expensicons.Stopwatch, text: translate('search.bulkActions.unhold'), value: CONST.SEARCH.BULK_ACTION_TYPES.UNHOLD, + shouldCloseModalOnSelect: true, onSelected: () => { + if (isOffline) { + setOfflineModalOpen?.(); + return; + } + clearSelectedItems?.(); if (isMobileSelectionModeActive) { setIsMobileSelectionModeActive?.(false); @@ -129,6 +177,11 @@ function SearchPageHeader({query, selectedItems = {}, hash, clearSelectedItems, theme.icon, styles.colorMuted, styles.fontWeightNormal, + query, + isOffline, + setOfflineModalOpen, + activeWorkspaceID, + selectedReports, ]); if (isSmallScreenWidth) { @@ -158,7 +211,6 @@ function SearchPageHeader({query, selectedItems = {}, hash, clearSelectedItems, customText={translate('workspace.common.selected', {selectedNumber: selectedItemsKeys.length})} options={headerButtonsOptions} isSplitButton={false} - isDisabled={isOffline} /> )} diff --git a/src/languages/en.ts b/src/languages/en.ts index d32e228dbb28..f6fe52da76f3 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3486,6 +3486,7 @@ export default { unhold: 'Unhold', noOptionsAvailable: 'No options available for the selected group of expenses.', }, + offlinePrompt: 'You can’t take this action right now because you appear to be offline.', }, genericErrorPage: { title: 'Uh-oh, something went wrong!', diff --git a/src/languages/es.ts b/src/languages/es.ts index 0f6fa177ef82..fbc33eb38986 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3538,6 +3538,7 @@ export default { unhold: 'Desbloquear', noOptionsAvailable: 'No hay opciones disponibles para el grupo de gastos seleccionado.', }, + offlinePrompt: 'No puedes realizar esta acción ahora mismo porque pareces estar desconectado.', }, genericErrorPage: { title: '¡Oh-oh, algo salió mal!', diff --git a/src/libs/API/parameters/ExportSearchItemsToCSVParams.ts b/src/libs/API/parameters/ExportSearchItemsToCSVParams.ts new file mode 100644 index 000000000000..979a7b99886f --- /dev/null +++ b/src/libs/API/parameters/ExportSearchItemsToCSVParams.ts @@ -0,0 +1,10 @@ +import type {SearchQuery} from '@src/types/onyx/SearchResults'; + +type ExportSearchItemsToCSVParams = { + query: SearchQuery; + reportIDList: string[]; + transactionIDList: string[]; + policyIDs: string[]; +}; + +export default ExportSearchItemsToCSVParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 204fa01ed14c..8cc3fb8f646f 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -258,3 +258,4 @@ export type {default as UpdateNetSuiteCustomFormIDParams} from './UpdateNetSuite export type {default as UpdateSageIntacctGenericTypeParams} from './UpdateSageIntacctGenericTypeParams'; export type {default as UpdateNetSuiteCustomersJobsParams} from './UpdateNetSuiteCustomersJobsParams'; export type {default as CopyExistingPolicyConnectionParams} from './CopyExistingPolicyConnectionParams'; +export type {default as ExportSearchItemsToCSVParams} from './ExportSearchItemsToCSVParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 4ecddbdb7406..c28399c97948 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -679,6 +679,7 @@ const READ_COMMANDS = { OPEN_POLICY_INITIAL_PAGE: 'OpenPolicyInitialPage', SEARCH: 'Search', OPEN_SUBSCRIPTION_PAGE: 'OpenSubscriptionPage', + EXPORT_SEARCH_ITEMS_TO_CSV: 'ExportSearchToCSV', } as const; type ReadCommand = ValueOf; @@ -732,6 +733,7 @@ type ReadCommandParameters = { [READ_COMMANDS.OPEN_POLICY_INITIAL_PAGE]: Parameters.OpenPolicyInitialPageParams; [READ_COMMANDS.SEARCH]: Parameters.SearchParams; [READ_COMMANDS.OPEN_SUBSCRIPTION_PAGE]: null; + [READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV]: Parameters.ExportSearchItemsToCSVParams; }; const SIDE_EFFECT_REQUEST_COMMANDS = { diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 4ce82a027a12..7e38c2336e34 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -3,6 +3,10 @@ import type {OnyxUpdate} from 'react-native-onyx'; import * as API from '@libs/API'; import type {SearchParams} from '@libs/API/parameters'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; +import * as ApiUtils from '@libs/ApiUtils'; +import fileDownload from '@libs/fileDownload'; +import enhanceParameters from '@libs/Network/enhanceParameters'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {SearchTransaction} from '@src/types/onyx/SearchResults'; import * as Report from './Report'; @@ -83,4 +87,28 @@ function deleteMoneyRequestOnSearch(hash: number, transactionIDList: string[]) { API.write(WRITE_COMMANDS.DELETE_MONEY_REQUEST_ON_SEARCH, {hash, transactionIDList}, {optimisticData, finallyData}); } -export {search, createTransactionThread, deleteMoneyRequestOnSearch, holdMoneyRequestOnSearch, unholdMoneyRequestOnSearch}; +type Params = Record; + +function exportSearchItemsToCSV(query: string, reportIDList: string[] | undefined, transactionIDList: string[], policyIDs: string[]) { + const fileName = `Expensify_${query}.csv`; + + const finalParameters = enhanceParameters(READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV, { + query, + reportIDList, + transactionIDList, + policyIDs, + }) as Params; + + const formData = new FormData(); + + Object.entries(finalParameters).forEach(([key, value]) => { + if (Array.isArray(value)) { + formData.append(key, value.join(',')); + } else { + formData.append(key, String(value)); + } + }); + + fileDownload(ApiUtils.getCommandURL({command: READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST); +} +export {search, createTransactionThread, deleteMoneyRequestOnSearch, holdMoneyRequestOnSearch, unholdMoneyRequestOnSearch, exportSearchItemsToCSV}; diff --git a/src/libs/fileDownload/index.ts b/src/libs/fileDownload/index.ts index b39e65a87f94..8891cf775107 100644 --- a/src/libs/fileDownload/index.ts +++ b/src/libs/fileDownload/index.ts @@ -9,7 +9,7 @@ import type {FileDownload} from './types'; * The function downloads an attachment on web/desktop platforms. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars -const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false) => { +const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false, formData = undefined, requestType = 'get') => { const resolvedUrl = tryResolveUrlFromApiRoot(url); if ( // we have two file download cases that we should allow 1. dowloading attachments 2. downloading Expensify package for Sage Intacct @@ -24,7 +24,12 @@ const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOp return Promise.resolve(); } - return fetch(url) + const fetchOptions: RequestInit = { + method: requestType, + body: formData, + }; + + return fetch(url, fetchOptions) .then((response) => response.blob()) .then((blob) => { // Create blob link to download diff --git a/src/libs/fileDownload/types.ts b/src/libs/fileDownload/types.ts index fcc210c1c42f..d8897331d21c 100644 --- a/src/libs/fileDownload/types.ts +++ b/src/libs/fileDownload/types.ts @@ -1,7 +1,7 @@ import type {Asset} from 'react-native-image-picker'; +import type {RequestType} from '@src/types/onyx/Request'; -type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean) => Promise; - +type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean, formData?: FormData, requestType?: RequestType) => Promise; type ImageResolution = {width: number; height: number}; type GetImageResolution = (url: File | Asset) => Promise; From 0387a7007f4f1770e82c6b8391f0bcd3fef16615 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 16 Jul 2024 12:49:37 +0200 Subject: [PATCH 035/119] update typings --- .../{index.tsx => TransparentOverlay.tsx} | 0 .../AutoCompleteSuggestionsPortal/index.native.tsx | 6 +++--- .../AutoCompleteSuggestionsPortal/index.tsx | 12 +++++++++--- src/components/AutoCompleteSuggestions/types.ts | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) rename src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/{index.tsx => TransparentOverlay.tsx} (100%) diff --git a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/TransparentOverlay.tsx similarity index 100% rename from src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/index.tsx rename to src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/TransparentOverlay.tsx diff --git a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.native.tsx b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.native.tsx index d30d97044fc0..9ac43c4d8830 100644 --- a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.native.tsx +++ b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.native.tsx @@ -4,10 +4,10 @@ import {View} from 'react-native'; import BaseAutoCompleteSuggestions from '@components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions'; import useStyleUtils from '@hooks/useStyleUtils'; import getBottomSuggestionPadding from './getBottomSuggestionPadding'; -import TransparentOverlay from './TransparentOverlay'; +import TransparentOverlay from './TransparentOverlay/TransparentOverlay'; import type {AutoCompleteSuggestionsPortalProps} from './types'; -function AutoCompleteSuggestionsPortal({left = 0, width = 0, bottom = 0, ...props}: AutoCompleteSuggestionsPortalProps) { +function AutoCompleteSuggestionsPortal({left = 0, width = 0, bottom = 0, resetSuggestions = () => {}, ...props}: AutoCompleteSuggestionsPortalProps) { const StyleUtils = useStyleUtils(); const styles = useMemo(() => StyleUtils.getBaseAutoCompleteSuggestionContainerStyle({left, width, bottom: bottom + getBottomSuggestionPadding()}), [StyleUtils, left, width, bottom]); @@ -17,7 +17,7 @@ function AutoCompleteSuggestionsPortal({left = 0, width = 0, bottom return ( - + {/* eslint-disable-next-line react/jsx-props-no-spreading */} diff --git a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.tsx b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.tsx index 1d56ab2cced4..d26dd0422368 100644 --- a/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.tsx +++ b/src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/index.tsx @@ -5,7 +5,7 @@ import {View} from 'react-native'; import BaseAutoCompleteSuggestions from '@components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions'; import useStyleUtils from '@hooks/useStyleUtils'; import getBottomSuggestionPadding from './getBottomSuggestionPadding'; -import TransparentOverlay from './TransparentOverlay'; +import TransparentOverlay from './TransparentOverlay/TransparentOverlay'; import type {AutoCompleteSuggestionsPortalProps} from './types'; /** @@ -15,7 +15,13 @@ import type {AutoCompleteSuggestionsPortalProps} from './types'; * On the native platform, tapping on auto-complete suggestions will not blur the main input. */ -function AutoCompleteSuggestionsPortal({left = 0, width = 0, bottom = 0, ...props}: AutoCompleteSuggestionsPortalProps): ReactElement | null | false { +function AutoCompleteSuggestionsPortal({ + left = 0, + width = 0, + bottom = 0, + resetSuggestions = () => {}, + ...props +}: AutoCompleteSuggestionsPortalProps): ReactElement | null | false { const StyleUtils = useStyleUtils(); const bodyElement = document.querySelector('body'); @@ -33,7 +39,7 @@ function AutoCompleteSuggestionsPortal({left = 0, width = 0, bottom bodyElement && ReactDOM.createPortal( <> - + {componentToRender} , bodyElement, diff --git a/src/components/AutoCompleteSuggestions/types.ts b/src/components/AutoCompleteSuggestions/types.ts index b60407e70beb..57347cd65abe 100644 --- a/src/components/AutoCompleteSuggestions/types.ts +++ b/src/components/AutoCompleteSuggestions/types.ts @@ -44,7 +44,7 @@ type AutoCompleteSuggestionsProps = { measureParentContainerAndReportCursor?: (props: MeasureParentContainerAndCursorCallback) => void; /** Reset the emoji suggestions */ - resetSuggestions: () => void; + resetSuggestions?: () => void; }; export type {AutoCompleteSuggestionsProps, RenderSuggestionMenuItemProps, MeasureParentContainerAndCursorCallback, MeasureParentContainerAndCursor}; From 26e6eeeaee615ee489ea5c291e2421aaabd97268 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 16 Jul 2024 13:16:55 +0200 Subject: [PATCH 036/119] fix: show no results found message when no search result for assignee --- src/pages/workspace/card/issueNew/AssigneeStep.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pages/workspace/card/issueNew/AssigneeStep.tsx b/src/pages/workspace/card/issueNew/AssigneeStep.tsx index 23acb3d4a24a..042e93ae2fae 100644 --- a/src/pages/workspace/card/issueNew/AssigneeStep.tsx +++ b/src/pages/workspace/card/issueNew/AssigneeStep.tsx @@ -119,6 +119,12 @@ function AssigneeStep({policy}: AssigneeStepProps) { ]; }, [membersDetails, debouncedSearchTerm]); + const headerMessage = useMemo(() => { + const searchValue = debouncedSearchTerm.trim().toLowerCase(); + + return OptionsListUtils.getHeaderMessage(sections[0].data.length !== 0, false, searchValue); + }, [debouncedSearchTerm, sections]); + return ( From 45141855cb9e86a41766de7fa1823598eadd2367 Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Tue, 16 Jul 2024 14:59:47 +0200 Subject: [PATCH 037/119] Change request type --- src/components/Search/SearchPageHeader.tsx | 2 +- src/libs/actions/Search.ts | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/components/Search/SearchPageHeader.tsx b/src/components/Search/SearchPageHeader.tsx index 4833f8d37b0a..af5badb7cf8a 100644 --- a/src/components/Search/SearchPageHeader.tsx +++ b/src/components/Search/SearchPageHeader.tsx @@ -76,7 +76,7 @@ function SearchPageHeader({ return; } clearSelectedItems?.(); - SearchActions.exportSearchItemsToCSV(query, selectedReports, selectedItemsKeys, [activeWorkspaceID ?? '']); + SearchActions.exportSearchItemsToCSV(query, selectedReports ?? [], selectedItemsKeys, [activeWorkspaceID ?? '']); }, }, ]; diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 7e38c2336e34..24fd2cd571e6 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -6,7 +6,6 @@ import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ApiUtils from '@libs/ApiUtils'; import fileDownload from '@libs/fileDownload'; import enhanceParameters from '@libs/Network/enhanceParameters'; -import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {SearchTransaction} from '@src/types/onyx/SearchResults'; import * as Report from './Report'; @@ -99,16 +98,11 @@ function exportSearchItemsToCSV(query: string, reportIDList: string[] | undefine policyIDs, }) as Params; - const formData = new FormData(); + // Convert finalParameters to a query string + const queryString = Object.entries(finalParameters) + .map(([key, value]) => `${key}=${Array.isArray(value) ? value.join(',') : String(value)}`) + .join('&'); - Object.entries(finalParameters).forEach(([key, value]) => { - if (Array.isArray(value)) { - formData.append(key, value.join(',')); - } else { - formData.append(key, String(value)); - } - }); - - fileDownload(ApiUtils.getCommandURL({command: READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST); + fileDownload(`${ApiUtils.getCommandURL({command: READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV})}${queryString}`, fileName); } export {search, createTransactionThread, deleteMoneyRequestOnSearch, holdMoneyRequestOnSearch, unholdMoneyRequestOnSearch, exportSearchItemsToCSV}; From 2c69e75f37507e559d52fae2e24755b7716d663b Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Tue, 16 Jul 2024 15:15:45 +0200 Subject: [PATCH 038/119] Revert fileDownload function changes --- src/libs/fileDownload/index.ts | 9 ++------- src/libs/fileDownload/types.ts | 3 +-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/libs/fileDownload/index.ts b/src/libs/fileDownload/index.ts index 8891cf775107..b39e65a87f94 100644 --- a/src/libs/fileDownload/index.ts +++ b/src/libs/fileDownload/index.ts @@ -9,7 +9,7 @@ import type {FileDownload} from './types'; * The function downloads an attachment on web/desktop platforms. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars -const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false, formData = undefined, requestType = 'get') => { +const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false) => { const resolvedUrl = tryResolveUrlFromApiRoot(url); if ( // we have two file download cases that we should allow 1. dowloading attachments 2. downloading Expensify package for Sage Intacct @@ -24,12 +24,7 @@ const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOp return Promise.resolve(); } - const fetchOptions: RequestInit = { - method: requestType, - body: formData, - }; - - return fetch(url, fetchOptions) + return fetch(url) .then((response) => response.blob()) .then((blob) => { // Create blob link to download diff --git a/src/libs/fileDownload/types.ts b/src/libs/fileDownload/types.ts index d8897331d21c..3af584bb8d3a 100644 --- a/src/libs/fileDownload/types.ts +++ b/src/libs/fileDownload/types.ts @@ -1,7 +1,6 @@ import type {Asset} from 'react-native-image-picker'; -import type {RequestType} from '@src/types/onyx/Request'; -type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean, formData?: FormData, requestType?: RequestType) => Promise; +type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean) => Promise; type ImageResolution = {width: number; height: number}; type GetImageResolution = (url: File | Asset) => Promise; From 6c77fa8a69f76e5666c46db74faba099ce86dedf Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Tue, 16 Jul 2024 15:16:17 +0200 Subject: [PATCH 039/119] Add back empty line --- src/libs/fileDownload/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/fileDownload/types.ts b/src/libs/fileDownload/types.ts index 3af584bb8d3a..fcc210c1c42f 100644 --- a/src/libs/fileDownload/types.ts +++ b/src/libs/fileDownload/types.ts @@ -1,6 +1,7 @@ import type {Asset} from 'react-native-image-picker'; type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean) => Promise; + type ImageResolution = {width: number; height: number}; type GetImageResolution = (url: File | Asset) => Promise; From a91b592f66854e8aef23945f8bc51e1ece2c0e75 Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Tue, 16 Jul 2024 15:40:32 +0200 Subject: [PATCH 040/119] CR fixes --- .../Search/SearchListWithHeader.tsx | 74 +++++++++---------- src/components/Search/SearchPageHeader.tsx | 40 +++++----- src/libs/actions/Search.ts | 2 +- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/components/Search/SearchListWithHeader.tsx b/src/components/Search/SearchListWithHeader.tsx index 8a8970341a70..1c7d3d3f3b07 100644 --- a/src/components/Search/SearchListWithHeader.tsx +++ b/src/components/Search/SearchListWithHeader.tsx @@ -12,7 +12,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; import * as SearchActions from '@libs/actions/Search'; import * as SearchUtils from '@libs/SearchUtils'; import CONST from '@src/CONST'; -import type {SearchDataTypes, SearchQuery} from '@src/types/onyx/SearchResults'; +import type {SearchDataTypes, SearchQuery, SearchReport} from '@src/types/onyx/SearchResults'; import SearchPageHeader from './SearchPageHeader'; import type {SelectedTransactionInfo, SelectedTransactions} from './types'; @@ -29,17 +29,17 @@ function mapTransactionItemToSelectedEntry(item: TransactionListItemType): [stri return [item.keyForList, {isSelected: true, canDelete: item.canDelete, action: item.action}]; } -function mapToTransactionItemWithSelectionInfo(item: TransactionListItemType, selectedItems: SelectedTransactions) { - return {...item, isSelected: !!selectedItems[item.keyForList]?.isSelected}; +function mapToTransactionItemWithSelectionInfo(item: TransactionListItemType, selectedTransactions: SelectedTransactions) { + return {...item, isSelected: !!selectedTransactions[item.keyForList]?.isSelected}; } -function mapToItemWithSelectionInfo(item: TransactionListItemType | ReportListItemType, selectedItems: SelectedTransactions) { +function mapToItemWithSelectionInfo(item: TransactionListItemType | ReportListItemType, selectedTransactions: SelectedTransactions) { return SearchUtils.isTransactionListItemType(item) - ? mapToTransactionItemWithSelectionInfo(item, selectedItems) + ? mapToTransactionItemWithSelectionInfo(item, selectedTransactions) : { ...item, - transactions: item.transactions?.map((tranaction) => mapToTransactionItemWithSelectionInfo(tranaction, selectedItems)), - isSelected: item.transactions.every((transaction) => !!selectedItems[transaction.keyForList]?.isSelected), + transactions: item.transactions?.map((tranaction) => mapToTransactionItemWithSelectionInfo(tranaction, selectedTransactions)), + isSelected: item.transactions.every((transaction) => !!selectedTransactions[transaction.keyForList]?.isSelected), }; } @@ -51,36 +51,36 @@ function SearchListWithHeader( const {translate} = useLocalize(); const [isModalVisible, setIsModalVisible] = useState(false); const [longPressedItem, setLongPressedItem] = useState(null); - const [selectedItems, setSelectedItems] = useState({}); - const [selectedItemsToDelete, setSelectedItemsToDelete] = useState([]); + const [selectedTransactions, setSelectedTransactions] = useState({}); + const [selectedReports, setSelectedReports] = useState>([]); + const [selectedTransactionsToDelete, setSelectedTransactionsToDelete] = useState([]); const [deleteExpensesConfirmModalVisible, setDeleteExpensesConfirmModalVisible] = useState(false); const [offlineModalVisible, setOfflineModalVisible] = useState(false); - const [selectedReports, setSelectedReports] = useState([]); const handleOnSelectDeleteOption = (itemsToDelete: string[]) => { - setSelectedItemsToDelete(itemsToDelete); + setSelectedTransactionsToDelete(itemsToDelete); setDeleteExpensesConfirmModalVisible(true); }; const handleOnCancelConfirmModal = () => { - setSelectedItemsToDelete([]); + setSelectedTransactionsToDelete([]); setDeleteExpensesConfirmModalVisible(false); }; - const clearSelectedItems = () => setSelectedItems({}); + const clearSelectedTransactions = () => setSelectedTransactions({}); const handleDeleteExpenses = () => { - if (selectedItemsToDelete.length === 0) { + if (selectedTransactionsToDelete.length === 0) { return; } - clearSelectedItems(); + clearSelectedTransactions(); setDeleteExpensesConfirmModalVisible(false); - SearchActions.deleteMoneyRequestOnSearch(hash, selectedItemsToDelete); + SearchActions.deleteMoneyRequestOnSearch(hash, selectedTransactionsToDelete); }; useEffect(() => { - clearSelectedItems(); + clearSelectedTransactions(); }, [hash]); const toggleTransaction = useCallback( @@ -90,7 +90,7 @@ function SearchListWithHeader( return; } - setSelectedItems((prev) => { + setSelectedTransactions((prev) => { if (prev[item.keyForList]?.isSelected) { const {[item.keyForList]: omittedTransaction, ...transactions} = prev; return transactions; @@ -101,27 +101,27 @@ function SearchListWithHeader( return; } - if (item.transactions.every((transaction) => selectedItems[transaction.keyForList]?.isSelected)) { - const reducedSelectedItems: SelectedTransactions = {...selectedItems}; - setSelectedReports([...selectedReports.filter((reportID) => reportID !== item.reportID)]); + if (item.transactions.every((transaction) => selectedTransactions[transaction.keyForList]?.isSelected)) { + const reducedSelectedTransactions: SelectedTransactions = {...selectedTransactions}; + setSelectedReports((prevReports) => prevReports.filter((reportID) => reportID !== item.reportID)); item.transactions.forEach((transaction) => { - delete reducedSelectedItems[transaction.keyForList]; + delete reducedSelectedTransactions[transaction.keyForList]; }); - setSelectedItems(reducedSelectedItems); + setSelectedTransactions(reducedSelectedTransactions); return; } if (item.reportID) { setSelectedReports([...selectedReports, item.reportID]); } - setSelectedItems({ - ...selectedItems, + setSelectedTransactions({ + ...selectedTransactions, ...Object.fromEntries(item.transactions.map(mapTransactionItemToSelectedEntry)), }); }, - [selectedItems, selectedReports], + [selectedTransactions, selectedReports], ); const openBottomModal = (item: TransactionListItemType | ReportListItemType | null) => { @@ -151,35 +151,35 @@ function SearchListWithHeader( return; } - setSelectedItems({}); - }, [setSelectedItems, isMobileSelectionModeActive]); + setSelectedTransactions({}); + }, [setSelectedTransactions, isMobileSelectionModeActive]); const toggleAllTransactions = () => { const areItemsOfReportType = searchType === CONST.SEARCH.DATA_TYPES.REPORT; const flattenedItems = areItemsOfReportType ? (data as ReportListItemType[]).flatMap((item) => item.transactions) : data; - const isAllSelected = flattenedItems.length === Object.keys(selectedItems).length; + const isAllSelected = flattenedItems.length === Object.keys(selectedTransactions).length; if (isAllSelected) { - clearSelectedItems(); + clearSelectedTransactions(); return; } if (areItemsOfReportType) { - setSelectedItems(Object.fromEntries((data as ReportListItemType[]).flatMap((item) => item.transactions.map(mapTransactionItemToSelectedEntry)))); + setSelectedTransactions(Object.fromEntries((data as ReportListItemType[]).flatMap((item) => item.transactions.map(mapTransactionItemToSelectedEntry)))); return; } - setSelectedItems(Object.fromEntries((data as TransactionListItemType[]).map(mapTransactionItemToSelectedEntry))); + setSelectedTransactions(Object.fromEntries((data as TransactionListItemType[]).map(mapTransactionItemToSelectedEntry))); }; - const sortedSelectedData = useMemo(() => data.map((item) => mapToItemWithSelectionInfo(item, selectedItems)), [data, selectedItems]); + const sortedSelectedData = useMemo(() => data.map((item) => mapToItemWithSelectionInfo(item, selectedTransactions)), [data, selectedTransactions]); return ( <> void; + selectedTransactions?: SelectedTransactions; + selectedReports?: Array; + clearSelectedTransactions?: () => void; hash: number; onSelectDeleteOption?: (itemsToDelete: string[]) => void; isMobileSelectionModeActive?: boolean; @@ -35,9 +35,9 @@ type SearchHeaderOptionValue = DeepValueOf { - if (selectedItemsKeys.length === 0) { + if (selectedTransactionsKeys.length === 0) { return []; } @@ -75,13 +75,13 @@ function SearchPageHeader({ setOfflineModalOpen?.(); return; } - clearSelectedItems?.(); - SearchActions.exportSearchItemsToCSV(query, selectedReports ?? [], selectedItemsKeys, [activeWorkspaceID ?? '']); + clearSelectedTransactions?.(); + SearchActions.exportSearchItemsToCSV(query, selectedReports, selectedTransactionsKeys, [activeWorkspaceID ?? '']); }, }, ]; - const itemsToDelete = Object.keys(selectedItems ?? {}).filter((id) => selectedItems[id].canDelete); + const itemsToDelete = Object.keys(selectedTransactions ?? {}).filter((id) => selectedTransactions[id].canDelete); if (itemsToDelete.length > 0) { options.push({ @@ -100,7 +100,7 @@ function SearchPageHeader({ }); } - const itemsToHold = selectedItemsKeys.filter((id) => selectedItems[id].action === CONST.SEARCH.BULK_ACTION_TYPES.HOLD); + const itemsToHold = selectedTransactionsKeys.filter((id) => selectedTransactions[id].action === CONST.SEARCH.BULK_ACTION_TYPES.HOLD); if (itemsToHold.length > 0) { options.push({ @@ -114,7 +114,7 @@ function SearchPageHeader({ return; } - clearSelectedItems?.(); + clearSelectedTransactions?.(); if (isMobileSelectionModeActive) { setIsMobileSelectionModeActive?.(false); } @@ -123,7 +123,7 @@ function SearchPageHeader({ }); } - const itemsToUnhold = selectedItemsKeys.filter((id) => selectedItems[id].action === CONST.SEARCH.BULK_ACTION_TYPES.UNHOLD); + const itemsToUnhold = selectedTransactionsKeys.filter((id) => selectedTransactions[id].action === CONST.SEARCH.BULK_ACTION_TYPES.UNHOLD); if (itemsToUnhold.length > 0) { options.push({ @@ -137,7 +137,7 @@ function SearchPageHeader({ return; } - clearSelectedItems?.(); + clearSelectedTransactions?.(); if (isMobileSelectionModeActive) { setIsMobileSelectionModeActive?.(false); } @@ -166,11 +166,11 @@ function SearchPageHeader({ return options; }, [ - selectedItemsKeys, - selectedItems, + selectedTransactionsKeys, + selectedTransactions, translate, onSelectDeleteOption, - clearSelectedItems, + clearSelectedTransactions, isMobileSelectionModeActive, hash, setIsMobileSelectionModeActive, @@ -189,7 +189,7 @@ function SearchPageHeader({ return ( ); } @@ -208,7 +208,7 @@ function SearchPageHeader({ shouldAlwaysShowDropdownMenu pressOnEnter buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} - customText={translate('workspace.common.selected', {selectedNumber: selectedItemsKeys.length})} + customText={translate('workspace.common.selected', {selectedNumber: selectedTransactionsKeys.length})} options={headerButtonsOptions} isSplitButton={false} /> diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 24fd2cd571e6..f6abb552cde0 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -88,7 +88,7 @@ function deleteMoneyRequestOnSearch(hash: number, transactionIDList: string[]) { type Params = Record; -function exportSearchItemsToCSV(query: string, reportIDList: string[] | undefined, transactionIDList: string[], policyIDs: string[]) { +function exportSearchItemsToCSV(query: string, reportIDList: Array | undefined, transactionIDList: string[], policyIDs: string[]) { const fileName = `Expensify_${query}.csv`; const finalParameters = enhanceParameters(READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV, { From a2a9e37be111f146aba9d8ba1b63a08b2e01d8ed Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 16:45:23 +0300 Subject: [PATCH 041/119] restructure integrations --- docs/_data/_routes.yml | 4 ++-- .../integrations/{HR-integrations => }/ADP.md | 0 .../{accounting-integrations => Accelo}/Accelo.md | 0 .../Additional-Travel-Integrations.md | 0 .../{accounting-integrations => Certinia}/Certinia.md | 0 .../integrations/{travel-integrations => }/Egencia.md | 0 .../integrations/{travel-integrations => }/Global-VaTax.md | 0 .../integrations/{other-integrations => }/Google-Apps-SSO.md | 0 .../integrations/{HR-integrations => }/Greenhouse.md | 0 .../integrations/{HR-integrations => }/Gusto.md | 0 .../Indirect-Accounting-Integrations.md | 0 .../integrations/{travel-integrations => }/Lyft.md | 0 .../integrations/{travel-integrations => }/Navan.md | 0 .../{accounting-integrations => Netsuite}/NetSuite.md | 0 .../integrations/{HR-integrations => }/QuickBooks-Time.md | 0 .../QuickBooks-Desktop.md | 0 .../QuickBooks-Online.md | 0 .../integrations/{HR-integrations => }/Rippling.md | 0 .../Sage-Intacct.md | 0 .../integrations/{travel-integrations => }/TravelPerk.md | 0 .../integrations/{travel-integrations => }/Uber.md | 0 .../integrations/{HR-integrations => }/Workday.md | 0 .../integrations/{accounting-integrations => Xero}/Xero.md | 0 .../integrations/{HR-integrations => }/Zenefits.md | 0 .../HR-integrations.html => connections/accelo.html} | 0 .../certinia.html} | 0 .../hubs/{integrations => connections}/index.html | 0 .../other-integrations.html => connections/netsuite.html} | 0 .../quickbooks-desktop.html} | 0 .../hubs/connections/quickbooks-online.html | 5 +++++ docs/expensify-classic/hubs/connections/sage-intacct.html | 5 +++++ docs/expensify-classic/hubs/connections/xero.html | 5 +++++ 32 files changed, 17 insertions(+), 2 deletions(-) rename docs/articles/expensify-classic/integrations/{HR-integrations => }/ADP.md (100%) rename docs/articles/expensify-classic/integrations/{accounting-integrations => Accelo}/Accelo.md (100%) rename docs/articles/expensify-classic/integrations/{travel-integrations => }/Additional-Travel-Integrations.md (100%) rename docs/articles/expensify-classic/integrations/{accounting-integrations => Certinia}/Certinia.md (100%) rename docs/articles/expensify-classic/integrations/{travel-integrations => }/Egencia.md (100%) rename docs/articles/expensify-classic/integrations/{travel-integrations => }/Global-VaTax.md (100%) rename docs/articles/expensify-classic/integrations/{other-integrations => }/Google-Apps-SSO.md (100%) rename docs/articles/expensify-classic/integrations/{HR-integrations => }/Greenhouse.md (100%) rename docs/articles/expensify-classic/integrations/{HR-integrations => }/Gusto.md (100%) rename docs/articles/expensify-classic/integrations/{accounting-integrations => }/Indirect-Accounting-Integrations.md (100%) rename docs/articles/expensify-classic/integrations/{travel-integrations => }/Lyft.md (100%) rename docs/articles/expensify-classic/integrations/{travel-integrations => }/Navan.md (100%) rename docs/articles/expensify-classic/integrations/{accounting-integrations => Netsuite}/NetSuite.md (100%) rename docs/articles/expensify-classic/integrations/{HR-integrations => }/QuickBooks-Time.md (100%) rename docs/articles/expensify-classic/integrations/{accounting-integrations => Quickbooks-Desktop}/QuickBooks-Desktop.md (100%) rename docs/articles/expensify-classic/integrations/{accounting-integrations => Quickbooks-Online}/QuickBooks-Online.md (100%) rename docs/articles/expensify-classic/integrations/{HR-integrations => }/Rippling.md (100%) rename docs/articles/expensify-classic/integrations/{accounting-integrations => Sage-Intacct}/Sage-Intacct.md (100%) rename docs/articles/expensify-classic/integrations/{travel-integrations => }/TravelPerk.md (100%) rename docs/articles/expensify-classic/integrations/{travel-integrations => }/Uber.md (100%) rename docs/articles/expensify-classic/integrations/{HR-integrations => }/Workday.md (100%) rename docs/articles/expensify-classic/integrations/{accounting-integrations => Xero}/Xero.md (100%) rename docs/articles/expensify-classic/integrations/{HR-integrations => }/Zenefits.md (100%) rename docs/expensify-classic/hubs/{integrations/HR-integrations.html => connections/accelo.html} (100%) rename docs/expensify-classic/hubs/{integrations/accounting-integrations.html => connections/certinia.html} (100%) rename docs/expensify-classic/hubs/{integrations => connections}/index.html (100%) rename docs/expensify-classic/hubs/{integrations/other-integrations.html => connections/netsuite.html} (100%) rename docs/expensify-classic/hubs/{integrations/travel-integrations.html => connections/quickbooks-desktop.html} (100%) create mode 100644 docs/expensify-classic/hubs/connections/quickbooks-online.html create mode 100644 docs/expensify-classic/hubs/connections/sage-intacct.html create mode 100644 docs/expensify-classic/hubs/connections/xero.html diff --git a/docs/_data/_routes.yml b/docs/_data/_routes.yml index 7f416951b58c..85ffbb30c360 100644 --- a/docs/_data/_routes.yml +++ b/docs/_data/_routes.yml @@ -69,8 +69,8 @@ platforms: icon: /assets/images/handshake.svg description: Discover the benefits of becoming an Expensify Partner. - - href: integrations - title: Integrations + - href: connections + title: Connections icon: /assets/images/simple-illustration__monitor-remotesync.svg description: Integrate with accounting or HR software to streamline expense approvals. diff --git a/docs/articles/expensify-classic/integrations/HR-integrations/ADP.md b/docs/articles/expensify-classic/integrations/ADP.md similarity index 100% rename from docs/articles/expensify-classic/integrations/HR-integrations/ADP.md rename to docs/articles/expensify-classic/integrations/ADP.md diff --git a/docs/articles/expensify-classic/integrations/accounting-integrations/Accelo.md b/docs/articles/expensify-classic/integrations/Accelo/Accelo.md similarity index 100% rename from docs/articles/expensify-classic/integrations/accounting-integrations/Accelo.md rename to docs/articles/expensify-classic/integrations/Accelo/Accelo.md diff --git a/docs/articles/expensify-classic/integrations/travel-integrations/Additional-Travel-Integrations.md b/docs/articles/expensify-classic/integrations/Additional-Travel-Integrations.md similarity index 100% rename from docs/articles/expensify-classic/integrations/travel-integrations/Additional-Travel-Integrations.md rename to docs/articles/expensify-classic/integrations/Additional-Travel-Integrations.md diff --git a/docs/articles/expensify-classic/integrations/accounting-integrations/Certinia.md b/docs/articles/expensify-classic/integrations/Certinia/Certinia.md similarity index 100% rename from docs/articles/expensify-classic/integrations/accounting-integrations/Certinia.md rename to docs/articles/expensify-classic/integrations/Certinia/Certinia.md diff --git a/docs/articles/expensify-classic/integrations/travel-integrations/Egencia.md b/docs/articles/expensify-classic/integrations/Egencia.md similarity index 100% rename from docs/articles/expensify-classic/integrations/travel-integrations/Egencia.md rename to docs/articles/expensify-classic/integrations/Egencia.md diff --git a/docs/articles/expensify-classic/integrations/travel-integrations/Global-VaTax.md b/docs/articles/expensify-classic/integrations/Global-VaTax.md similarity index 100% rename from docs/articles/expensify-classic/integrations/travel-integrations/Global-VaTax.md rename to docs/articles/expensify-classic/integrations/Global-VaTax.md diff --git a/docs/articles/expensify-classic/integrations/other-integrations/Google-Apps-SSO.md b/docs/articles/expensify-classic/integrations/Google-Apps-SSO.md similarity index 100% rename from docs/articles/expensify-classic/integrations/other-integrations/Google-Apps-SSO.md rename to docs/articles/expensify-classic/integrations/Google-Apps-SSO.md diff --git a/docs/articles/expensify-classic/integrations/HR-integrations/Greenhouse.md b/docs/articles/expensify-classic/integrations/Greenhouse.md similarity index 100% rename from docs/articles/expensify-classic/integrations/HR-integrations/Greenhouse.md rename to docs/articles/expensify-classic/integrations/Greenhouse.md diff --git a/docs/articles/expensify-classic/integrations/HR-integrations/Gusto.md b/docs/articles/expensify-classic/integrations/Gusto.md similarity index 100% rename from docs/articles/expensify-classic/integrations/HR-integrations/Gusto.md rename to docs/articles/expensify-classic/integrations/Gusto.md diff --git a/docs/articles/expensify-classic/integrations/accounting-integrations/Indirect-Accounting-Integrations.md b/docs/articles/expensify-classic/integrations/Indirect-Accounting-Integrations.md similarity index 100% rename from docs/articles/expensify-classic/integrations/accounting-integrations/Indirect-Accounting-Integrations.md rename to docs/articles/expensify-classic/integrations/Indirect-Accounting-Integrations.md diff --git a/docs/articles/expensify-classic/integrations/travel-integrations/Lyft.md b/docs/articles/expensify-classic/integrations/Lyft.md similarity index 100% rename from docs/articles/expensify-classic/integrations/travel-integrations/Lyft.md rename to docs/articles/expensify-classic/integrations/Lyft.md diff --git a/docs/articles/expensify-classic/integrations/travel-integrations/Navan.md b/docs/articles/expensify-classic/integrations/Navan.md similarity index 100% rename from docs/articles/expensify-classic/integrations/travel-integrations/Navan.md rename to docs/articles/expensify-classic/integrations/Navan.md diff --git a/docs/articles/expensify-classic/integrations/accounting-integrations/NetSuite.md b/docs/articles/expensify-classic/integrations/Netsuite/NetSuite.md similarity index 100% rename from docs/articles/expensify-classic/integrations/accounting-integrations/NetSuite.md rename to docs/articles/expensify-classic/integrations/Netsuite/NetSuite.md diff --git a/docs/articles/expensify-classic/integrations/HR-integrations/QuickBooks-Time.md b/docs/articles/expensify-classic/integrations/QuickBooks-Time.md similarity index 100% rename from docs/articles/expensify-classic/integrations/HR-integrations/QuickBooks-Time.md rename to docs/articles/expensify-classic/integrations/QuickBooks-Time.md diff --git a/docs/articles/expensify-classic/integrations/accounting-integrations/QuickBooks-Desktop.md b/docs/articles/expensify-classic/integrations/Quickbooks-Desktop/QuickBooks-Desktop.md similarity index 100% rename from docs/articles/expensify-classic/integrations/accounting-integrations/QuickBooks-Desktop.md rename to docs/articles/expensify-classic/integrations/Quickbooks-Desktop/QuickBooks-Desktop.md diff --git a/docs/articles/expensify-classic/integrations/accounting-integrations/QuickBooks-Online.md b/docs/articles/expensify-classic/integrations/Quickbooks-Online/QuickBooks-Online.md similarity index 100% rename from docs/articles/expensify-classic/integrations/accounting-integrations/QuickBooks-Online.md rename to docs/articles/expensify-classic/integrations/Quickbooks-Online/QuickBooks-Online.md diff --git a/docs/articles/expensify-classic/integrations/HR-integrations/Rippling.md b/docs/articles/expensify-classic/integrations/Rippling.md similarity index 100% rename from docs/articles/expensify-classic/integrations/HR-integrations/Rippling.md rename to docs/articles/expensify-classic/integrations/Rippling.md diff --git a/docs/articles/expensify-classic/integrations/accounting-integrations/Sage-Intacct.md b/docs/articles/expensify-classic/integrations/Sage-Intacct/Sage-Intacct.md similarity index 100% rename from docs/articles/expensify-classic/integrations/accounting-integrations/Sage-Intacct.md rename to docs/articles/expensify-classic/integrations/Sage-Intacct/Sage-Intacct.md diff --git a/docs/articles/expensify-classic/integrations/travel-integrations/TravelPerk.md b/docs/articles/expensify-classic/integrations/TravelPerk.md similarity index 100% rename from docs/articles/expensify-classic/integrations/travel-integrations/TravelPerk.md rename to docs/articles/expensify-classic/integrations/TravelPerk.md diff --git a/docs/articles/expensify-classic/integrations/travel-integrations/Uber.md b/docs/articles/expensify-classic/integrations/Uber.md similarity index 100% rename from docs/articles/expensify-classic/integrations/travel-integrations/Uber.md rename to docs/articles/expensify-classic/integrations/Uber.md diff --git a/docs/articles/expensify-classic/integrations/HR-integrations/Workday.md b/docs/articles/expensify-classic/integrations/Workday.md similarity index 100% rename from docs/articles/expensify-classic/integrations/HR-integrations/Workday.md rename to docs/articles/expensify-classic/integrations/Workday.md diff --git a/docs/articles/expensify-classic/integrations/accounting-integrations/Xero.md b/docs/articles/expensify-classic/integrations/Xero/Xero.md similarity index 100% rename from docs/articles/expensify-classic/integrations/accounting-integrations/Xero.md rename to docs/articles/expensify-classic/integrations/Xero/Xero.md diff --git a/docs/articles/expensify-classic/integrations/HR-integrations/Zenefits.md b/docs/articles/expensify-classic/integrations/Zenefits.md similarity index 100% rename from docs/articles/expensify-classic/integrations/HR-integrations/Zenefits.md rename to docs/articles/expensify-classic/integrations/Zenefits.md diff --git a/docs/expensify-classic/hubs/integrations/HR-integrations.html b/docs/expensify-classic/hubs/connections/accelo.html similarity index 100% rename from docs/expensify-classic/hubs/integrations/HR-integrations.html rename to docs/expensify-classic/hubs/connections/accelo.html diff --git a/docs/expensify-classic/hubs/integrations/accounting-integrations.html b/docs/expensify-classic/hubs/connections/certinia.html similarity index 100% rename from docs/expensify-classic/hubs/integrations/accounting-integrations.html rename to docs/expensify-classic/hubs/connections/certinia.html diff --git a/docs/expensify-classic/hubs/integrations/index.html b/docs/expensify-classic/hubs/connections/index.html similarity index 100% rename from docs/expensify-classic/hubs/integrations/index.html rename to docs/expensify-classic/hubs/connections/index.html diff --git a/docs/expensify-classic/hubs/integrations/other-integrations.html b/docs/expensify-classic/hubs/connections/netsuite.html similarity index 100% rename from docs/expensify-classic/hubs/integrations/other-integrations.html rename to docs/expensify-classic/hubs/connections/netsuite.html diff --git a/docs/expensify-classic/hubs/integrations/travel-integrations.html b/docs/expensify-classic/hubs/connections/quickbooks-desktop.html similarity index 100% rename from docs/expensify-classic/hubs/integrations/travel-integrations.html rename to docs/expensify-classic/hubs/connections/quickbooks-desktop.html diff --git a/docs/expensify-classic/hubs/connections/quickbooks-online.html b/docs/expensify-classic/hubs/connections/quickbooks-online.html new file mode 100644 index 000000000000..86641ee60b7d --- /dev/null +++ b/docs/expensify-classic/hubs/connections/quickbooks-online.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include section.html %} diff --git a/docs/expensify-classic/hubs/connections/sage-intacct.html b/docs/expensify-classic/hubs/connections/sage-intacct.html new file mode 100644 index 000000000000..86641ee60b7d --- /dev/null +++ b/docs/expensify-classic/hubs/connections/sage-intacct.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include section.html %} diff --git a/docs/expensify-classic/hubs/connections/xero.html b/docs/expensify-classic/hubs/connections/xero.html new file mode 100644 index 000000000000..86641ee60b7d --- /dev/null +++ b/docs/expensify-classic/hubs/connections/xero.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include section.html %} From b272b8f0d042e80c797b4e0e9f156c66d9a1c57d Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 16:48:08 +0300 Subject: [PATCH 042/119] rename to connections --- .../expensify-classic/{integrations => connections}/ADP.md | 0 .../{integrations => connections}/Accelo/Accelo.md | 0 .../Additional-Travel-Integrations.md | 0 .../{integrations => connections}/Certinia/Certinia.md | 0 .../expensify-classic/{integrations => connections}/Egencia.md | 0 .../{integrations => connections}/Global-VaTax.md | 0 .../{integrations => connections}/Google-Apps-SSO.md | 0 .../expensify-classic/{integrations => connections}/Greenhouse.md | 0 .../expensify-classic/{integrations => connections}/Gusto.md | 0 .../Indirect-Accounting-Integrations.md | 0 .../expensify-classic/{integrations => connections}/Lyft.md | 0 .../expensify-classic/{integrations => connections}/Navan.md | 0 .../{integrations => connections}/Netsuite/NetSuite.md | 0 .../{integrations => connections}/QuickBooks-Time.md | 0 .../Quickbooks-Desktop/QuickBooks-Desktop.md | 0 .../Quickbooks-Online/QuickBooks-Online.md | 0 .../expensify-classic/{integrations => connections}/Rippling.md | 0 .../{integrations => connections}/Sage-Intacct/Sage-Intacct.md | 0 .../expensify-classic/{integrations => connections}/TravelPerk.md | 0 .../expensify-classic/{integrations => connections}/Uber.md | 0 .../expensify-classic/{integrations => connections}/Workday.md | 0 .../expensify-classic/{integrations => connections}/Xero/Xero.md | 0 .../expensify-classic/{integrations => connections}/Zenefits.md | 0 23 files changed, 0 insertions(+), 0 deletions(-) rename docs/articles/expensify-classic/{integrations => connections}/ADP.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Accelo/Accelo.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Additional-Travel-Integrations.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Certinia/Certinia.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Egencia.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Global-VaTax.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Google-Apps-SSO.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Greenhouse.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Gusto.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Indirect-Accounting-Integrations.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Lyft.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Navan.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Netsuite/NetSuite.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/QuickBooks-Time.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Quickbooks-Desktop/QuickBooks-Desktop.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Quickbooks-Online/QuickBooks-Online.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Rippling.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Sage-Intacct/Sage-Intacct.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/TravelPerk.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Uber.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Workday.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Xero/Xero.md (100%) rename docs/articles/expensify-classic/{integrations => connections}/Zenefits.md (100%) diff --git a/docs/articles/expensify-classic/integrations/ADP.md b/docs/articles/expensify-classic/connections/ADP.md similarity index 100% rename from docs/articles/expensify-classic/integrations/ADP.md rename to docs/articles/expensify-classic/connections/ADP.md diff --git a/docs/articles/expensify-classic/integrations/Accelo/Accelo.md b/docs/articles/expensify-classic/connections/Accelo/Accelo.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Accelo/Accelo.md rename to docs/articles/expensify-classic/connections/Accelo/Accelo.md diff --git a/docs/articles/expensify-classic/integrations/Additional-Travel-Integrations.md b/docs/articles/expensify-classic/connections/Additional-Travel-Integrations.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Additional-Travel-Integrations.md rename to docs/articles/expensify-classic/connections/Additional-Travel-Integrations.md diff --git a/docs/articles/expensify-classic/integrations/Certinia/Certinia.md b/docs/articles/expensify-classic/connections/Certinia/Certinia.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Certinia/Certinia.md rename to docs/articles/expensify-classic/connections/Certinia/Certinia.md diff --git a/docs/articles/expensify-classic/integrations/Egencia.md b/docs/articles/expensify-classic/connections/Egencia.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Egencia.md rename to docs/articles/expensify-classic/connections/Egencia.md diff --git a/docs/articles/expensify-classic/integrations/Global-VaTax.md b/docs/articles/expensify-classic/connections/Global-VaTax.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Global-VaTax.md rename to docs/articles/expensify-classic/connections/Global-VaTax.md diff --git a/docs/articles/expensify-classic/integrations/Google-Apps-SSO.md b/docs/articles/expensify-classic/connections/Google-Apps-SSO.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Google-Apps-SSO.md rename to docs/articles/expensify-classic/connections/Google-Apps-SSO.md diff --git a/docs/articles/expensify-classic/integrations/Greenhouse.md b/docs/articles/expensify-classic/connections/Greenhouse.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Greenhouse.md rename to docs/articles/expensify-classic/connections/Greenhouse.md diff --git a/docs/articles/expensify-classic/integrations/Gusto.md b/docs/articles/expensify-classic/connections/Gusto.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Gusto.md rename to docs/articles/expensify-classic/connections/Gusto.md diff --git a/docs/articles/expensify-classic/integrations/Indirect-Accounting-Integrations.md b/docs/articles/expensify-classic/connections/Indirect-Accounting-Integrations.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Indirect-Accounting-Integrations.md rename to docs/articles/expensify-classic/connections/Indirect-Accounting-Integrations.md diff --git a/docs/articles/expensify-classic/integrations/Lyft.md b/docs/articles/expensify-classic/connections/Lyft.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Lyft.md rename to docs/articles/expensify-classic/connections/Lyft.md diff --git a/docs/articles/expensify-classic/integrations/Navan.md b/docs/articles/expensify-classic/connections/Navan.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Navan.md rename to docs/articles/expensify-classic/connections/Navan.md diff --git a/docs/articles/expensify-classic/integrations/Netsuite/NetSuite.md b/docs/articles/expensify-classic/connections/Netsuite/NetSuite.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Netsuite/NetSuite.md rename to docs/articles/expensify-classic/connections/Netsuite/NetSuite.md diff --git a/docs/articles/expensify-classic/integrations/QuickBooks-Time.md b/docs/articles/expensify-classic/connections/QuickBooks-Time.md similarity index 100% rename from docs/articles/expensify-classic/integrations/QuickBooks-Time.md rename to docs/articles/expensify-classic/connections/QuickBooks-Time.md diff --git a/docs/articles/expensify-classic/integrations/Quickbooks-Desktop/QuickBooks-Desktop.md b/docs/articles/expensify-classic/connections/Quickbooks-Desktop/QuickBooks-Desktop.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Quickbooks-Desktop/QuickBooks-Desktop.md rename to docs/articles/expensify-classic/connections/Quickbooks-Desktop/QuickBooks-Desktop.md diff --git a/docs/articles/expensify-classic/integrations/Quickbooks-Online/QuickBooks-Online.md b/docs/articles/expensify-classic/connections/Quickbooks-Online/QuickBooks-Online.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Quickbooks-Online/QuickBooks-Online.md rename to docs/articles/expensify-classic/connections/Quickbooks-Online/QuickBooks-Online.md diff --git a/docs/articles/expensify-classic/integrations/Rippling.md b/docs/articles/expensify-classic/connections/Rippling.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Rippling.md rename to docs/articles/expensify-classic/connections/Rippling.md diff --git a/docs/articles/expensify-classic/integrations/Sage-Intacct/Sage-Intacct.md b/docs/articles/expensify-classic/connections/Sage-Intacct/Sage-Intacct.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Sage-Intacct/Sage-Intacct.md rename to docs/articles/expensify-classic/connections/Sage-Intacct/Sage-Intacct.md diff --git a/docs/articles/expensify-classic/integrations/TravelPerk.md b/docs/articles/expensify-classic/connections/TravelPerk.md similarity index 100% rename from docs/articles/expensify-classic/integrations/TravelPerk.md rename to docs/articles/expensify-classic/connections/TravelPerk.md diff --git a/docs/articles/expensify-classic/integrations/Uber.md b/docs/articles/expensify-classic/connections/Uber.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Uber.md rename to docs/articles/expensify-classic/connections/Uber.md diff --git a/docs/articles/expensify-classic/integrations/Workday.md b/docs/articles/expensify-classic/connections/Workday.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Workday.md rename to docs/articles/expensify-classic/connections/Workday.md diff --git a/docs/articles/expensify-classic/integrations/Xero/Xero.md b/docs/articles/expensify-classic/connections/Xero/Xero.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Xero/Xero.md rename to docs/articles/expensify-classic/connections/Xero/Xero.md diff --git a/docs/articles/expensify-classic/integrations/Zenefits.md b/docs/articles/expensify-classic/connections/Zenefits.md similarity index 100% rename from docs/articles/expensify-classic/integrations/Zenefits.md rename to docs/articles/expensify-classic/connections/Zenefits.md From ed50d80520d48073a00a62ea34e7c1b11fdc2a0d Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Tue, 16 Jul 2024 15:49:29 +0200 Subject: [PATCH 043/119] Add confirmed translations --- src/languages/es.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index fbc33eb38986..3f06ac7756dd 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3523,7 +3523,7 @@ export default { screenShareRequest: 'Expensify te está invitando a compartir la pantalla', }, search: { - selectMultiple: 'Seleccionar múltiples', + selectMultiple: 'Seleccionar varios', resultsAreLimited: 'Los resultados de búsqueda están limitados.', searchResults: { emptyResults: { @@ -3538,7 +3538,7 @@ export default { unhold: 'Desbloquear', noOptionsAvailable: 'No hay opciones disponibles para el grupo de gastos seleccionado.', }, - offlinePrompt: 'No puedes realizar esta acción ahora mismo porque pareces estar desconectado.', + offlinePrompt: 'No puedes realizar esta acción ahora mismo porque parece que estás desconectado.', }, genericErrorPage: { title: '¡Oh-oh, algo salió mal!', From 3620a7d7d1811608b4566512f0fd8d50d6579f28 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 16:49:40 +0300 Subject: [PATCH 044/119] fix case --- .../expensify-classic/connections/{Accelo => accelo}/Accelo.md | 0 .../connections/{Certinia => certinia}/Certinia.md | 0 .../connections/{Netsuite => netsuite}/NetSuite.md | 0 .../QuickBooks-Desktop.md | 0 .../{Quickbooks-Online => quickbooks-online}/QuickBooks-Online.md | 0 .../connections/{Sage-Intacct => sage-intacct}/Sage-Intacct.md | 0 .../articles/expensify-classic/connections/{Xero => xero}/Xero.md | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename docs/articles/expensify-classic/connections/{Accelo => accelo}/Accelo.md (100%) rename docs/articles/expensify-classic/connections/{Certinia => certinia}/Certinia.md (100%) rename docs/articles/expensify-classic/connections/{Netsuite => netsuite}/NetSuite.md (100%) rename docs/articles/expensify-classic/connections/{Quickbooks-Desktop => quickbooks-desktop}/QuickBooks-Desktop.md (100%) rename docs/articles/expensify-classic/connections/{Quickbooks-Online => quickbooks-online}/QuickBooks-Online.md (100%) rename docs/articles/expensify-classic/connections/{Sage-Intacct => sage-intacct}/Sage-Intacct.md (100%) rename docs/articles/expensify-classic/connections/{Xero => xero}/Xero.md (100%) diff --git a/docs/articles/expensify-classic/connections/Accelo/Accelo.md b/docs/articles/expensify-classic/connections/accelo/Accelo.md similarity index 100% rename from docs/articles/expensify-classic/connections/Accelo/Accelo.md rename to docs/articles/expensify-classic/connections/accelo/Accelo.md diff --git a/docs/articles/expensify-classic/connections/Certinia/Certinia.md b/docs/articles/expensify-classic/connections/certinia/Certinia.md similarity index 100% rename from docs/articles/expensify-classic/connections/Certinia/Certinia.md rename to docs/articles/expensify-classic/connections/certinia/Certinia.md diff --git a/docs/articles/expensify-classic/connections/Netsuite/NetSuite.md b/docs/articles/expensify-classic/connections/netsuite/NetSuite.md similarity index 100% rename from docs/articles/expensify-classic/connections/Netsuite/NetSuite.md rename to docs/articles/expensify-classic/connections/netsuite/NetSuite.md diff --git a/docs/articles/expensify-classic/connections/Quickbooks-Desktop/QuickBooks-Desktop.md b/docs/articles/expensify-classic/connections/quickbooks-desktop/QuickBooks-Desktop.md similarity index 100% rename from docs/articles/expensify-classic/connections/Quickbooks-Desktop/QuickBooks-Desktop.md rename to docs/articles/expensify-classic/connections/quickbooks-desktop/QuickBooks-Desktop.md diff --git a/docs/articles/expensify-classic/connections/Quickbooks-Online/QuickBooks-Online.md b/docs/articles/expensify-classic/connections/quickbooks-online/QuickBooks-Online.md similarity index 100% rename from docs/articles/expensify-classic/connections/Quickbooks-Online/QuickBooks-Online.md rename to docs/articles/expensify-classic/connections/quickbooks-online/QuickBooks-Online.md diff --git a/docs/articles/expensify-classic/connections/Sage-Intacct/Sage-Intacct.md b/docs/articles/expensify-classic/connections/sage-intacct/Sage-Intacct.md similarity index 100% rename from docs/articles/expensify-classic/connections/Sage-Intacct/Sage-Intacct.md rename to docs/articles/expensify-classic/connections/sage-intacct/Sage-Intacct.md diff --git a/docs/articles/expensify-classic/connections/Xero/Xero.md b/docs/articles/expensify-classic/connections/xero/Xero.md similarity index 100% rename from docs/articles/expensify-classic/connections/Xero/Xero.md rename to docs/articles/expensify-classic/connections/xero/Xero.md From 8300dfe859aca0392f8ccb418ab2eb4218509795 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 17:12:57 +0300 Subject: [PATCH 045/119] add configure --- .../connections/accelo/Configure-Accelo.md | 6 ++++++ .../connections/accelo/{Accelo.md => Connect-To-Accelo.md} | 0 .../connections/certinia/Configure-Certinia.md | 6 ++++++ .../certinia/{Certinia.md => Connect-To-Certinia.md} | 0 .../connections/netsuite/Configure-Netsuite.md | 6 ++++++ .../netsuite/{NetSuite.md => Connect-To-NetSuite.md} | 0 .../quickbooks-desktop/Configure-Quickbooks-Desktop.md | 6 ++++++ ...ickBooks-Desktop.md => Connect-To-QuickBooks-Desktop.md} | 0 .../quickbooks-online/Configure-Quickbooks-Online.md | 6 ++++++ ...QuickBooks-Online.md => Connect-To-QuickBooks-Online.md} | 0 .../connections/sage-intacct/Configure-Sage-Intacct.md | 6 ++++++ .../{Sage-Intacct.md => Connect-To-Sage-Intacct.md} | 0 .../expensify-classic/connections/xero/Configure-Xero.md | 6 ++++++ .../connections/xero/{Xero.md => Connect-To-Xero.md} | 0 14 files changed, 42 insertions(+) create mode 100644 docs/articles/expensify-classic/connections/accelo/Configure-Accelo.md rename docs/articles/expensify-classic/connections/accelo/{Accelo.md => Connect-To-Accelo.md} (100%) create mode 100644 docs/articles/expensify-classic/connections/certinia/Configure-Certinia.md rename docs/articles/expensify-classic/connections/certinia/{Certinia.md => Connect-To-Certinia.md} (100%) create mode 100644 docs/articles/expensify-classic/connections/netsuite/Configure-Netsuite.md rename docs/articles/expensify-classic/connections/netsuite/{NetSuite.md => Connect-To-NetSuite.md} (100%) create mode 100644 docs/articles/expensify-classic/connections/quickbooks-desktop/Configure-Quickbooks-Desktop.md rename docs/articles/expensify-classic/connections/quickbooks-desktop/{QuickBooks-Desktop.md => Connect-To-QuickBooks-Desktop.md} (100%) create mode 100644 docs/articles/expensify-classic/connections/quickbooks-online/Configure-Quickbooks-Online.md rename docs/articles/expensify-classic/connections/quickbooks-online/{QuickBooks-Online.md => Connect-To-QuickBooks-Online.md} (100%) create mode 100644 docs/articles/expensify-classic/connections/sage-intacct/Configure-Sage-Intacct.md rename docs/articles/expensify-classic/connections/sage-intacct/{Sage-Intacct.md => Connect-To-Sage-Intacct.md} (100%) create mode 100644 docs/articles/expensify-classic/connections/xero/Configure-Xero.md rename docs/articles/expensify-classic/connections/xero/{Xero.md => Connect-To-Xero.md} (100%) diff --git a/docs/articles/expensify-classic/connections/accelo/Configure-Accelo.md b/docs/articles/expensify-classic/connections/accelo/Configure-Accelo.md new file mode 100644 index 000000000000..26862841b567 --- /dev/null +++ b/docs/articles/expensify-classic/connections/accelo/Configure-Accelo.md @@ -0,0 +1,6 @@ +--- +title: Configure Accelo +description: Configure Accelo +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/accelo/Accelo.md b/docs/articles/expensify-classic/connections/accelo/Connect-To-Accelo.md similarity index 100% rename from docs/articles/expensify-classic/connections/accelo/Accelo.md rename to docs/articles/expensify-classic/connections/accelo/Connect-To-Accelo.md diff --git a/docs/articles/expensify-classic/connections/certinia/Configure-Certinia.md b/docs/articles/expensify-classic/connections/certinia/Configure-Certinia.md new file mode 100644 index 000000000000..0b8245462bb4 --- /dev/null +++ b/docs/articles/expensify-classic/connections/certinia/Configure-Certinia.md @@ -0,0 +1,6 @@ +--- +title: Configure Certinia +description: Configure Certinia +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/certinia/Certinia.md b/docs/articles/expensify-classic/connections/certinia/Connect-To-Certinia.md similarity index 100% rename from docs/articles/expensify-classic/connections/certinia/Certinia.md rename to docs/articles/expensify-classic/connections/certinia/Connect-To-Certinia.md diff --git a/docs/articles/expensify-classic/connections/netsuite/Configure-Netsuite.md b/docs/articles/expensify-classic/connections/netsuite/Configure-Netsuite.md new file mode 100644 index 000000000000..e14a4cab21d6 --- /dev/null +++ b/docs/articles/expensify-classic/connections/netsuite/Configure-Netsuite.md @@ -0,0 +1,6 @@ +--- +title: Configure Netsuite +description: Configure Netsuite +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/netsuite/NetSuite.md b/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md similarity index 100% rename from docs/articles/expensify-classic/connections/netsuite/NetSuite.md rename to docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md diff --git a/docs/articles/expensify-classic/connections/quickbooks-desktop/Configure-Quickbooks-Desktop.md b/docs/articles/expensify-classic/connections/quickbooks-desktop/Configure-Quickbooks-Desktop.md new file mode 100644 index 000000000000..eda92d41e820 --- /dev/null +++ b/docs/articles/expensify-classic/connections/quickbooks-desktop/Configure-Quickbooks-Desktop.md @@ -0,0 +1,6 @@ +--- +title: Configure Quickbooks Desktop +description: Configure Quickbooks Desktop +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/quickbooks-desktop/QuickBooks-Desktop.md b/docs/articles/expensify-classic/connections/quickbooks-desktop/Connect-To-QuickBooks-Desktop.md similarity index 100% rename from docs/articles/expensify-classic/connections/quickbooks-desktop/QuickBooks-Desktop.md rename to docs/articles/expensify-classic/connections/quickbooks-desktop/Connect-To-QuickBooks-Desktop.md diff --git a/docs/articles/expensify-classic/connections/quickbooks-online/Configure-Quickbooks-Online.md b/docs/articles/expensify-classic/connections/quickbooks-online/Configure-Quickbooks-Online.md new file mode 100644 index 000000000000..99e598adb06a --- /dev/null +++ b/docs/articles/expensify-classic/connections/quickbooks-online/Configure-Quickbooks-Online.md @@ -0,0 +1,6 @@ +--- +title: Configure Quickbooks Online +description: Configure Quickbooks Online +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/quickbooks-online/QuickBooks-Online.md b/docs/articles/expensify-classic/connections/quickbooks-online/Connect-To-QuickBooks-Online.md similarity index 100% rename from docs/articles/expensify-classic/connections/quickbooks-online/QuickBooks-Online.md rename to docs/articles/expensify-classic/connections/quickbooks-online/Connect-To-QuickBooks-Online.md diff --git a/docs/articles/expensify-classic/connections/sage-intacct/Configure-Sage-Intacct.md b/docs/articles/expensify-classic/connections/sage-intacct/Configure-Sage-Intacct.md new file mode 100644 index 000000000000..444825973161 --- /dev/null +++ b/docs/articles/expensify-classic/connections/sage-intacct/Configure-Sage-Intacct.md @@ -0,0 +1,6 @@ +--- +title: Configure Sage Intacct +description: Configure Sage Intacct +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/sage-intacct/Sage-Intacct.md b/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md similarity index 100% rename from docs/articles/expensify-classic/connections/sage-intacct/Sage-Intacct.md rename to docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md diff --git a/docs/articles/expensify-classic/connections/xero/Configure-Xero.md b/docs/articles/expensify-classic/connections/xero/Configure-Xero.md new file mode 100644 index 000000000000..b23216c28401 --- /dev/null +++ b/docs/articles/expensify-classic/connections/xero/Configure-Xero.md @@ -0,0 +1,6 @@ +--- +title: Configure Xero +description: Configure Xero +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/xero/Xero.md b/docs/articles/expensify-classic/connections/xero/Connect-To-Xero.md similarity index 100% rename from docs/articles/expensify-classic/connections/xero/Xero.md rename to docs/articles/expensify-classic/connections/xero/Connect-To-Xero.md From 65f476ad33bff5e547fa3e6c999303e055274682 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 17:17:28 +0300 Subject: [PATCH 046/119] add trobleshooting articles --- .../connections/accelo/Accelo-Troubleshooting.md | 6 ++++++ .../connections/certinia/Certinia-Troubleshooting.md | 6 ++++++ .../connections/netsuite/Netsuite-Troubleshooting.md | 6 ++++++ .../Quickbooks-Desktop-Troubleshooting.md | 6 ++++++ .../quickbooks-online/Quickbooks-Online-Troubleshooting.md | 6 ++++++ .../sage-intacct/Sage-Intacct-Troubleshooting.md | 6 ++++++ .../connections/xero/Xero-Troubleshooting.md | 6 ++++++ 7 files changed, 42 insertions(+) create mode 100644 docs/articles/expensify-classic/connections/accelo/Accelo-Troubleshooting.md create mode 100644 docs/articles/expensify-classic/connections/certinia/Certinia-Troubleshooting.md create mode 100644 docs/articles/expensify-classic/connections/netsuite/Netsuite-Troubleshooting.md create mode 100644 docs/articles/expensify-classic/connections/quickbooks-desktop/Quickbooks-Desktop-Troubleshooting.md create mode 100644 docs/articles/expensify-classic/connections/quickbooks-online/Quickbooks-Online-Troubleshooting.md create mode 100644 docs/articles/expensify-classic/connections/sage-intacct/Sage-Intacct-Troubleshooting.md create mode 100644 docs/articles/expensify-classic/connections/xero/Xero-Troubleshooting.md diff --git a/docs/articles/expensify-classic/connections/accelo/Accelo-Troubleshooting.md b/docs/articles/expensify-classic/connections/accelo/Accelo-Troubleshooting.md new file mode 100644 index 000000000000..1044e3326d91 --- /dev/null +++ b/docs/articles/expensify-classic/connections/accelo/Accelo-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Accelo Troubleshooting +description: Accelo Troubleshooting +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/certinia/Certinia-Troubleshooting.md b/docs/articles/expensify-classic/connections/certinia/Certinia-Troubleshooting.md new file mode 100644 index 000000000000..82a2762ee99a --- /dev/null +++ b/docs/articles/expensify-classic/connections/certinia/Certinia-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Certinia Troubleshooting +description: Certinia Troubleshooting +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/netsuite/Netsuite-Troubleshooting.md b/docs/articles/expensify-classic/connections/netsuite/Netsuite-Troubleshooting.md new file mode 100644 index 000000000000..698aaead045b --- /dev/null +++ b/docs/articles/expensify-classic/connections/netsuite/Netsuite-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Netsuite Troubleshooting +description: Netsuite Troubleshooting +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/quickbooks-desktop/Quickbooks-Desktop-Troubleshooting.md b/docs/articles/expensify-classic/connections/quickbooks-desktop/Quickbooks-Desktop-Troubleshooting.md new file mode 100644 index 000000000000..cdbba9ec0b23 --- /dev/null +++ b/docs/articles/expensify-classic/connections/quickbooks-desktop/Quickbooks-Desktop-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Quickbooks Desktop Troubleshooting +description: Quickbooks Desktop Troubleshooting +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/quickbooks-online/Quickbooks-Online-Troubleshooting.md b/docs/articles/expensify-classic/connections/quickbooks-online/Quickbooks-Online-Troubleshooting.md new file mode 100644 index 000000000000..7e58ad83a164 --- /dev/null +++ b/docs/articles/expensify-classic/connections/quickbooks-online/Quickbooks-Online-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Quickbooks Online Troubleshooting +description: Quickbooks Online Troubleshooting +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/sage-intacct/Sage-Intacct-Troubleshooting.md b/docs/articles/expensify-classic/connections/sage-intacct/Sage-Intacct-Troubleshooting.md new file mode 100644 index 000000000000..db341f87e930 --- /dev/null +++ b/docs/articles/expensify-classic/connections/sage-intacct/Sage-Intacct-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Sage Intacct Troubleshooting +description: Sage Intacct Troubleshooting +--- + +# Coming soon diff --git a/docs/articles/expensify-classic/connections/xero/Xero-Troubleshooting.md b/docs/articles/expensify-classic/connections/xero/Xero-Troubleshooting.md new file mode 100644 index 000000000000..98ae5033db50 --- /dev/null +++ b/docs/articles/expensify-classic/connections/xero/Xero-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Xero Troubleshooting +description: Xero Troubleshooting +--- + +# Coming soon From e692dda606820f3d68ff7ffe4bb7061c08dc402e Mon Sep 17 00:00:00 2001 From: James Dean Date: Tue, 16 Jul 2024 10:03:29 -0700 Subject: [PATCH 047/119] Update en.ts --- src/languages/en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index cdfe31ddd051..219dc22ee0e4 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -4040,7 +4040,7 @@ export default { }, cardSection: { title: 'Payment', - subtitle: 'Add a payment card to pay for your Expensify subscription.', + subtitle: 'Add a card to pay for your Expensify subscription.', addCardButton: 'Add payment card', cardNextPayment: ({nextPaymentDate}) => `Your next payment date is ${nextPaymentDate}.`, cardEnding: ({cardNumber}) => `Card ending in ${cardNumber}`, From 6d66a45074b113522ca30d3e6735e7730740cebc Mon Sep 17 00:00:00 2001 From: James Dean Date: Tue, 16 Jul 2024 10:05:39 -0700 Subject: [PATCH 048/119] Update es.ts --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 055dcf043ef4..8f4284bab45b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -4560,7 +4560,7 @@ export default { }, cardSection: { title: 'Pago', - subtitle: 'Añade una tarjeta de pago para abonar tu suscripción a Expensify', + subtitle: 'Añade una tarjeta para abonar tu suscripción a Expensify', addCardButton: 'Añade tarjeta de pago', cardNextPayment: ({nextPaymentDate}) => `Tu próxima fecha de pago es ${nextPaymentDate}.`, cardEnding: ({cardNumber}) => `Tarjeta terminada en ${cardNumber}`, From b201c2d921b3e0f225f0340f59bd545f7e98ecf5 Mon Sep 17 00:00:00 2001 From: James Dean Date: Tue, 16 Jul 2024 10:06:33 -0700 Subject: [PATCH 049/119] Update es.ts --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 8f4284bab45b..bbbb40edb653 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -4560,7 +4560,7 @@ export default { }, cardSection: { title: 'Pago', - subtitle: 'Añade una tarjeta para abonar tu suscripción a Expensify', + subtitle: 'Añade una tarjeta para pagar tu suscripción a Expensify', addCardButton: 'Añade tarjeta de pago', cardNextPayment: ({nextPaymentDate}) => `Tu próxima fecha de pago es ${nextPaymentDate}.`, cardEnding: ({cardNumber}) => `Tarjeta terminada en ${cardNumber}`, From ed217e8209cbb22c551465229e964df6276b613b Mon Sep 17 00:00:00 2001 From: James Dean Date: Tue, 16 Jul 2024 10:07:22 -0700 Subject: [PATCH 050/119] Update es.ts --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index bbbb40edb653..7175756978ab 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -4560,7 +4560,7 @@ export default { }, cardSection: { title: 'Pago', - subtitle: 'Añade una tarjeta para pagar tu suscripción a Expensify', + subtitle: 'Añade una tarjeta para pagar tu suscripción a Expensify.', addCardButton: 'Añade tarjeta de pago', cardNextPayment: ({nextPaymentDate}) => `Tu próxima fecha de pago es ${nextPaymentDate}.`, cardEnding: ({cardNumber}) => `Tarjeta terminada en ${cardNumber}`, From 9de2a2503cd3bf8f9f1423a551cb887ba3659c0a Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 20:13:43 +0300 Subject: [PATCH 051/119] alphabetically order the articles and sections --- docs/_includes/hub.html | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/_includes/hub.html b/docs/_includes/hub.html index 7f1e25243c09..cac0eaeec382 100644 --- a/docs/_includes/hub.html +++ b/docs/_includes/hub.html @@ -12,13 +12,17 @@

{{ hub.description }}

+{% assign sortedSectionsAndArticles = hub.sections | concat: hub.articles | sort: 'title' %} +
- {% for section in hub.sections %} - {% include section-card.html platform=activePlatform hub=hub.href section=section.href title=section.title %} - {% endfor %} - {% for article in hub.articles %} - {% include article-card.html hub=hub.href href=article.href title=article.title platform=activePlatform %} + {% for item in sortedSectionsAndArticles %} + + {% if item.articles %} + {% include section-card.html platform=activePlatform hub=hub.href section=item.href title=item.title %} + {% else %} + {% include article-card.html hub=hub.href href=item.href title=item.title platform=activePlatform %} + {% endif %} {% endfor %}
From 3788291a68cdd614ad8bc8eaa0e83b315f0edf21 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 20:30:05 +0300 Subject: [PATCH 052/119] alphabetically order the articles and sections in LHN --- docs/_includes/lhn-template.html | 50 ++++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/_includes/lhn-template.html b/docs/_includes/lhn-template.html index 32078c1a8de6..d8298aa22aa7 100644 --- a/docs/_includes/lhn-template.html +++ b/docs/_includes/lhn-template.html @@ -33,31 +33,31 @@ {{ hub.title }}
    - {% for section in hub.sections %} -
  • - {% if section.href == activeSection %} - -
      - {% for article in section.articles %} - {% assign article_href = section.href | append: '/' | append: article.href %} - {% include lhn-article-link.html platform=activePlatform hub=hub.href href=article_href title=article.title %} - {% endfor %} -
    - {% else %} - - - {{ section.title }} - - {% endif %} - -
  • - {% endfor %} - - {% for article in hub.articles %} - {% include lhn-article-link.html platform=activePlatform hub=hub.href href=article.href title=article.title %} + {% assign sortedSectionsAndArticles = hub.sections | concat: hub.articles | sort: 'title' %} + {% for item in sortedSectionsAndArticles %} + {% if item.articles %} +
  • + {% if item.href == activeSection %} + +
      + {% for article in item.articles %} + {% assign article_href = item.href | append: '/' | append: article.href %} + {% include lhn-article-link.html platform=activePlatform hub=hub.href href=article_href title=article.title %} + {% endfor %} +
    + {% else %} + + + {{ item.title }} + + {% endif %} +
  • + {% else %} + {% include lhn-article-link.html platform=activePlatform hub=hub.href href=item.href title=item.title %} + {% endif %} {% endfor %}
{% else %} From db4042d434675b33d4dc6dc34cbfcff453257860 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 23:37:11 +0300 Subject: [PATCH 053/119] add redirects for moved articles --- docs/redirects.csv | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/redirects.csv b/docs/redirects.csv index 1a60d52c1749..5cb7d3c1576e 100644 --- a/docs/redirects.csv +++ b/docs/redirects.csv @@ -217,4 +217,31 @@ https://help.expensify.com/articles/new-expensify/expenses/Set-up-your-wallet,ht https://help.expensify.com/articles/new-expensify/expenses/Split-an-expense,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Split-an-expense https://help.expensify.com/articles/new-expensify/expenses/Track-expenses,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Track-expenses https://help.expensify.com/articles/new-expensify/expenses/Unlock-a-Business-Bank-Account,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Unlock-a-Business-Bank-Account -https://help.expensify.com/articles/new-expensify/expenses/Validate-a-Business-Bank-Account,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Validate-a-Business-Bank-Account \ No newline at end of file +https://help.expensify.com/articles/new-expensify/expenses/Validate-a-Business-Bank-Account,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Validate-a-Business-Bank-Account +https://help.expensify.com/expensify-classic/hubs/integrations/HR-integrations,http://127.0.0.1:4000/expensify-classic/hubs/connections +https://help.expensify.com/expensify-classic/hubs/integrations/accounting-integrations,http://127.0.0.1:4000/expensify-classic/hubs/connections +https://help.expensify.com/expensify-classic/hubs/integrations/other-integrations,http://127.0.0.1:4000/expensify-classic/hubs/connections +https://help.expensify.com/expensify-classic/hubs/integrations/travel-integrations,http://127.0.0.1:4000/expensify-classic/hubs/connections +https://help.expensify.com/articles/expensify-classic/integrations/HR-integrations/ADP,http://127.0.0.1:4000/articles/expensify-classic/connections/ADP +https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/Accelo,http://127.0.0.1:4000/expensify-classic/hubs/connections/accelo +https://help.expensify.com/articles/expensify-classic/integrations/travel-integrations/Additional-Travel-Integrations,http://127.0.0.1:4000/articles/expensify-classic/connections/Additional-Travel-Integrations +https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/Certinia,http://127.0.0.1:4000/expensify-classic/hubs/connections/certinia +https://help.expensify.com/articles/expensify-classic/integrations/travel-integrations/Egencia,http://127.0.0.1:4000/articles/expensify-classic/connections/Egencia +https://help.expensify.com/articles/expensify-classic/integrations/travel-integrations/Global-VaTax,http://127.0.0.1:4000/articles/expensify-classic/connections/Global-VaTax +https://help.expensify.com/articles/expensify-classic/integrations/other-integrations/Google-Apps-SSO,http://127.0.0.1:4000/articles/expensify-classic/connections/Google-Apps-SSO +https://help.expensify.com/articles/expensify-classic/integrations/HR-integrations/Greenhouse,http://127.0.0.1:4000/articles/expensify-classic/connections/Greenhouse +https://help.expensify.com/articles/expensify-classic/integrations/HR-integrations/Gusto,http://127.0.0.1:4000/articles/expensify-classic/connections/Gusto +https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/Indirect-Accounting-Integrations,http://127.0.0.1:4000/articles/expensify-classic/connections/Indirect-Accounting-Integrations +https://help.expensify.com/articles/expensify-classic/integrations/travel-integrations/Lyft,http://127.0.0.1:4000/articles/expensify-classic/connections/Lyft +https://help.expensify.com/articles/expensify-classic/integrations/travel-integrations/Navan,http://127.0.0.1:4000/articles/expensify-classic/connections/Navan +https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/NetSuite,http://127.0.0.1:4000/expensify-classic/hubs/connections/netsuite +https://help.expensify.com/articles/expensify-classic/integrations/HR-integrations/QuickBooks-Time,http://127.0.0.1:4000/articles/expensify-classic/connections/QuickBooks-Time +https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/QuickBooks-Desktop,http://127.0.0.1:4000/expensify-classic/hubs/connections/quickbooks-desktop +https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/QuickBooks-Online,http://127.0.0.1:4000/expensify-classic/hubs/connections/quickbooks-online +https://help.expensify.com/articles/expensify-classic/integrations/HR-integrations/Rippling,http://127.0.0.1:4000/articles/expensify-classic/connections/Rippling +https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/Sage-Intacct,http://127.0.0.1:4000/expensify-classic/hubs/connections/sage-intacct +https://help.expensify.com/articles/expensify-classic/integrations/travel-integrations/TravelPerk,http://127.0.0.1:4000/articles/expensify-classic/connections/TravelPerk +https://help.expensify.com/articles/expensify-classic/integrations/travel-integrations/Uber,http://127.0.0.1:4000/articles/expensify-classic/connections/Uber +https://help.expensify.com/articles/expensify-classic/integrations/HR-integrations/Workday,http://127.0.0.1:4000/articles/expensify-classic/connections/Workday +https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/Xero,http://127.0.0.1:4000/expensify-classic/hubs/connections/xero +https://help.expensify.com/articles/expensify-classic/integrations/HR-integrations/Zenefits,http://127.0.0.1:4000/articles/expensify-classic/connections/Zenefits \ No newline at end of file From b9627ad130ba7116cd3917aff2a3c73ab771170c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 16 Jul 2024 23:49:22 +0300 Subject: [PATCH 054/119] rm duplicate --- docs/redirects.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/redirects.csv b/docs/redirects.csv index d39db13cd0d5..a66579076c3b 100644 --- a/docs/redirects.csv +++ b/docs/redirects.csv @@ -217,7 +217,6 @@ https://help.expensify.com/articles/new-expensify/expenses/Set-up-your-wallet,ht https://help.expensify.com/articles/new-expensify/expenses/Split-an-expense,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Split-an-expense https://help.expensify.com/articles/new-expensify/expenses/Track-expenses,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Track-expenses https://help.expensify.com/articles/new-expensify/expenses/Unlock-a-Business-Bank-Account,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Unlock-a-Business-Bank-Account -https://help.expensify.com/articles/new-expensify/expenses/Validate-a-Business-Bank-Account,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Validate-a-Business-Bank-Account https://help.expensify.com/expensify-classic/hubs/integrations/HR-integrations,https://help.expensify.com/expensify-classic/hubs/connections https://help.expensify.com/expensify-classic/hubs/integrations/accounting-integrations,https://help.expensify.com/expensify-classic/hubs/connections https://help.expensify.com/expensify-classic/hubs/integrations/other-integrations,https://help.expensify.com/expensify-classic/hubs/connections From ff1d4320b6550fb8879bd48abe6b00288dfb5943 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 17 Jul 2024 00:18:30 +0300 Subject: [PATCH 055/119] rm unused hubs --- .../hubs/connect-credit-cards/business-bank-accounts.html | 5 ----- .../hubs/connect-credit-cards/deposit-accounts.html | 5 ----- docs/expensify-classic/hubs/expenses/expenses.html | 5 ----- docs/expensify-classic/hubs/expenses/reports.html | 5 ----- .../hubs/getting-started/approved-accountants.html | 5 ----- docs/expensify-classic/hubs/getting-started/support.html | 5 ----- .../hubs/getting-started/tips-and-tricks.html | 5 ----- docs/expensify-classic/hubs/workspaces/reports.html | 5 ----- 8 files changed, 40 deletions(-) delete mode 100644 docs/expensify-classic/hubs/connect-credit-cards/business-bank-accounts.html delete mode 100644 docs/expensify-classic/hubs/connect-credit-cards/deposit-accounts.html delete mode 100644 docs/expensify-classic/hubs/expenses/expenses.html delete mode 100644 docs/expensify-classic/hubs/expenses/reports.html delete mode 100644 docs/expensify-classic/hubs/getting-started/approved-accountants.html delete mode 100644 docs/expensify-classic/hubs/getting-started/support.html delete mode 100644 docs/expensify-classic/hubs/getting-started/tips-and-tricks.html delete mode 100644 docs/expensify-classic/hubs/workspaces/reports.html diff --git a/docs/expensify-classic/hubs/connect-credit-cards/business-bank-accounts.html b/docs/expensify-classic/hubs/connect-credit-cards/business-bank-accounts.html deleted file mode 100644 index 86641ee60b7d..000000000000 --- a/docs/expensify-classic/hubs/connect-credit-cards/business-bank-accounts.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: default ---- - -{% include section.html %} diff --git a/docs/expensify-classic/hubs/connect-credit-cards/deposit-accounts.html b/docs/expensify-classic/hubs/connect-credit-cards/deposit-accounts.html deleted file mode 100644 index 86641ee60b7d..000000000000 --- a/docs/expensify-classic/hubs/connect-credit-cards/deposit-accounts.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: default ---- - -{% include section.html %} diff --git a/docs/expensify-classic/hubs/expenses/expenses.html b/docs/expensify-classic/hubs/expenses/expenses.html deleted file mode 100644 index 86641ee60b7d..000000000000 --- a/docs/expensify-classic/hubs/expenses/expenses.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: default ---- - -{% include section.html %} diff --git a/docs/expensify-classic/hubs/expenses/reports.html b/docs/expensify-classic/hubs/expenses/reports.html deleted file mode 100644 index 86641ee60b7d..000000000000 --- a/docs/expensify-classic/hubs/expenses/reports.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: default ---- - -{% include section.html %} diff --git a/docs/expensify-classic/hubs/getting-started/approved-accountants.html b/docs/expensify-classic/hubs/getting-started/approved-accountants.html deleted file mode 100644 index 86641ee60b7d..000000000000 --- a/docs/expensify-classic/hubs/getting-started/approved-accountants.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: default ---- - -{% include section.html %} diff --git a/docs/expensify-classic/hubs/getting-started/support.html b/docs/expensify-classic/hubs/getting-started/support.html deleted file mode 100644 index 86641ee60b7d..000000000000 --- a/docs/expensify-classic/hubs/getting-started/support.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: default ---- - -{% include section.html %} diff --git a/docs/expensify-classic/hubs/getting-started/tips-and-tricks.html b/docs/expensify-classic/hubs/getting-started/tips-and-tricks.html deleted file mode 100644 index 86641ee60b7d..000000000000 --- a/docs/expensify-classic/hubs/getting-started/tips-and-tricks.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: default ---- - -{% include section.html %} diff --git a/docs/expensify-classic/hubs/workspaces/reports.html b/docs/expensify-classic/hubs/workspaces/reports.html deleted file mode 100644 index 86641ee60b7d..000000000000 --- a/docs/expensify-classic/hubs/workspaces/reports.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: default ---- - -{% include section.html %} From b0cb52f33e963580fb845e76a6774e2f8733ba10 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 17 Jul 2024 01:21:54 +0300 Subject: [PATCH 056/119] add order for rearranging article in custom way --- .../connections/accelo/Accelo-Troubleshooting.md | 1 + .../expensify-classic/connections/accelo/Configure-Accelo.md | 1 + .../expensify-classic/connections/accelo/Connect-To-Accelo.md | 1 + .../expensify-classic/connections/certinia/Configure-Certinia.md | 1 + .../connections/certinia/Connect-To-Certinia.md | 1 + .../connections/netsuite/Connect-To-NetSuite.md | 1 + .../quickbooks-desktop/Connect-To-QuickBooks-Desktop.md | 1 + .../quickbooks-online/Connect-To-QuickBooks-Online.md | 1 + .../connections/sage-intacct/Connect-To-Sage-Intacct.md | 1 + .../expensify-classic/connections/xero/Connect-To-Xero.md | 1 + 10 files changed, 10 insertions(+) diff --git a/docs/articles/expensify-classic/connections/accelo/Accelo-Troubleshooting.md b/docs/articles/expensify-classic/connections/accelo/Accelo-Troubleshooting.md index 1044e3326d91..fd0a6ca59069 100644 --- a/docs/articles/expensify-classic/connections/accelo/Accelo-Troubleshooting.md +++ b/docs/articles/expensify-classic/connections/accelo/Accelo-Troubleshooting.md @@ -1,6 +1,7 @@ --- title: Accelo Troubleshooting description: Accelo Troubleshooting +order: 3 --- # Coming soon diff --git a/docs/articles/expensify-classic/connections/accelo/Configure-Accelo.md b/docs/articles/expensify-classic/connections/accelo/Configure-Accelo.md index 26862841b567..abb14767b196 100644 --- a/docs/articles/expensify-classic/connections/accelo/Configure-Accelo.md +++ b/docs/articles/expensify-classic/connections/accelo/Configure-Accelo.md @@ -1,6 +1,7 @@ --- title: Configure Accelo description: Configure Accelo +order: 2 --- # Coming soon diff --git a/docs/articles/expensify-classic/connections/accelo/Connect-To-Accelo.md b/docs/articles/expensify-classic/connections/accelo/Connect-To-Accelo.md index fffe0abb43aa..96b0a17a1528 100644 --- a/docs/articles/expensify-classic/connections/accelo/Connect-To-Accelo.md +++ b/docs/articles/expensify-classic/connections/accelo/Connect-To-Accelo.md @@ -1,6 +1,7 @@ --- title: Accelo description: Help doc for Accelo integration +order: 1 --- diff --git a/docs/articles/expensify-classic/connections/certinia/Configure-Certinia.md b/docs/articles/expensify-classic/connections/certinia/Configure-Certinia.md index 0b8245462bb4..dc7398c11888 100644 --- a/docs/articles/expensify-classic/connections/certinia/Configure-Certinia.md +++ b/docs/articles/expensify-classic/connections/certinia/Configure-Certinia.md @@ -1,6 +1,7 @@ --- title: Configure Certinia description: Configure Certinia +order: 2 --- # Coming soon diff --git a/docs/articles/expensify-classic/connections/certinia/Connect-To-Certinia.md b/docs/articles/expensify-classic/connections/certinia/Connect-To-Certinia.md index 6c7014827ea6..5e5174a336b3 100644 --- a/docs/articles/expensify-classic/connections/certinia/Connect-To-Certinia.md +++ b/docs/articles/expensify-classic/connections/certinia/Connect-To-Certinia.md @@ -1,6 +1,7 @@ --- title: Certinia description: Guide to connecting Expensify and Certinia FFA and PSA/SRP (formerly known as FinancialForce) +order: 1 --- # Overview [Cetinia](https://use.expensify.com/financialforce) (formerly known as FinancialForce) is a cloud-based software solution that provides a range of financial management and accounting applications built on the Salesforce platform. There are two versions: PSA/SRP and FFA and we support both. diff --git a/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md b/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md index ee116f65a398..3c0e228c923f 100644 --- a/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md +++ b/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md @@ -1,6 +1,7 @@ --- title: NetSuite description: Connect and configure NetSuite directly to Expensify. +order: 1 --- # Overview Expensify's seamless integration with NetSuite enables you to streamline your expense reporting process. This integration allows you to automate the export of reports, tailor your coding preferences, and tap into NetSuite's array of advanced features. By correctly configuring your NetSuite settings in Expensify, you can leverage the connection's settings to automate most of the tasks, making your workflow more efficient. diff --git a/docs/articles/expensify-classic/connections/quickbooks-desktop/Connect-To-QuickBooks-Desktop.md b/docs/articles/expensify-classic/connections/quickbooks-desktop/Connect-To-QuickBooks-Desktop.md index 8fe31f3ec4f4..cd0b23d327d7 100644 --- a/docs/articles/expensify-classic/connections/quickbooks-desktop/Connect-To-QuickBooks-Desktop.md +++ b/docs/articles/expensify-classic/connections/quickbooks-desktop/Connect-To-QuickBooks-Desktop.md @@ -1,6 +1,7 @@ --- title: QuickBooks Desktop description: How to connect Expensify to QuickBooks Desktop and troubleshoot issues. +order: 1 --- # Overview QuickBooks Desktop is an accounting package developed by Intuit. It is designed for small and medium-sized businesses to help them manage their financial and accounting tasks. You can connect Expensify to QuickBooks Desktop to make expense management seamless. diff --git a/docs/articles/expensify-classic/connections/quickbooks-online/Connect-To-QuickBooks-Online.md b/docs/articles/expensify-classic/connections/quickbooks-online/Connect-To-QuickBooks-Online.md index 623e5f1dd997..1d536d7bdb66 100644 --- a/docs/articles/expensify-classic/connections/quickbooks-online/Connect-To-QuickBooks-Online.md +++ b/docs/articles/expensify-classic/connections/quickbooks-online/Connect-To-QuickBooks-Online.md @@ -1,6 +1,7 @@ --- title: QuickBooks Online description: Everything you need to know about using Expensify's direct integration with QuickBooks Online. +order: 1 --- # Overview diff --git a/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md b/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md index 560a65d0d722..369c3aae9fa9 100644 --- a/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md +++ b/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md @@ -1,6 +1,7 @@ --- title: Sage Intacct description: Connect your Expensify workspace with Sage Intacct +order: 1 --- # Overview Expensify’s seamless integration with Sage Intacct allows you to connect using either Role-based permissions or User-based permissions. diff --git a/docs/articles/expensify-classic/connections/xero/Connect-To-Xero.md b/docs/articles/expensify-classic/connections/xero/Connect-To-Xero.md index 9dd479e90cf1..3010d11c2ff1 100644 --- a/docs/articles/expensify-classic/connections/xero/Connect-To-Xero.md +++ b/docs/articles/expensify-classic/connections/xero/Connect-To-Xero.md @@ -1,6 +1,7 @@ --- title: The Xero Integration description: Everything you need to know about Expensify's direct integration with Xero +order: 1 --- # About From 71791462903885530995ddd43fac3037ca321095 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 17 Jul 2024 01:22:10 +0300 Subject: [PATCH 057/119] handle custom order for articles --- .github/scripts/createDocsRoutes.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/scripts/createDocsRoutes.ts b/.github/scripts/createDocsRoutes.ts index fc3f376a1774..a8ac3d511ff9 100644 --- a/.github/scripts/createDocsRoutes.ts +++ b/.github/scripts/createDocsRoutes.ts @@ -5,6 +5,7 @@ import type {ValueOf} from 'type-fest'; type Article = { href: string; title: string; + order?: number; }; type Section = { @@ -60,11 +61,12 @@ function toTitleCase(str: string): string { /** * @param filename - The name of the file */ -function getArticleObj(filename: string): Article { +function getArticleObj(filename: string, order?: number): Article { const href = filename.replace('.md', ''); return { href, title: toTitleCase(href.replaceAll('-', ' ')), + order, }; } @@ -90,6 +92,12 @@ function pushOrCreateEntry(hubs: Hub[], hub: string, } } +function getOrderFromArticleFrontMatter(path: string): number | undefined { + const frontmatter = fs.readFileSync(path, 'utf8').split('---')[1]; + const frontmatterObject = yaml.load(frontmatter) as Record; + return frontmatterObject.order as number | undefined; +} + /** * Add articles and sections to hubs * @param hubs - The hubs inside docs/articles/ for a platform @@ -113,7 +121,8 @@ function createHubsWithArticles(hubs: string[], platformName: ValueOf { - articles.push(getArticleObj(subArticle)); + const order = getOrderFromArticleFrontMatter(`${docsDir}/articles/${platformName}/${hub}/${section}/${subArticle}`); + articles.push(getArticleObj(subArticle, order)); }); pushOrCreateEntry(routeHubs, hub, 'sections', { From ba1050f4ca422c1092a5339a671047c3cef23406 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 17 Jul 2024 01:22:18 +0300 Subject: [PATCH 058/119] handle custom order for articles --- docs/_includes/section.html | 3 ++- .../hubs/bank-accounts-and-payments/payments.html | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 docs/expensify-classic/hubs/bank-accounts-and-payments/payments.html diff --git a/docs/_includes/section.html b/docs/_includes/section.html index 786e7d997462..b6def157e954 100644 --- a/docs/_includes/section.html +++ b/docs/_includes/section.html @@ -15,7 +15,8 @@

- {% for article in section.articles %} + {% assign sortedArticles = section.articles | sort: 'order', 'last' | default: 999 %} + {% for article in sortedArticles %} {% assign article_href = section.href | append: '/' | append: article.href %} {% include article-card.html hub=hub.href href=article_href title=article.title platform=activePlatform %} {% endfor %} diff --git a/docs/expensify-classic/hubs/bank-accounts-and-payments/payments.html b/docs/expensify-classic/hubs/bank-accounts-and-payments/payments.html new file mode 100644 index 000000000000..86641ee60b7d --- /dev/null +++ b/docs/expensify-classic/hubs/bank-accounts-and-payments/payments.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include section.html %} From c86a01b2189076f74ffaa184fec2eb0cebfe070d Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 17:02:59 -0700 Subject: [PATCH 059/119] Fix isActive for the DelaySubmissions toggle --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 372044d4bb12..ae5cc5edeb20 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -128,7 +128,7 @@ function WorkspaceWorkflowsPage({policy, betas, route}: WorkspaceWorkflowsPagePr brickRoadIndicator={hasDelayedSubmissionError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} /> ), - isActive: (policy?.harvesting?.enabled && policy.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT && !hasDelayedSubmissionError) ?? false, + isActive: (policy?.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT && !hasDelayedSubmissionError) ?? false, pendingAction: policy?.pendingFields?.autoReporting, errors: ErrorUtils.getLatestErrorField(policy ?? {}, CONST.POLICY.COLLECTION_KEYS.AUTOREPORTING), onCloseError: () => Policy.clearPolicyErrorField(policy?.id ?? '-1', CONST.POLICY.COLLECTION_KEYS.AUTOREPORTING), From d3fface073cb92a709e48d65b696ed533c79ae15 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 17:13:49 -0700 Subject: [PATCH 060/119] Fix display for manual frequency --- src/libs/PolicyUtils.ts | 22 +++++++++++++++++++ .../workflows/WorkspaceWorkflowsPage.tsx | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index bfce8a91e71a..03f5240a6128 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -340,6 +340,27 @@ function isInstantSubmitEnabled(policy: OnyxInputOrEntry): boolean { return policy?.type === CONST.POLICY.TYPE.FREE || (policy?.autoReporting === true && policy?.autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT); } +/** + * This gets a "corrected" value for autoReportingFrequency. The purpose of this function is to encapsulate some logic around the "immediate" frequency. + * + * - "immediate" is actually not immediate. For that you want "instant". + * - immediate & harvesting.enabled === daily + * - immediate & !harvesting.enabled === manual + */ +function getCorrectedAutoReportingFrequency(policy: OnyxInputOrEntry): ValueOf | undefined { + if (policy?.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE) { + return policy?.autoReportingFrequency; + } + + if (policy?.harvesting?.enabled) { + // this is actually not really "immediate". It's "daily". Surprise! + return CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE; + } + + // "manual" is really just "daily" with harvesting disabled + return CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL; +} + /** * Checks if policy's approval mode is "optional", a.k.a. "Submit & Close" */ @@ -793,6 +814,7 @@ export { isDeletedPolicyEmployee, isFreeGroupPolicy, isInstantSubmitEnabled, + getCorrectedAutoReportingFrequency, isPaidGroupPolicy, isPendingDeletePolicy, isPolicyAdmin, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index ae5cc5edeb20..11c2d370fc3d 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -119,7 +119,7 @@ function WorkspaceWorkflowsPage({policy, betas, route}: WorkspaceWorkflowsPagePr // Instant submit is the equivalent of delayed submissions being turned off, so we show the feature as disabled if the frequency is instant description={ getAutoReportingFrequencyDisplayNames(preferredLocale)[ - (policy?.autoReportingFrequency as AutoReportingFrequencyKey) ?? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.WEEKLY + (PolicyUtils.getCorrectedAutoReportingFrequency(policy) as AutoReportingFrequencyKey) ?? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.WEEKLY ] } shouldShowRightIcon From 9b40a16310bb0b222f38f5ee1ab74af54ada8604 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 17:16:56 -0700 Subject: [PATCH 061/119] Improve comment --- src/libs/PolicyUtils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 03f5240a6128..f57a11203464 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -346,6 +346,8 @@ function isInstantSubmitEnabled(policy: OnyxInputOrEntry): boolean { * - "immediate" is actually not immediate. For that you want "instant". * - immediate & harvesting.enabled === daily * - immediate & !harvesting.enabled === manual + * + * Note that "daily" and "manual" only exist as options for the API, not in the database or Onyx. */ function getCorrectedAutoReportingFrequency(policy: OnyxInputOrEntry): ValueOf | undefined { if (policy?.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE) { From 41c912b86bb6928dd4c65a7df9bee6cc64e9ecc6 Mon Sep 17 00:00:00 2001 From: Rocio Perez-Cano Date: Tue, 16 Jul 2024 20:54:32 -0400 Subject: [PATCH 062/119] Update WS to fix vulnerabilities --- package-lock.json | 1179 +-------------------------------------------- 1 file changed, 16 insertions(+), 1163 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0bf27b50ca8b..7aff2b05b6b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6124,28 +6124,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/console/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/console/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/@jest/console/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -6249,28 +6227,6 @@ } } }, - "node_modules/@jest/core/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/@jest/core/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -6339,86 +6295,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/create-cache-key-function/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/create-cache-key-function/node_modules/@types/yargs": { - "version": "17.0.31", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/create-cache-key-function/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/create-cache-key-function/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/create-cache-key-function/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/create-cache-key-function/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/@jest/create-cache-key-function/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/create-cache-key-function/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/environment": { "version": "29.7.0", "license": "MIT", @@ -6432,86 +6308,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/environment/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/environment/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/environment/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/environment/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/environment/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/@jest/environment/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/environment/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/expect": { "version": "29.6.2", "license": "MIT", @@ -6548,86 +6344,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/fake-timers/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/fake-timers/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/fake-timers/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/@jest/fake-timers/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/fake-timers/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/globals": { "version": "29.5.0", "license": "MIT", @@ -6641,86 +6357,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/globals/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/globals/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/globals/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/globals/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/@jest/globals/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/globals/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/reporters": { "version": "29.4.1", "license": "MIT", @@ -6762,28 +6398,6 @@ } } }, - "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/@jest/reporters/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -6903,86 +6517,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/test-result/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/test-result/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/test-result/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/test-result/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/test-result/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/@jest/test-result/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/test-result/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/test-sequencer": { "version": "29.4.1", "license": "MIT", @@ -7020,28 +6554,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/transform/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/@jest/transform/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -7119,10 +6631,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -7137,10 +6646,7 @@ }, "node_modules/@jest/types/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -7153,10 +6659,7 @@ }, "node_modules/@jest/types/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7170,10 +6673,7 @@ }, "node_modules/@jest/types/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -7183,27 +6683,18 @@ }, "node_modules/@jest/types/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "node_modules/@jest/types/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=8" } }, "node_modules/@jest/types/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -9073,9 +8564,9 @@ } }, "node_modules/@react-native-community/cli-server-api/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "engines": { "node": ">=8.3.0" }, @@ -18210,10 +17701,7 @@ "version": "17.0.32", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "@types/yargs-parser": "*" } @@ -29887,28 +29375,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-circus/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -29999,28 +29465,6 @@ } } }, - "node_modules/jest-cli/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-cli/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -30122,28 +29566,6 @@ } } }, - "node_modules/jest-config/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-config/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-config/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -30297,28 +29719,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-each/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-each/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -30402,28 +29802,6 @@ } } }, - "node_modules/jest-environment-jsdom/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-environment-jsdom/node_modules/acorn": { "version": "8.11.3", "license": "MIT", @@ -30434,47 +29812,6 @@ "node": ">=0.4.0" } }, - "node_modules/jest-environment-jsdom/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-environment-jsdom/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-environment-jsdom/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, "node_modules/jest-environment-jsdom/node_modules/cssstyle": { "version": "2.3.0", "license": "MIT", @@ -30523,13 +29860,6 @@ "node": ">= 6" } }, - "node_modules/jest-environment-jsdom/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-environment-jsdom/node_modules/html-encoding-sniffer": { "version": "3.0.0", "license": "MIT", @@ -30593,16 +29923,6 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/jest-environment-jsdom/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-environment-jsdom/node_modules/tr46": { "version": "3.0.0", "license": "MIT", @@ -30673,86 +29993,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@types/yargs": { - "version": "17.0.31", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-environment-node/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-environment-node/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-environment-node/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/jest-environment-node/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-node/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-expo": { "version": "50.0.1", "license": "MIT", @@ -30820,69 +30060,6 @@ "fsevents": "^2.3.2" } }, - "node_modules/jest-haste-map/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-haste-map/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-haste-map/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-haste-map/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-haste-map/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, "node_modules/jest-haste-map/node_modules/has-flag": { "version": "4.0.0", "license": "MIT", @@ -30916,16 +30093,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest-haste-map/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-leak-detector": { "version": "29.4.1", "license": "MIT", @@ -31026,28 +30193,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-message-util/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-message-util/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -31118,86 +30263,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-mock/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-mock/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-mock/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-mock/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-mock/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/jest-mock/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-mock/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", "license": "MIT", @@ -31337,28 +30402,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runner/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-runner/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -31483,28 +30526,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-runtime/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -31592,28 +30613,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -31696,28 +30695,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-util/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-util/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -31791,28 +30768,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-validate/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -32106,28 +31061,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-watcher/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-watcher/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -32228,86 +31161,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest/node_modules/@jest/types": { - "version": "29.6.3", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest/node_modules/@types/yargs": { - "version": "17.0.24", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest/node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/jest/node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jimp-compact": { "version": "0.16.1", "license": "MIT" @@ -34101,8 +32954,9 @@ } }, "node_modules/metro/node_modules/ws": { - "version": "7.5.9", - "license": "MIT", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "engines": { "node": ">=8.3.0" }, @@ -37958,8 +36812,9 @@ } }, "node_modules/react-native/node_modules/ws": { - "version": "6.2.2", - "license": "MIT", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", "dependencies": { "async-limiter": "~1.0.0" } @@ -38133,10 +36988,6 @@ "react": "^18.2.0" } }, - "node_modules/react-test-renderer/node_modules/react-is": { - "version": "18.2.0", - "license": "MIT" - }, "node_modules/react-test-renderer/node_modules/scheduler": { "version": "0.23.0", "license": "MIT", @@ -43163,9 +42014,10 @@ } }, "node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "7.5.9", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -43927,8 +42779,9 @@ } }, "node_modules/ws": { - "version": "8.16.0", - "license": "MIT", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, From 883e672fe95fc1fe612505481264b79ba3dc1830 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 18:40:36 -0700 Subject: [PATCH 063/119] Fix display issue in list --- .../workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx b/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx index 6f6e5fcff15d..c253ca7a4806 100644 --- a/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx @@ -98,7 +98,7 @@ function WorkspaceAutoReportingFrequencyPage({policy, route}: WorkspaceAutoRepor ); const autoReportingFrequencyItems: WorkspaceAutoReportingFrequencyPageItem[] = Object.keys(getAutoReportingFrequencyDisplayNames(preferredLocale)).map((frequencyKey) => { - const isSelected = policy?.autoReportingFrequency === frequencyKey; + const isSelected = PolicyUtils.getCorrectedAutoReportingFrequency(policy) === frequencyKey; return { text: getAutoReportingFrequencyDisplayNames(preferredLocale)[frequencyKey as AutoReportingFrequencyKey] || '', From 4f737844e20be2d0c3ff5d1cf660d02a2cb07342 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 18:47:48 -0700 Subject: [PATCH 064/119] Fix autoReportingFrequency in setWorkspaceAutoReportingFrequency --- src/libs/NextStepUtils.ts | 3 ++- src/libs/actions/Policy/Policy.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 0ac2878b6857..59f46b429698 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -79,7 +79,8 @@ function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf Date: Tue, 16 Jul 2024 18:49:29 -0700 Subject: [PATCH 065/119] Fix upgradeToCorporate --- src/libs/actions/Policy/Policy.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 916bf483ecae..f96a38db2000 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -3047,8 +3047,11 @@ function upgradeToCorporate(policyID: string, featureName: string) { glCodes: true, ...(PolicyUtils.isInstantSubmitEnabled(policy) && { autoReporting: true, - autoReportingFrequency: CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL, + autoReportingFrequency: CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE, }), + harvesting: { + enabled: false, + }, }, }, ]; @@ -3076,6 +3079,7 @@ function upgradeToCorporate(policyID: string, featureName: string) { glCodes: policy?.glCodes ?? null, autoReporting: policy?.autoReporting ?? null, autoReportingFrequency: policy?.autoReportingFrequency ?? null, + harvesting: policy?.harvesting ?? null, }, }, ]; From d49ad9ad8f6ed612fd63bc3da423d283403229c8 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 18:57:23 -0700 Subject: [PATCH 066/119] Account for harvesting in setWorkspaceAutoReportingFrequency optimistic data --- src/libs/actions/Policy/Policy.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index f96a38db2000..8210134e0a41 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -350,6 +350,11 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf // Recall that the "daily" and "manual" frequencies don't actually exist in Onyx or the DB (see PolicyUtils.getCorrectedAutoReportingFrequency) autoReportingFrequency: frequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL ? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE : frequency, pendingFields: {autoReportingFrequency: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + ...(frequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL && { + harvesting: { + enabled: false, + }, + }), }, }, ]; @@ -360,6 +365,7 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { autoReportingFrequency: policy?.autoReportingFrequency ?? null, + harvesting: policy?.harvesting ?? null, pendingFields: {autoReportingFrequency: null}, errorFields: {autoReportingFrequency: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workflowsDelayedSubmissionPage.autoReportingFrequencyErrorMessage')}, }, From 8b115726a757b64a92de18412ca7c9d24ec9eee5 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 19:01:06 -0700 Subject: [PATCH 067/119] Fix initial focus --- .../WorkspaceAutoReportingFrequencyPage.tsx | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx b/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx index c253ca7a4806..704f1def7ad3 100644 --- a/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx @@ -48,9 +48,11 @@ const getAutoReportingFrequencyDisplayNames = (locale: Locale): AutoReportingFre }); function WorkspaceAutoReportingFrequencyPage({policy, route}: WorkspaceAutoReportingFrequencyPageProps) { + const autoReportingFrequency = PolicyUtils.getCorrectedAutoReportingFrequency(policy); + const {translate, preferredLocale, toLocaleOrdinal} = useLocalize(); const styles = useThemeStyles(); - const [isMonthlyFrequency, setIsMonthlyFrequency] = useState(policy?.autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MONTHLY); + const [isMonthlyFrequency, setIsMonthlyFrequency] = useState(autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MONTHLY); const onSelectAutoReportingFrequency = (item: WorkspaceAutoReportingFrequencyPageItem) => { Policy.setWorkspaceAutoReportingFrequency(policy?.id ?? '-1', item.keyForList as AutoReportingFrequencyKey); @@ -97,16 +99,12 @@ function WorkspaceAutoReportingFrequencyPage({policy, route}: WorkspaceAutoRepor ); - const autoReportingFrequencyItems: WorkspaceAutoReportingFrequencyPageItem[] = Object.keys(getAutoReportingFrequencyDisplayNames(preferredLocale)).map((frequencyKey) => { - const isSelected = PolicyUtils.getCorrectedAutoReportingFrequency(policy) === frequencyKey; - - return { - text: getAutoReportingFrequencyDisplayNames(preferredLocale)[frequencyKey as AutoReportingFrequencyKey] || '', - keyForList: frequencyKey, - isSelected, - footerContent: isMonthlyFrequency && frequencyKey === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MONTHLY ? monthlyFrequencyDetails() : null, - }; - }); + const autoReportingFrequencyItems: WorkspaceAutoReportingFrequencyPageItem[] = Object.keys(getAutoReportingFrequencyDisplayNames(preferredLocale)).map((frequencyKey) => ({ + text: getAutoReportingFrequencyDisplayNames(preferredLocale)[frequencyKey as AutoReportingFrequencyKey] || '', + keyForList: frequencyKey, + isSelected: frequencyKey === autoReportingFrequency, + footerContent: isMonthlyFrequency && frequencyKey === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MONTHLY ? monthlyFrequencyDetails() : null, + })); return ( From c9143de446641c546f4b37d147027bfccab87c28 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 19:04:42 -0700 Subject: [PATCH 068/119] clarify comment --- src/libs/PolicyUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index f57a11203464..17ad47c00313 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -344,8 +344,8 @@ function isInstantSubmitEnabled(policy: OnyxInputOrEntry): boolean { * This gets a "corrected" value for autoReportingFrequency. The purpose of this function is to encapsulate some logic around the "immediate" frequency. * * - "immediate" is actually not immediate. For that you want "instant". - * - immediate & harvesting.enabled === daily - * - immediate & !harvesting.enabled === manual + * - (immediate && harvesting.enabled) === daily + * - (immediate && !harvesting.enabled) === manual * * Note that "daily" and "manual" only exist as options for the API, not in the database or Onyx. */ From 4aa4ea883ec7dd06bf6af019af2ccdd227ed359f Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 19:05:52 -0700 Subject: [PATCH 069/119] clarify another comment --- src/libs/PolicyUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 17ad47c00313..f0eed5375658 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -359,7 +359,7 @@ function getCorrectedAutoReportingFrequency(policy: OnyxInputOrEntry): V return CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE; } - // "manual" is really just "daily" with harvesting disabled + // "manual" is really just "immediate" (aka "daily") with harvesting disabled return CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL; } From 30aa5072e1b07a89d47b2d466c23893345c9e681 Mon Sep 17 00:00:00 2001 From: Skyweb331 Date: Wed, 17 Jul 2024 00:22:38 -0400 Subject: [PATCH 070/119] Bump expensify-common and react-native-live-markdown --- package-lock.json | 24 ++++++++++++------------ package.json | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3076816e9ed4..a1c876249cbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@dotlottie/react-player": "^1.6.3", - "@expensify/react-native-live-markdown": "0.1.103", + "@expensify/react-native-live-markdown": "0.1.105", "@expo/metro-runtime": "~3.1.1", "@formatjs/intl-datetimeformat": "^6.10.0", "@formatjs/intl-listformat": "^7.2.2", @@ -55,7 +55,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "2.0.39", + "expensify-common": "2.0.49", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.11.0", @@ -3785,9 +3785,9 @@ } }, "node_modules/@expensify/react-native-live-markdown": { - "version": "0.1.103", - "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.103.tgz", - "integrity": "sha512-w9jQoxBE9LghfL8UdYbG+8A+CApmER/XMH8N7/bINn7w57+FnnBa5ckPWx6/UYX7OYsmYxSaHJLQkJEXYlDRZg==", + "version": "0.1.105", + "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.105.tgz", + "integrity": "sha512-4cecVQFQQjdszUHtkHVT7sMwKntGCfxH62DJvbpa6H3eTuz3RCHrzWOZBQGRDVpn0aM3nwVgcWZSvNsDvT8Ziw==", "workspaces": [ "parser", "example", @@ -26003,9 +26003,9 @@ } }, "node_modules/expensify-common": { - "version": "2.0.39", - "resolved": "https://registry.npmjs.org/expensify-common/-/expensify-common-2.0.39.tgz", - "integrity": "sha512-HyW7MiS8+ZWO2xye5TSsiKJfIsaGl0M2RlI+txJNF9GWeroA6kaXybTY1Ppq+cS+a7+MU/KMQh7GNnIMrvkf+w==", + "version": "2.0.49", + "resolved": "https://registry.npmjs.org/expensify-common/-/expensify-common-2.0.49.tgz", + "integrity": "sha512-67QbRuR2XEl2RoNLSbyqGWATIbOXPV42azAfs2sqNT6iyWKcOgHUqRkWPhxA0GmSW35lwq66bvgPVsQUfMGCow==", "dependencies": { "awesome-phonenumber": "^5.4.0", "classnames": "2.5.0", @@ -26019,7 +26019,7 @@ "react-dom": "16.12.0", "semver": "^7.6.2", "simply-deferred": "git+https://github.com/Expensify/simply-deferred.git#77a08a95754660c7bd6e0b6979fdf84e8e831bf5", - "ua-parser-js": "^1.0.37" + "ua-parser-js": "^1.0.38" } }, "node_modules/expensify-common/node_modules/react": { @@ -26056,9 +26056,9 @@ } }, "node_modules/expensify-common/node_modules/ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index 02b8ce22cd20..3b8522e2b341 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@dotlottie/react-player": "^1.6.3", - "@expensify/react-native-live-markdown": "0.1.103", + "@expensify/react-native-live-markdown": "0.1.105", "@expo/metro-runtime": "~3.1.1", "@formatjs/intl-datetimeformat": "^6.10.0", "@formatjs/intl-listformat": "^7.2.2", @@ -110,7 +110,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "2.0.39", + "expensify-common": "2.0.49", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.11.0", From 4653dc6acba8c26daab0db9a9387447407759034 Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Wed, 17 Jul 2024 06:47:22 +0200 Subject: [PATCH 071/119] Review fixes --- src/components/Search/SearchListWithHeader.tsx | 15 +++++++++------ src/components/Search/SearchPageHeader.tsx | 12 ++++++------ src/libs/API/types.ts | 4 ++-- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/components/Search/SearchListWithHeader.tsx b/src/components/Search/SearchListWithHeader.tsx index 1c7d3d3f3b07..e639b1fd50c6 100644 --- a/src/components/Search/SearchListWithHeader.tsx +++ b/src/components/Search/SearchListWithHeader.tsx @@ -38,7 +38,7 @@ function mapToItemWithSelectionInfo(item: TransactionListItemType | ReportListIt ? mapToTransactionItemWithSelectionInfo(item, selectedTransactions) : { ...item, - transactions: item.transactions?.map((tranaction) => mapToTransactionItemWithSelectionInfo(tranaction, selectedTransactions)), + transactions: item.transactions?.map((transaction) => mapToTransactionItemWithSelectionInfo(transaction, selectedTransactions)), isSelected: item.transactions.every((transaction) => !!selectedTransactions[transaction.keyForList]?.isSelected), }; } @@ -67,20 +67,23 @@ function SearchListWithHeader( setDeleteExpensesConfirmModalVisible(false); }; - const clearSelectedTransactions = () => setSelectedTransactions({}); + const clearSelectedItems = () => { + setSelectedTransactions({}); + setSelectedReports([]); + }; const handleDeleteExpenses = () => { if (selectedTransactionsToDelete.length === 0) { return; } - clearSelectedTransactions(); + clearSelectedItems(); setDeleteExpensesConfirmModalVisible(false); SearchActions.deleteMoneyRequestOnSearch(hash, selectedTransactionsToDelete); }; useEffect(() => { - clearSelectedTransactions(); + clearSelectedItems(); }, [hash]); const toggleTransaction = useCallback( @@ -160,7 +163,7 @@ function SearchListWithHeader( const isAllSelected = flattenedItems.length === Object.keys(selectedTransactions).length; if (isAllSelected) { - clearSelectedTransactions(); + clearSelectedItems(); return; } @@ -179,7 +182,7 @@ function SearchListWithHeader( <> ; - clearSelectedTransactions?: () => void; + clearSelectedItems?: () => void; hash: number; onSelectDeleteOption?: (itemsToDelete: string[]) => void; isMobileSelectionModeActive?: boolean; @@ -37,7 +37,7 @@ function SearchPageHeader({ query, selectedTransactions = {}, hash, - clearSelectedTransactions, + clearSelectedItems, onSelectDeleteOption, isMobileSelectionModeActive, setIsMobileSelectionModeActive, @@ -75,7 +75,7 @@ function SearchPageHeader({ setOfflineModalOpen?.(); return; } - clearSelectedTransactions?.(); + SearchActions.exportSearchItemsToCSV(query, selectedReports, selectedTransactionsKeys, [activeWorkspaceID ?? '']); }, }, @@ -114,7 +114,7 @@ function SearchPageHeader({ return; } - clearSelectedTransactions?.(); + clearSelectedItems?.(); if (isMobileSelectionModeActive) { setIsMobileSelectionModeActive?.(false); } @@ -137,7 +137,7 @@ function SearchPageHeader({ return; } - clearSelectedTransactions?.(); + clearSelectedItems?.(); if (isMobileSelectionModeActive) { setIsMobileSelectionModeActive?.(false); } @@ -170,7 +170,7 @@ function SearchPageHeader({ selectedTransactions, translate, onSelectDeleteOption, - clearSelectedTransactions, + clearSelectedItems, isMobileSelectionModeActive, hash, setIsMobileSelectionModeActive, diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index c28399c97948..70ff94dfe8b9 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -311,6 +311,7 @@ const WRITE_COMMANDS = { UPDATE_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES_CREDIT_CARD_CHARGE_EXPORT_DEFAULT_VENDOR: 'UpdateSageIntacctNonreimbursableExpensesCreditCardChargeExportDefaultVendor', UPDATE_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES_EXPORT_ACCOUNT: 'UpdateSageIntacctNonreimbursableExpensesExportAccount', UPDATE_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES_EXPORT_VENDOR: 'UpdateSageIntacctNonreimbursableExpensesExportVendor', + EXPORT_SEARCH_ITEMS_TO_CSV: 'ExportSearchToCSV', } as const; type WriteCommand = ValueOf; @@ -628,6 +629,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.UPDATE_SAGE_INTACCT_PROJECTS_MAPPING]: Parameters.UpdateSageIntacctGenericTypeParams<'mapping', SageIntacctMappingValue>; [WRITE_COMMANDS.UPDATE_SAGE_INTACCT_SYNC_TAX_CONFIGURATION]: Parameters.UpdateSageIntacctGenericTypeParams<'enabled', boolean>; [WRITE_COMMANDS.UPDATE_SAGE_INTACCT_USER_DIMENSION]: Parameters.UpdateSageIntacctGenericTypeParams<'dimensions', string>; + [WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV]: Parameters.ExportSearchItemsToCSVParams; }; const READ_COMMANDS = { @@ -679,7 +681,6 @@ const READ_COMMANDS = { OPEN_POLICY_INITIAL_PAGE: 'OpenPolicyInitialPage', SEARCH: 'Search', OPEN_SUBSCRIPTION_PAGE: 'OpenSubscriptionPage', - EXPORT_SEARCH_ITEMS_TO_CSV: 'ExportSearchToCSV', } as const; type ReadCommand = ValueOf; @@ -733,7 +734,6 @@ type ReadCommandParameters = { [READ_COMMANDS.OPEN_POLICY_INITIAL_PAGE]: Parameters.OpenPolicyInitialPageParams; [READ_COMMANDS.SEARCH]: Parameters.SearchParams; [READ_COMMANDS.OPEN_SUBSCRIPTION_PAGE]: null; - [READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV]: Parameters.ExportSearchItemsToCSVParams; }; const SIDE_EFFECT_REQUEST_COMMANDS = { From ae6e2c405097974dfa145a594064605988924074 Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Wed, 17 Jul 2024 06:55:03 +0200 Subject: [PATCH 072/119] Use POST method --- src/libs/actions/Search.ts | 19 ++++++++++++------- src/libs/fileDownload/index.ts | 9 +++++++-- src/libs/fileDownload/types.ts | 4 ++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index f6abb552cde0..05156f5390d9 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -6,6 +6,7 @@ import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ApiUtils from '@libs/ApiUtils'; import fileDownload from '@libs/fileDownload'; import enhanceParameters from '@libs/Network/enhanceParameters'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {SearchTransaction} from '@src/types/onyx/SearchResults'; import * as Report from './Report'; @@ -88,21 +89,25 @@ function deleteMoneyRequestOnSearch(hash: number, transactionIDList: string[]) { type Params = Record; -function exportSearchItemsToCSV(query: string, reportIDList: Array | undefined, transactionIDList: string[], policyIDs: string[]) { +function exportSearchItemsToCSV(query: string, reportIDList: string[] | undefined, transactionIDList: string[], policyIDs: string[]) { const fileName = `Expensify_${query}.csv`; - const finalParameters = enhanceParameters(READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV, { + const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV, { query, reportIDList, transactionIDList, policyIDs, }) as Params; - // Convert finalParameters to a query string - const queryString = Object.entries(finalParameters) - .map(([key, value]) => `${key}=${Array.isArray(value) ? value.join(',') : String(value)}`) - .join('&'); + const formData = new FormData(); + Object.entries(finalParameters).forEach(([key, value]) => { + if (Array.isArray(value)) { + formData.append(key, value.join(',')); + } else { + formData.append(key, String(value)); + } + }); - fileDownload(`${ApiUtils.getCommandURL({command: READ_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV})}${queryString}`, fileName); + fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST); } export {search, createTransactionThread, deleteMoneyRequestOnSearch, holdMoneyRequestOnSearch, unholdMoneyRequestOnSearch, exportSearchItemsToCSV}; diff --git a/src/libs/fileDownload/index.ts b/src/libs/fileDownload/index.ts index b39e65a87f94..8891cf775107 100644 --- a/src/libs/fileDownload/index.ts +++ b/src/libs/fileDownload/index.ts @@ -9,7 +9,7 @@ import type {FileDownload} from './types'; * The function downloads an attachment on web/desktop platforms. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars -const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false) => { +const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false, formData = undefined, requestType = 'get') => { const resolvedUrl = tryResolveUrlFromApiRoot(url); if ( // we have two file download cases that we should allow 1. dowloading attachments 2. downloading Expensify package for Sage Intacct @@ -24,7 +24,12 @@ const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOp return Promise.resolve(); } - return fetch(url) + const fetchOptions: RequestInit = { + method: requestType, + body: formData, + }; + + return fetch(url, fetchOptions) .then((response) => response.blob()) .then((blob) => { // Create blob link to download diff --git a/src/libs/fileDownload/types.ts b/src/libs/fileDownload/types.ts index fcc210c1c42f..d8897331d21c 100644 --- a/src/libs/fileDownload/types.ts +++ b/src/libs/fileDownload/types.ts @@ -1,7 +1,7 @@ import type {Asset} from 'react-native-image-picker'; +import type {RequestType} from '@src/types/onyx/Request'; -type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean) => Promise; - +type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean, formData?: FormData, requestType?: RequestType) => Promise; type ImageResolution = {width: number; height: number}; type GetImageResolution = (url: File | Asset) => Promise; From c4dc4aa78201a5fdcfb837234cc29842ee25db99 Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Wed, 17 Jul 2024 07:00:08 +0200 Subject: [PATCH 073/119] Fix TS --- src/libs/actions/Search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 05156f5390d9..7c7d96bcdde0 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -89,7 +89,7 @@ function deleteMoneyRequestOnSearch(hash: number, transactionIDList: string[]) { type Params = Record; -function exportSearchItemsToCSV(query: string, reportIDList: string[] | undefined, transactionIDList: string[], policyIDs: string[]) { +function exportSearchItemsToCSV(query: string, reportIDList: Array | undefined, transactionIDList: string[], policyIDs: string[]) { const fileName = `Expensify_${query}.csv`; const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV, { From 746fce276c29d8b998f192b91c90e7edcff65ba5 Mon Sep 17 00:00:00 2001 From: Skyweb331 Date: Wed, 17 Jul 2024 01:17:51 -0400 Subject: [PATCH 074/119] update pod lock --- ios/Podfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 50dfc65d07b2..2d096f0f7a69 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1871,7 +1871,7 @@ PODS: - RNGoogleSignin (10.0.1): - GoogleSignIn (~> 7.0) - React-Core - - RNLiveMarkdown (0.1.103): + - RNLiveMarkdown (0.1.105): - glog - hermes-engine - RCT-Folly (= 2022.05.16.00) @@ -1889,9 +1889,9 @@ PODS: - React-utils - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNLiveMarkdown/common (= 0.1.103) + - RNLiveMarkdown/common (= 0.1.105) - Yoga - - RNLiveMarkdown/common (0.1.103): + - RNLiveMarkdown/common (0.1.105): - glog - hermes-engine - RCT-Folly (= 2022.05.16.00) @@ -2614,7 +2614,7 @@ SPEC CHECKSUMS: RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 RNGestureHandler: 74b7b3d06d667ba0bbf41da7718f2607ae0dfe8f RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0 - RNLiveMarkdown: f12157fc91b72e19705c9cc8c98034c4c1669d5a + RNLiveMarkdown: bae86068a0b80cda3d4875ac2a5a398955a94922 RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81 rnmapbox-maps: df8fe93dbd251f25022f4023d31bc04160d4d65c RNPermissions: d2392b754e67bc14491f5b12588bef2864e783f3 From ee834c14f5d90dac7860ca9dfe74514bbd7c1bfa Mon Sep 17 00:00:00 2001 From: Monil Bhavsar Date: Wed, 17 Jul 2024 11:31:24 +0530 Subject: [PATCH 075/119] Run prettier --- src/languages/en.ts | 3 +-- src/languages/es.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index e1358593ec3a..7b6554b0b5d6 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2252,8 +2252,7 @@ export default { }, nonReimbursableExpenses: { label: 'Export company cards as', - description: - 'Set how company card purchases export to Sage Intacct.', + description: 'Set how company card purchases export to Sage Intacct.', values: { [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE]: 'Credit cards', [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Vendor bills', diff --git a/src/languages/es.ts b/src/languages/es.ts index 0813faf391ba..0d8801deee8f 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2293,8 +2293,7 @@ export default { }, nonReimbursableExpenses: { label: 'Exportar tarjetas de empresa como', - description: - 'Establece cómo se exportan las compras con tarjeta de empresa a Sage Intacct.', + description: 'Establece cómo se exportan las compras con tarjeta de empresa a Sage Intacct.', values: { [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE]: 'Tarjetas de crédito', [CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Facturas de proveedores', From f5b529e74d6072ce7af3229f01a88d3291f1c8db Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 23:06:51 -0700 Subject: [PATCH 076/119] Re-enable harvesting if manual reporting is changed to auto reporting --- src/libs/actions/Policy/Policy.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 8210134e0a41..abb4f0b204c3 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -342,6 +342,8 @@ function deleteWorkspace(policyID: string, policyName: string) { function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf) { const policy = getPolicy(policyID); + const wasPolicyManuallyReported = PolicyUtils.getCorrectedAutoReportingFrequency(policy) === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL; + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -355,6 +357,12 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf enabled: false, }, }), + ...(wasPolicyManuallyReported && + frequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL && { + harvesting: { + enabled: true, + }, + }), }, }, ]; From ac5770e92541b19e9b30c99ef37546c0fc3a8954 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 23:24:14 -0700 Subject: [PATCH 077/119] Use types to prevent manual from being saved in Onyx --- src/types/onyx/Policy.ts | 8 ++++++-- tests/unit/NextStepUtilsTest.ts | 4 ++-- tests/utils/collections/policies.ts | 8 +++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index ed10473ecb97..c6ee689fe131 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1352,8 +1352,12 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** Whether the auto reporting is enabled */ autoReporting?: boolean; - /** The scheduled submit frequency set up on this policy */ - autoReportingFrequency?: ValueOf; + /** + * The scheduled submit frequency set up on this policy. + * Note that manual does not exist in the DB and thus should not exist in Onyx, only as a param for the API. + * "manual" really means "immediate" (aka "daily") && harvesting.enabled === false + */ + autoReportingFrequency?: Exclude, typeof CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL>; /** Scheduled submit data */ harvesting?: { diff --git a/tests/unit/NextStepUtilsTest.ts b/tests/unit/NextStepUtilsTest.ts index f92bc7a9dfee..fce66fbb1249 100644 --- a/tests/unit/NextStepUtilsTest.ts +++ b/tests/unit/NextStepUtilsTest.ts @@ -311,9 +311,9 @@ describe('libs/NextStepUtils', () => { ]; return Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { - autoReportingFrequency: CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL, + autoReportingFrequency: CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE, harvesting: { - enabled: true, + enabled: false, }, }).then(() => { const result = NextStepUtils.buildNextStep(report, CONST.REPORT.STATUS_NUM.OPEN); diff --git a/tests/utils/collections/policies.ts b/tests/utils/collections/policies.ts index d34a2f6474b5..47bf996afb7e 100644 --- a/tests/utils/collections/policies.ts +++ b/tests/utils/collections/policies.ts @@ -1,4 +1,5 @@ import {rand, randAvatar, randBoolean, randCurrencyCode, randEmail, randPastDate, randWord} from '@ngneat/falso'; +import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import type {Policy} from '@src/types/onyx'; @@ -9,7 +10,12 @@ export default function createRandomPolicy(index: number): Policy { type: rand(Object.values(CONST.POLICY.TYPE)), autoReporting: randBoolean(), isPolicyExpenseChatEnabled: randBoolean(), - autoReportingFrequency: rand(Object.values(CONST.POLICY.AUTO_REPORTING_FREQUENCIES)), + autoReportingFrequency: rand( + Object.values(CONST.POLICY.AUTO_REPORTING_FREQUENCIES).filter( + (frequency): frequency is Exclude, typeof CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL> => + frequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL, + ), + ), harvesting: { enabled: randBoolean(), }, From 11e86eda68eb85e5a9c38a0ece352f08a69e233e Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 23:27:21 -0700 Subject: [PATCH 078/119] Improve comments --- src/libs/actions/Policy/Policy.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index abb4f0b204c3..996c196ac9d3 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -352,11 +352,16 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf // Recall that the "daily" and "manual" frequencies don't actually exist in Onyx or the DB (see PolicyUtils.getCorrectedAutoReportingFrequency) autoReportingFrequency: frequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL ? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE : frequency, pendingFields: {autoReportingFrequency: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + + // To set the frequency to "manual", we really must set it to "immediate" with harvesting disabled ...(frequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL && { harvesting: { enabled: false, }, }), + + // If the policy was manually reported before, and now will be auto-reported, + // then we must re-enable harvesting ...(wasPolicyManuallyReported && frequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL && { harvesting: { From 30506e454e10cda26bfcc92e70dad1439e1cc20f Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 16 Jul 2024 23:57:11 -0700 Subject: [PATCH 079/119] Upgrade electron-builder --- package-lock.json | 1223 ++++++++++++++++++++++++++++++++++++--------- package.json | 2 +- 2 files changed, 982 insertions(+), 243 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3076816e9ed4..dd40f6caf180 100644 --- a/package-lock.json +++ b/package-lock.json @@ -212,7 +212,7 @@ "diff-so-fancy": "^1.3.0", "dotenv": "^16.0.3", "electron": "^29.4.1", - "electron-builder": "24.13.2", + "electron-builder": "25.0.0", "eslint": "^8.57.0", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-config-expensify": "^2.0.52", @@ -2982,8 +2982,9 @@ }, "node_modules/@develar/schema-utils": { "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" @@ -2998,8 +2999,9 @@ }, "node_modules/@develar/schema-utils/node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3013,16 +3015,18 @@ }, "node_modules/@develar/schema-utils/node_modules/ajv-keywords": { "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/@develar/schema-utils/node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", @@ -3107,9 +3111,10 @@ } }, "node_modules/@electron/asar": { - "version": "3.2.8", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.10.tgz", + "integrity": "sha512-mvBSwIBUeiRscrCeJE1LwctAriBj65eUDm0Pc11iE5gRwzkmsdbS7FnZ1XUWjpSeQWL1L5g12Fc/SchPM9DUOw==", "dev": true, - "license": "MIT", "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", @@ -3124,8 +3129,9 @@ }, "node_modules/@electron/asar/node_modules/commander": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } @@ -3188,9 +3194,10 @@ } }, "node_modules/@electron/notarize": { - "version": "2.2.1", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.3.2.tgz", + "integrity": "sha512-zfayxCe19euNwRycCty1C7lF7snk9YwfRpB5M8GLr1a4ICH63znxaPNAubrMvj0yDvVozqfgsdYpXVUnpWBDpg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", @@ -3201,9 +3208,10 @@ } }, "node_modules/@electron/osx-sign": { - "version": "1.0.5", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.0.tgz", + "integrity": "sha512-TEXhxlYSDRr9JWK5nWdOv5MtuUdaZ412uxIIEQ0hLt80o0HYWtQJBlW5QmrQDMtebzATaOjKG9UfCzLyA90zWQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "compare-version": "^0.1.2", "debug": "^4.3.4", @@ -3222,8 +3230,9 @@ }, "node_modules/@electron/osx-sign/node_modules/fs-extra": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -3235,8 +3244,9 @@ }, "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8.0.0" }, @@ -3244,21 +3254,172 @@ "url": "https://github.com/sponsors/gjtorikian/" } }, + "node_modules/@electron/rebuild": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.6.0.tgz", + "integrity": "sha512-zF4x3QupRU3uNGaP5X1wjpmcjfw1H87kyqZ00Tc3HvriV+4gmOGuvQjGNkrJuXdsApssdNyVwLsy+TaeTGGcVw==", + "dev": true, + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "node-gyp": "^9.0.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/rebuild/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@electron/rebuild/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@electron/rebuild/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@electron/rebuild/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@electron/rebuild/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/rebuild/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@electron/rebuild/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@electron/universal": { - "version": "1.5.1", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz", + "integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==", "dev": true, - "license": "MIT", "dependencies": { - "@electron/asar": "^3.2.1", - "@malept/cross-spawn-promise": "^1.1.0", + "@electron/asar": "^3.2.7", + "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.3.1", - "dir-compare": "^3.0.0", - "fs-extra": "^9.0.1", - "minimatch": "^3.0.4", - "plist": "^3.0.4" + "dir-compare": "^4.2.0", + "fs-extra": "^11.1.1", + "minimatch": "^9.0.3", + "plist": "^3.1.0" }, "engines": { - "node": ">=8.6" + "node": ">=16.4" + } + }, + "node_modules/@electron/universal/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { @@ -7418,7 +7579,9 @@ } }, "node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", + "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", "dev": true, "funding": [ { @@ -7430,18 +7593,18 @@ "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" } ], - "license": "Apache-2.0", "dependencies": { "cross-spawn": "^7.0.1" }, "engines": { - "node": ">= 10" + "node": ">= 12.13.0" } }, "node_modules/@malept/flatpak-bundler": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", + "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.0", @@ -17655,8 +17818,9 @@ }, "node_modules/@types/debug": { "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/ms": "*" } @@ -17743,8 +17907,9 @@ }, "node_modules/@types/fs-extra": { "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -17931,8 +18096,9 @@ }, "node_modules/@types/ms": { "version": "0.7.34", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true }, "node_modules/@types/node": { "version": "20.11.5", @@ -17963,8 +18129,9 @@ }, "node_modules/@types/plist": { "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", + "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "@types/node": "*", @@ -18172,9 +18339,10 @@ "dev": true }, "node_modules/@types/verror": { - "version": "1.10.9", + "version": "1.10.10", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.10.tgz", + "integrity": "sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==", "dev": true, - "license": "MIT", "optional": true }, "node_modules/@types/webpack": { @@ -18947,8 +19115,9 @@ }, "node_modules/7zip-bin": { "version": "5.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", + "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==", + "dev": true }, "node_modules/abab": { "version": "2.0.6", @@ -18956,8 +19125,8 @@ }, "node_modules/abbrev": { "version": "1.1.1", - "license": "ISC", - "optional": true + "devOptional": true, + "license": "ISC" }, "node_modules/abort-controller": { "version": "3.0.0", @@ -19075,6 +19244,18 @@ "node": ">= 6.0.0" } }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dev": true, + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "license": "MIT", @@ -19295,29 +19476,32 @@ } }, "node_modules/app-builder-bin": { - "version": "4.0.0", - "dev": true, - "license": "MIT" + "version": "5.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.4.tgz", + "integrity": "sha512-4MitKmOtfTdMONrtRoiaqJ6HtlVZXgrNX1PNdEzEHSAoXU85x7s+mo0IhAS9K9qgjyTVuLrM1E/HAMp5qGyoOA==", + "dev": true }, "node_modules/app-builder-lib": { - "version": "24.13.2", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-25.0.0.tgz", + "integrity": "sha512-GIx0n/QvbeObY8rQTTp08UPn4pS9xSGZLq6cPRy/CyX/mTNN9pO/uU28MWgqjnYXk0bf/595vzDdAijuDyz5Zw==", "dev": true, - "license": "MIT", "dependencies": { "@develar/schema-utils": "~2.6.5", - "@electron/notarize": "2.2.1", - "@electron/osx-sign": "1.0.5", - "@electron/universal": "1.5.1", + "@electron/notarize": "2.3.2", + "@electron/osx-sign": "1.3.0", + "@electron/rebuild": "3.6.0", + "@electron/universal": "2.0.1", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", + "builder-util": "25.0.0", + "builder-util-runtime": "9.2.5", "chromium-pickle-js": "^0.2.0", "debug": "^4.3.4", "ejs": "^3.1.8", - "electron-publish": "24.13.1", + "electron-publish": "25.0.0", "form-data": "^4.0.0", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", @@ -19325,8 +19509,9 @@ "isbinaryfile": "^5.0.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", - "minimatch": "^5.1.1", - "read-config-file": "6.3.2", + "minimatch": "^10.0.0", + "read-config-file": "6.4.0", + "resedit": "^1.7.0", "sanitize-filename": "^1.6.3", "semver": "^7.3.8", "tar": "^6.1.12", @@ -19336,27 +19521,30 @@ "node": ">=14.0.0" }, "peerDependencies": { - "dmg-builder": "24.13.2", - "electron-builder-squirrel-windows": "24.13.2" + "dmg-builder": "25.0.0", + "electron-builder-squirrel-windows": "25.0.0" } }, "node_modules/app-builder-lib/node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/app-builder-lib/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/app-builder-lib/node_modules/form-data": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -19368,8 +19556,9 @@ }, "node_modules/app-builder-lib/node_modules/fs-extra": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -19381,8 +19570,9 @@ }, "node_modules/app-builder-lib/node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -19391,14 +19581,18 @@ } }, "node_modules/app-builder-lib/node_modules/minimatch": { - "version": "5.1.6", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/app-root-dir": { @@ -19418,13 +19612,14 @@ }, "node_modules/aproba": { "version": "1.2.0", - "license": "ISC", - "optional": true + "devOptional": true, + "license": "ISC" }, "node_modules/archiver": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "archiver-utils": "^2.1.0", @@ -19441,8 +19636,9 @@ }, "node_modules/archiver-utils": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "glob": "^7.1.4", @@ -19462,8 +19658,9 @@ }, "node_modules/archiver/node_modules/readable-stream": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "inherits": "^2.0.3", @@ -19735,8 +19932,9 @@ }, "node_modules/assert-plus": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, - "license": "MIT", "optional": true, "engines": { "node": ">=0.8" @@ -19779,8 +19977,9 @@ }, "node_modules/astral-regex": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "license": "MIT", "optional": true, "engines": { "node": ">=8" @@ -19800,8 +19999,9 @@ }, "node_modules/async-exit-hook": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -20942,13 +21142,15 @@ }, "node_modules/bluebird": { "version": "3.7.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true }, "node_modules/bluebird-lst": { "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", + "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", "dev": true, - "license": "MIT", "dependencies": { "bluebird": "^3.5.5" } @@ -21268,17 +21470,6 @@ "node": "*" } }, - "node_modules/buffer-equal": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/buffer-fill": { "version": "1.0.0", "license": "MIT" @@ -21292,15 +21483,16 @@ "license": "MIT" }, "node_modules/builder-util": { - "version": "24.13.1", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-25.0.0.tgz", + "integrity": "sha512-cI8zIsipo/gciZ5jGEA1qYL5Em1N6cWoNMpeJWZAfOs3H9s5zQWKnAS7rTdlJpsJ88gEmL5/32yeXUF2Uzxw6w==", "dev": true, - "license": "MIT", "dependencies": { "@types/debug": "^4.1.6", "7zip-bin": "~5.2.0", - "app-builder-bin": "4.0.0", + "app-builder-bin": "v5.0.0-alpha.4", "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.2.4", + "builder-util-runtime": "9.2.5", "chalk": "^4.1.2", "cross-spawn": "^7.0.3", "debug": "^4.3.4", @@ -21315,9 +21507,10 @@ } }, "node_modules/builder-util-runtime": { - "version": "9.2.4", + "version": "9.2.5", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.5.tgz", + "integrity": "sha512-HjIDfhvqx/8B3TDN4GbABQcgpewTU4LMRTQPkVpKYV3lsuxEJoIfvg09GyWTNmfVNSUAYf+fbTN//JX4TH20pg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.4", "sax": "^1.2.4" @@ -21328,8 +21521,9 @@ }, "node_modules/builder-util/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -21342,13 +21536,15 @@ }, "node_modules/builder-util/node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/builder-util/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -21362,8 +21558,9 @@ }, "node_modules/builder-util/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -21373,13 +21570,15 @@ }, "node_modules/builder-util/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/builder-util/node_modules/fs-extra": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -21391,16 +21590,18 @@ }, "node_modules/builder-util/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/builder-util/node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -21410,8 +21611,9 @@ }, "node_modules/builder-util/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21804,8 +22006,9 @@ }, "node_modules/chromium-pickle-js": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true }, "node_modules/ci-info": { "version": "3.8.0", @@ -22011,8 +22214,9 @@ }, "node_modules/cli-truncate": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "slice-ansi": "^3.0.0", @@ -22165,8 +22369,8 @@ }, "node_modules/color-support": { "version": "1.1.3", + "devOptional": true, "license": "ISC", - "optional": true, "bin": { "color-support": "bin.js" } @@ -22231,8 +22435,9 @@ }, "node_modules/compare-version": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -22263,8 +22468,9 @@ }, "node_modules/compress-commons": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "buffer-crc32": "^0.2.13", @@ -22278,8 +22484,9 @@ }, "node_modules/compress-commons/node_modules/readable-stream": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "inherits": "^2.0.3", @@ -22444,47 +22651,64 @@ } }, "node_modules/config-file-ts": { - "version": "0.2.6", + "version": "0.2.8-rc1", + "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz", + "integrity": "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==", "dev": true, - "license": "MIT", "dependencies": { - "glob": "^10.3.10", - "typescript": "^5.3.3" + "glob": "^10.3.12", + "typescript": "^5.4.3" } }, "node_modules/config-file-ts/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/config-file-ts/node_modules/glob": { - "version": "10.3.10", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, - "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.17" + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/config-file-ts/node_modules/minimatch": { - "version": "9.0.3", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -22496,9 +22720,10 @@ } }, "node_modules/config-file-ts/node_modules/minipass": { - "version": "7.0.4", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -22587,8 +22812,8 @@ }, "node_modules/console-control-strings": { "version": "1.1.0", - "license": "ISC", - "optional": true + "devOptional": true, + "license": "ISC" }, "node_modules/constants-browserify": { "version": "1.0.0", @@ -22806,8 +23031,9 @@ }, "node_modules/crc": { "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "buffer": "^5.1.0" @@ -22815,8 +23041,9 @@ }, "node_modules/crc-32": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "dev": true, - "license": "Apache-2.0", "peer": true, "bin": { "crc32": "bin/crc32.njs" @@ -22827,8 +23054,9 @@ }, "node_modules/crc32-stream": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "crc-32": "^1.2.0", @@ -22840,8 +23068,9 @@ }, "node_modules/crc32-stream/node_modules/readable-stream": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "inherits": "^2.0.3", @@ -23581,8 +23810,8 @@ }, "node_modules/delegates": { "version": "1.0.0", - "license": "MIT", - "optional": true + "devOptional": true, + "license": "MIT" }, "node_modules/denodeify": { "version": "1.2.1", @@ -23643,8 +23872,8 @@ }, "node_modules/detect-libc": { "version": "2.0.1", + "devOptional": true, "license": "Apache-2.0", - "optional": true, "engines": { "node": ">=8" } @@ -23737,12 +23966,13 @@ "license": "MIT" }, "node_modules/dir-compare": { - "version": "3.3.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", + "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", "dev": true, - "license": "MIT", "dependencies": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " } }, "node_modules/dir-glob": { @@ -23756,13 +23986,14 @@ } }, "node_modules/dmg-builder": { - "version": "24.13.2", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-25.0.0.tgz", + "integrity": "sha512-kXETWCy/JIXS8PHYc8Y0EdSWO02gpf4jleW74hkIp6o9WWTjAdBRw2fAcRBNIEBUJtVHFrgCYsEWh0wKFUB0+A==", "dev": true, - "license": "MIT", "dependencies": { - "app-builder-lib": "24.13.2", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", + "app-builder-lib": "25.0.0", + "builder-util": "25.0.0", + "builder-util-runtime": "9.2.5", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" @@ -23773,13 +24004,15 @@ }, "node_modules/dmg-builder/node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/dmg-builder/node_modules/fs-extra": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -23791,8 +24024,9 @@ }, "node_modules/dmg-builder/node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -23802,8 +24036,9 @@ }, "node_modules/dmg-license": { "version": "1.0.11", + "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", + "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -23827,8 +24062,9 @@ }, "node_modules/dmg-license/node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -23843,8 +24079,9 @@ }, "node_modules/dmg-license/node_modules/json-schema-traverse": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "license": "MIT", "optional": true }, "node_modules/dns-packet": { @@ -23959,20 +24196,31 @@ } }, "node_modules/dotenv": { - "version": "16.3.1", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/dotenv-expand": { - "version": "5.1.0", + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.6.tgz", + "integrity": "sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==", "dev": true, - "license": "BSD-2-Clause" + "dependencies": { + "dotenv": "^16.4.4" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } }, "node_modules/duplexer": { "version": "0.1.2", @@ -24040,19 +24288,20 @@ } }, "node_modules/electron-builder": { - "version": "24.13.2", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-25.0.0.tgz", + "integrity": "sha512-3nEqF6KnoM206mLz1C70VXWCzXmH2boL82wkpgLB1GXgK3dly6ay/cepI+2BmQT4iWkIHeG8qH9bPjPj0hn+1A==", "dev": true, - "license": "MIT", "dependencies": { - "app-builder-lib": "24.13.2", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", + "app-builder-lib": "25.0.0", + "builder-util": "25.0.0", + "builder-util-runtime": "9.2.5", "chalk": "^4.1.2", - "dmg-builder": "24.13.2", + "dmg-builder": "25.0.0", "fs-extra": "^10.1.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", - "read-config-file": "6.3.2", + "read-config-file": "6.4.0", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, @@ -24065,21 +24314,23 @@ } }, "node_modules/electron-builder-squirrel-windows": { - "version": "24.13.2", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-25.0.0.tgz", + "integrity": "sha512-bfARwAdye1UkFQZ7NedHZBcOek2lvDDeg/pCaXT4Nrki7gdwrvVY/Be/QJm7Smc6IR/mviozbL9ykUHQ/FSsbw==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { - "app-builder-lib": "24.13.2", + "app-builder-lib": "25.0.0", "archiver": "^5.3.1", - "builder-util": "24.13.1", + "builder-util": "25.0.0", "fs-extra": "^10.1.0" } }, "node_modules/electron-builder-squirrel-windows/node_modules/fs-extra": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -24168,13 +24419,14 @@ } }, "node_modules/electron-publish": { - "version": "24.13.1", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-25.0.0.tgz", + "integrity": "sha512-8wq3pVLq9bpd/jNKJGIXbeL8B8AovLojtCDkVSuSgrLtxEndqy5JfuadUKPAgbmh1zjholNAHsfHH9FS5yeYAg==", "dev": true, - "license": "MIT", "dependencies": { "@types/fs-extra": "^9.0.11", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", + "builder-util": "25.0.0", + "builder-util-runtime": "9.2.5", "chalk": "^4.1.2", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", @@ -24183,8 +24435,9 @@ }, "node_modules/electron-publish/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -24197,8 +24450,9 @@ }, "node_modules/electron-publish/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -24212,8 +24466,9 @@ }, "node_modules/electron-publish/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -24223,13 +24478,15 @@ }, "node_modules/electron-publish/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/electron-publish/node_modules/fs-extra": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -24241,16 +24498,18 @@ }, "node_modules/electron-publish/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/electron-publish/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -24313,6 +24572,15 @@ "node": ">= 0.8" } }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "license": "MIT", @@ -26381,6 +26649,12 @@ "node": ">=8" } }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, "node_modules/express": { "version": "4.18.1", "license": "MIT", @@ -26544,11 +26818,12 @@ }, "node_modules/extsprintf": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", "dev": true, "engines": [ "node >=0.6.0" ], - "license": "MIT", "optional": true }, "node_modules/fast-deep-equal": { @@ -27797,8 +28072,8 @@ }, "node_modules/has-unicode": { "version": "2.0.1", - "license": "ISC", - "optional": true + "devOptional": true, + "license": "ISC" }, "node_modules/has-value": { "version": "1.0.0", @@ -28024,8 +28299,9 @@ }, "node_modules/hosted-git-info": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -28285,6 +28561,15 @@ "node": ">=10.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/husky": { "version": "1.3.1", "dev": true, @@ -28560,8 +28845,9 @@ }, "node_modules/iconv-corefoundation": { "version": "1.1.7", + "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", + "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -28930,6 +29216,25 @@ "node": ">=0.10.0" } }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, "node_modules/ip-regex": { "version": "2.1.0", "license": "MIT", @@ -29077,8 +29382,9 @@ }, "node_modules/is-ci": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "dev": true, - "license": "MIT", "dependencies": { "ci-info": "^3.2.0" }, @@ -29313,6 +29619,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, "node_modules/is-map": { "version": "2.0.2", "dev": true, @@ -29589,8 +29901,9 @@ }, "node_modules/isbinaryfile": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 18.0.0" }, @@ -32359,6 +32672,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, "node_modules/jsc-android": { "version": "250231.0.0", "license": "BSD-2-Clause" @@ -32707,13 +33026,15 @@ }, "node_modules/lazy-val": { "version": "1.0.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", + "dev": true }, "node_modules/lazystream": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "readable-stream": "^2.0.5" @@ -32932,20 +33253,23 @@ }, "node_modules/lodash.defaults": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/lodash.difference": { "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/lodash.flatten": { "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/lodash.isequal": { @@ -32954,8 +33278,9 @@ }, "node_modules/lodash.isplainobject": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/lodash.memoize": { @@ -32975,8 +33300,9 @@ }, "node_modules/lodash.union": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/log-symbols": { @@ -33344,6 +33670,175 @@ "url": "https://github.com/wojtekmaj/make-event-props?sponsor=1" } }, + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-fetch-happen/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen/node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/makeerror": { "version": "1.0.12", "license": "BSD-3-Clause", @@ -34240,6 +34735,23 @@ "node": ">= 8" } }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, "node_modules/minipass-flush": { "version": "1.0.5", "license": "ISC", @@ -34260,6 +34772,18 @@ "node": ">=8" } }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/minizlib": { "version": "2.1.2", "license": "MIT", @@ -34516,16 +35040,38 @@ "node": ">= 10.13" } }, + "node_modules/node-abi": { + "version": "3.65.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.65.0.tgz", + "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-abort-controller": { "version": "3.1.1", "license": "MIT" }, "node_modules/node-addon-api": { "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", "dev": true, - "license": "MIT", "optional": true }, + "node_modules/node-api-version": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.0.tgz", + "integrity": "sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + } + }, "node_modules/node-dir": { "version": "0.1.17", "license": "MIT", @@ -34583,6 +35129,95 @@ "node": ">= 6.13.0" } }, + "node_modules/node-gyp": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", + "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/node-int64": { "version": "0.4.0", "license": "MIT" @@ -34650,6 +35285,21 @@ "url": "https://github.com/sponsors/antelle" } }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "license": "BSD-2-Clause", @@ -35876,6 +36526,16 @@ "path2d-polyfill": "^2.0.1" } }, + "node_modules/pe-library": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.0.tgz", + "integrity": "sha512-JAmVv2jGxmczplhHO7UoFGJ+pM/yMBpny3vNjwNFuaeQfzKlekQidZ8Ss8EJ0qee8wEQN4lY2IwtWx2oRfMsag==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, "node_modules/peek-stream": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", @@ -36045,14 +36705,24 @@ } }, "node_modules/plist": { - "version": "3.0.6", - "license": "MIT", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", "dependencies": { + "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" }, "engines": { - "node": ">=6" + "node": ">=10.4.0" + } + }, + "node_modules/plist/node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "engines": { + "node": ">=10.0.0" } }, "node_modules/plist/node_modules/xmlbuilder": { @@ -38565,6 +39235,18 @@ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/read-binary-file-arch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", + "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "bin": { + "read-binary-file-arch": "cli.js" + } + }, "node_modules/read-cmd-shim": { "version": "4.0.0", "license": "ISC", @@ -38573,16 +39255,17 @@ } }, "node_modules/read-config-file": { - "version": "6.3.2", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.4.0.tgz", + "integrity": "sha512-uB5QOBeF84PT61GlV11OTV4jUGHAO3iDEOP6v9ygxhG6Bs9PLg7WsjNT6mtIX2G+x8lJTr4ZWNeG6LDTKkNf2Q==", "dev": true, - "license": "MIT", "dependencies": { - "config-file-ts": "^0.2.4", - "dotenv": "^9.0.2", - "dotenv-expand": "^5.1.0", + "config-file-ts": "0.2.8-rc1", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", "js-yaml": "^4.1.0", - "json5": "^2.2.0", - "lazy-val": "^1.0.4" + "json5": "^2.2.3", + "lazy-val": "^1.0.5" }, "engines": { "node": ">=12.0.0" @@ -38590,21 +39273,15 @@ }, "node_modules/read-config-file/node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/read-config-file/node_modules/dotenv": { - "version": "9.0.2", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=10" - } + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/read-config-file/node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -38775,8 +39452,9 @@ }, "node_modules/readdir-glob": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, - "license": "Apache-2.0", "peer": true, "dependencies": { "minimatch": "^5.1.0" @@ -38784,8 +39462,9 @@ }, "node_modules/readdir-glob/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "balanced-match": "^1.0.0" @@ -38793,8 +39472,9 @@ }, "node_modules/readdir-glob/node_modules/minimatch": { "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "license": "ISC", "peer": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -39160,6 +39840,19 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/resedit": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.0.tgz", + "integrity": "sha512-dbsZ0gk5opWPFlKMqvxCrLCuMZUVmsW3yTPT0tT4mYwo5fjQM8c4HMN9ZJt6dRDqDV/78m9SU4rv24PN4NiYaA==", + "dev": true, + "dependencies": { + "pe-library": "^0.4.0" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, "node_modules/reselect": { "version": "4.1.7", "dev": true, @@ -39432,8 +40125,9 @@ }, "node_modules/sanitize-filename": { "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", "dev": true, - "license": "WTFPL OR ISC", "dependencies": { "truncate-utf8-bytes": "^1.0.0" } @@ -39973,8 +40667,9 @@ }, "node_modules/slice-ansi": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "ansi-styles": "^4.0.0", @@ -39987,8 +40682,9 @@ }, "node_modules/slice-ansi/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "color-convert": "^2.0.1" @@ -40002,8 +40698,9 @@ }, "node_modules/slice-ansi/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "color-name": "~1.1.4" @@ -40014,8 +40711,9 @@ }, "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "license": "MIT", "optional": true }, "node_modules/slugify": { @@ -40027,9 +40725,9 @@ }, "node_modules/smart-buffer": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, - "license": "MIT", - "optional": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -40235,6 +40933,34 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/sort-asc": { "version": "0.2.0", "license": "MIT", @@ -40521,8 +41247,9 @@ }, "node_modules/stat-mode": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } @@ -41263,8 +41990,9 @@ }, "node_modules/temp-file": { "version": "3.4.0", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", + "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", "dev": true, - "license": "MIT", "dependencies": { "async-exit-hook": "^2.0.1", "fs-extra": "^10.0.0" @@ -41272,8 +42000,9 @@ }, "node_modules/temp-file/node_modules/fs-extra": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -41615,16 +42344,18 @@ }, "node_modules/tmp": { "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "license": "MIT", "engines": { "node": ">=14.14" } }, "node_modules/tmp-promise": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", "dev": true, - "license": "MIT", "dependencies": { "tmp": "^0.2.0" } @@ -41765,8 +42496,9 @@ }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", "dev": true, - "license": "WTFPL", "dependencies": { "utf8-byte-length": "^1.0.1" } @@ -42571,9 +43303,10 @@ "license": "MIT" }, "node_modules/utf8-byte-length": { - "version": "1.0.4", - "dev": true, - "license": "WTFPL" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "dev": true }, "node_modules/util": { "version": "0.11.1", @@ -42659,8 +43392,9 @@ }, "node_modules/verror": { "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "assert-plus": "^1.0.0", @@ -43788,8 +44522,8 @@ }, "node_modules/wide-align": { "version": "1.1.5", + "devOptional": true, "license": "ISC", - "optional": true, "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -44076,8 +44810,9 @@ }, "node_modules/zip-stream": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "archiver-utils": "^3.0.4", @@ -44090,8 +44825,9 @@ }, "node_modules/zip-stream/node_modules/archiver-utils": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "glob": "^7.2.3", @@ -44111,8 +44847,10 @@ }, "node_modules/zip-stream/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "peer": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -44131,8 +44869,9 @@ }, "node_modules/zip-stream/node_modules/readable-stream": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "inherits": "^2.0.3", diff --git a/package.json b/package.json index 02b8ce22cd20..0a3ed0ea453b 100644 --- a/package.json +++ b/package.json @@ -267,7 +267,7 @@ "diff-so-fancy": "^1.3.0", "dotenv": "^16.0.3", "electron": "^29.4.1", - "electron-builder": "24.13.2", + "electron-builder": "25.0.0", "eslint": "^8.57.0", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-config-expensify": "^2.0.52", From f1d941749d4bd1222e5441572cc69f3dd230f660 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 17 Jul 2024 15:25:53 +0700 Subject: [PATCH 080/119] fix: remove receipt when upload fail --- src/libs/actions/IOU.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index d710c06c0d0d..f24aad9a55a5 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6813,13 +6813,12 @@ function replaceReceipt(transactionID: string, file: File, source: string) { }, }, ]; - const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, value: { - receipt: oldReceipt, + receipt: !isEmptyObject(oldReceipt) ? oldReceipt : null, filename: transaction?.filename, errors: getReceiptError(receiptOptimistic, file.name), }, From 7d6e381bc0789e52d2273b01b02acf8f03d93a71 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 17 Jul 2024 16:28:56 +0800 Subject: [PATCH 081/119] center on map when the waypoint coordinates exist --- src/components/MapView/MapView.tsx | 3 ++- src/components/MapView/MapView.website.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/MapView/MapView.tsx b/src/components/MapView/MapView.tsx index 553be816cf3f..6b2c5cc22220 100644 --- a/src/components/MapView/MapView.tsx +++ b/src/components/MapView/MapView.tsx @@ -157,7 +157,8 @@ const MapView = forwardRef( } }; const centerMap = useCallback(() => { - if (directionCoordinates && directionCoordinates.length > 1) { + const waypointCoordinates = waypoints?.map((waypoint) => waypoint.coordinate) ?? []; + if (waypointCoordinates.length > 1 || ((directionCoordinates ?? []).length) > 1) { const {southWest, northEast} = utils.getBounds(waypoints?.map((waypoint) => waypoint.coordinate) ?? [], directionCoordinates); cameraRef.current?.fitBounds(southWest, northEast, mapPadding, CONST.MAPBOX.ANIMATION_DURATION_ON_CENTER_ME); return; diff --git a/src/components/MapView/MapView.website.tsx b/src/components/MapView/MapView.website.tsx index c8f4e9bb38fc..105a775552aa 100644 --- a/src/components/MapView/MapView.website.tsx +++ b/src/components/MapView/MapView.website.tsx @@ -194,7 +194,8 @@ const MapView = forwardRef( if (!mapRef) { return; } - if (directionCoordinates && directionCoordinates.length > 1) { + const waypointCoordinates = waypoints?.map((waypoint) => waypoint.coordinate) ?? []; + if (waypointCoordinates.length > 1 || ((directionCoordinates ?? []).length) > 1) { const {northEast, southWest} = utils.getBounds(waypoints?.map((waypoint) => waypoint.coordinate) ?? [], directionCoordinates); const map = mapRef?.getMap(); map?.fitBounds([southWest, northEast], {padding: mapPadding, animate: true, duration: CONST.MAPBOX.ANIMATION_DURATION_ON_CENTER_ME}); From a8b76fa16179a3400c2546bdc2c9faf5a9c33e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 17 Jul 2024 10:29:36 +0200 Subject: [PATCH 082/119] pass currentUserAccountID to money report header --- src/pages/home/ReportScreen.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 49897928ffe9..c06fdbf5f86c 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -358,6 +358,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro reportActions={reportActions} shouldUseNarrowLayout={shouldUseNarrowLayout} onBackButtonPress={onBackButtonPress} + currentUserAccountID={currentUserAccountID} /> ); } From 68ab5c62d74de7ca6a7aed695ff83b4b2996d56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 17 Jul 2024 10:30:00 +0200 Subject: [PATCH 083/119] do not show export to integration button if user not an admin or manager --- src/components/MoneyReportHeader.tsx | 17 +++++++++++++++-- .../ReportActionItem/ReportPreview.tsx | 13 +++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 51c64650477a..d47084bc7aba 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -55,11 +55,22 @@ type MoneyReportHeaderProps = { /** Whether we should display the header as in narrow layout */ shouldUseNarrowLayout?: boolean; + /** The accountID of the current user */ + currentUserAccountID: number; + /** Method to trigger when pressing close button of the header */ onBackButtonPress: () => void; }; -function MoneyReportHeader({policy, report: moneyRequestReport, transactionThreadReportID, reportActions, shouldUseNarrowLayout = false, onBackButtonPress}: MoneyReportHeaderProps) { +function MoneyReportHeader({ + policy, + report: moneyRequestReport, + transactionThreadReportID, + reportActions, + shouldUseNarrowLayout = false, + onBackButtonPress, + currentUserAccountID, +}: MoneyReportHeaderProps) { const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReport.chatReportID}`); const [nextStep] = useOnyx(`${ONYXKEYS.COLLECTION.NEXT_STEP}${moneyRequestReport.reportID}`); const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`); @@ -118,7 +129,9 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !allHavePendingRTERViolation; - const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && !!policy; + const isManager = currentUserAccountID === moneyRequestReport?.managerID; + const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; + const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && (isManager || isAdmin); const shouldShowSettlementButton = (shouldShowPayButton || shouldShowApproveButton) && !allHavePendingRTERViolation && !shouldShowExportIntegrationButton; diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 053f2774279e..b9d824375c42 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -37,7 +37,7 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Policy, Report, ReportAction, Transaction, TransactionViolations, UserWallet} from '@src/types/onyx'; +import type {Policy, Report, ReportAction, Session, Transaction, TransactionViolations, UserWallet} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import ExportWithDropdownMenu from './ExportWithDropdownMenu'; import type {PendingMessageProps} from './MoneyRequestPreview/types'; @@ -47,6 +47,8 @@ type ReportPreviewOnyxProps = { /** The policy tied to the expense report */ policy: OnyxEntry; + session: OnyxEntry; + /** ChatReport associated with iouReport */ chatReport: OnyxEntry; @@ -96,6 +98,7 @@ function ReportPreview({ iouReport, policy, iouReportID, + session, policyID, chatReportID, chatReport, @@ -115,6 +118,7 @@ function ReportPreview({ const {canUseViolations} = usePermissions(); const {isOffline} = useNetwork(); + const currentUserAccountID = session?.accountID; const {hasMissingSmartscanFields, areAllRequestsBeingSmartScanned, hasOnlyTransactionsWithPendingRoutes, hasNonReimbursableTransactions} = useMemo( () => ({ hasMissingSmartscanFields: ReportUtils.hasMissingSmartscanFields(iouReportID), @@ -341,7 +345,9 @@ function ReportPreview({ */ const connectedIntegration = PolicyUtils.getConnectedIntegration(policy); - const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration; + const isManager = currentUserAccountID === iouReport?.managerID; + const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; + const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && (isManager || isAdmin); return ( ({ userWallet: { key: ONYXKEYS.USER_WALLET, }, + session: { + key: ONYXKEYS.SESSION, + }, })(ReportPreview); From 27e2e2ee3fec87e2bdfcdccf59e59fcbd667da59 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 17 Jul 2024 17:26:44 +0800 Subject: [PATCH 084/119] prettier --- src/components/MapView/MapView.tsx | 2 +- src/components/MapView/MapView.website.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MapView/MapView.tsx b/src/components/MapView/MapView.tsx index 6b2c5cc22220..57eec0510114 100644 --- a/src/components/MapView/MapView.tsx +++ b/src/components/MapView/MapView.tsx @@ -158,7 +158,7 @@ const MapView = forwardRef( }; const centerMap = useCallback(() => { const waypointCoordinates = waypoints?.map((waypoint) => waypoint.coordinate) ?? []; - if (waypointCoordinates.length > 1 || ((directionCoordinates ?? []).length) > 1) { + if (waypointCoordinates.length > 1 || (directionCoordinates ?? []).length > 1) { const {southWest, northEast} = utils.getBounds(waypoints?.map((waypoint) => waypoint.coordinate) ?? [], directionCoordinates); cameraRef.current?.fitBounds(southWest, northEast, mapPadding, CONST.MAPBOX.ANIMATION_DURATION_ON_CENTER_ME); return; diff --git a/src/components/MapView/MapView.website.tsx b/src/components/MapView/MapView.website.tsx index 105a775552aa..618dd5b24cf5 100644 --- a/src/components/MapView/MapView.website.tsx +++ b/src/components/MapView/MapView.website.tsx @@ -195,7 +195,7 @@ const MapView = forwardRef( return; } const waypointCoordinates = waypoints?.map((waypoint) => waypoint.coordinate) ?? []; - if (waypointCoordinates.length > 1 || ((directionCoordinates ?? []).length) > 1) { + if (waypointCoordinates.length > 1 || (directionCoordinates ?? []).length > 1) { const {northEast, southWest} = utils.getBounds(waypoints?.map((waypoint) => waypoint.coordinate) ?? [], directionCoordinates); const map = mapRef?.getMap(); map?.fitBounds([southWest, northEast], {padding: mapPadding, animate: true, duration: CONST.MAPBOX.ANIMATION_DURATION_ON_CENTER_ME}); From b74a6b1055c45162fb68830c89491945840cc670 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 17 Jul 2024 18:09:56 +0800 Subject: [PATCH 085/119] optimistically remove the hold violation --- src/libs/actions/IOU.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index d710c06c0d0d..40403eded27f 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7060,6 +7060,7 @@ function putOnHold(transactionID: string, comment: string, reportID: string) { */ function unholdRequest(transactionID: string, reportID: string) { const createdReportAction = ReportUtils.buildOptimisticUnHoldReportAction(); + const transactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`]; const optimisticData: OnyxUpdate[] = [ { @@ -7079,6 +7080,11 @@ function unholdRequest(transactionID: string, reportID: string) { }, }, }, + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, + value: transactionViolations?.filter((violation) => violation.name !== CONST.VIOLATIONS.HOLD) ?? [], + }, ]; const successData: OnyxUpdate[] = [ @@ -7103,6 +7109,11 @@ function unholdRequest(transactionID: string, reportID: string) { errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('iou.error.genericUnholdExpenseFailureMessage'), }, }, + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, + value: transactionViolations ?? null, + }, ]; API.write( From 6e9c800675962c54408f0cdfec03844c550865f4 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Wed, 17 Jul 2024 17:54:14 +0700 Subject: [PATCH 086/119] remove reportNameValuePairs argument --- src/libs/ReportUtils.ts | 3 ++- src/pages/home/report/ReportFooter.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index ace8f547b75c..90a0757b5e85 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6138,7 +6138,7 @@ function isMoneyRequestReportPendingDeletion(reportOrID: OnyxEntry | str return parentReportAction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; } -function canUserPerformWriteAction(report: OnyxEntry, reportNameValuePairs?: OnyxEntry) { +function canUserPerformWriteAction(report: OnyxEntry) { const reportErrors = getAddWorkspaceRoomOrChatReportErrors(report); // If the expense report is marked for deletion, let us prevent any further write action. @@ -6146,6 +6146,7 @@ function canUserPerformWriteAction(report: OnyxEntry, reportNameValuePai return false; } + const reportNameValuePairs = getReportNameValuePairs(report?.reportID); return !isArchivedRoom(report, reportNameValuePairs) && isEmptyObject(reportErrors) && report && isAllowedToComment(report) && !isAnonymousUser && canWriteInReport(report); } diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index 8c13b0f8696c..a02b5ca3af44 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -103,7 +103,7 @@ function ReportFooter({ // If a user just signed in and is viewing a public report, optimistically show the composer while loading the report, since they will have write access when the response comes back. const shouldShowComposerOptimistically = !isAnonymousUser && ReportUtils.isPublicRoom(report) && !!reportMetadata?.isLoadingInitialReportActions; - const shouldHideComposer = (!ReportUtils.canUserPerformWriteAction(report, reportNameValuePairs) && !shouldShowComposerOptimistically) || isBlockedFromChat; + const shouldHideComposer = (!ReportUtils.canUserPerformWriteAction(report) && !shouldShowComposerOptimistically) || isBlockedFromChat; const canWriteInReport = ReportUtils.canWriteInReport(report); const isSystemChat = ReportUtils.isSystemChat(report); const isAdminsOnlyPostingRoom = ReportUtils.isAdminsOnlyPostingRoom(report); From 6ea8fc6e49c2c6a88f30eca101358d8c8665c684 Mon Sep 17 00:00:00 2001 From: Dominic <165644294+dominictb@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:47:03 +0700 Subject: [PATCH 087/119] Remove en translation messsage Co-authored-by: Sobit Neupane <073bct543.sobit@pcampus.edu.np> --- src/languages/en.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index ff6b62cc27b7..b431531bc854 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -787,7 +787,6 @@ export default { atLeastTwoDifferentWaypoints: 'Please enter at least two different addresses.', splitExpenseMultipleParticipantsErrorMessage: 'An expense cannot be split between a workspace and other members. Please update your selection.', invalidMerchant: 'Please enter a correct merchant.', - workspaceNotAccessible: 'The workspace you selected is no longer accessible, possibly because it has been deleted or you no longer have access to it.', }, waitingOnEnabledWallet: ({submitterDisplayName}: WaitingOnBankAccountParams) => `started settling up. Payment is on hold until ${submitterDisplayName} enables their wallet.`, enableWallet: 'Enable wallet', From d71f595f81b501a7c29745797b94acc14facdca1 Mon Sep 17 00:00:00 2001 From: Dominic <165644294+dominictb@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:47:42 +0700 Subject: [PATCH 088/119] Remove es translation message Co-authored-by: Sobit Neupane <073bct543.sobit@pcampus.edu.np> --- src/languages/es.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index ede5e7c6391c..6c5841e2a7d6 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -785,7 +785,6 @@ export default { atLeastTwoDifferentWaypoints: 'Por favor, introduce al menos dos direcciones diferentes.', splitExpenseMultipleParticipantsErrorMessage: 'Solo puedes dividir un gasto entre un único espacio de trabajo o con miembros individuales. Por favor, actualiza tu selección.', invalidMerchant: 'Por favor, introduce un comerciante correcto.', - workspaceNotAccessible: 'El espacio de trabajo que seleccionaste ya no está accesible, posiblemente porque ha sido eliminado o ya no tienes acceso a él.', }, waitingOnEnabledWallet: ({submitterDisplayName}: WaitingOnBankAccountParams) => `inició el pago, pero no se procesará hasta que ${submitterDisplayName} active su billetera`, enableWallet: 'Habilitar billetera', From f3b343763f922cd3f38c0615636df423a7fccbf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 17 Jul 2024 14:53:23 +0200 Subject: [PATCH 089/119] remove the manager check --- src/components/MoneyReportHeader.tsx | 16 ++-------------- .../ReportActionItem/ReportPreview.tsx | 10 +--------- src/pages/home/ReportScreen.tsx | 1 - 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index d47084bc7aba..1acee187c67b 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -55,22 +55,11 @@ type MoneyReportHeaderProps = { /** Whether we should display the header as in narrow layout */ shouldUseNarrowLayout?: boolean; - /** The accountID of the current user */ - currentUserAccountID: number; - /** Method to trigger when pressing close button of the header */ onBackButtonPress: () => void; }; -function MoneyReportHeader({ - policy, - report: moneyRequestReport, - transactionThreadReportID, - reportActions, - shouldUseNarrowLayout = false, - onBackButtonPress, - currentUserAccountID, -}: MoneyReportHeaderProps) { +function MoneyReportHeader({policy, report: moneyRequestReport, transactionThreadReportID, reportActions, shouldUseNarrowLayout = false, onBackButtonPress}: MoneyReportHeaderProps) { const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReport.chatReportID}`); const [nextStep] = useOnyx(`${ONYXKEYS.COLLECTION.NEXT_STEP}${moneyRequestReport.reportID}`); const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`); @@ -129,9 +118,8 @@ function MoneyReportHeader({ const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !allHavePendingRTERViolation; - const isManager = currentUserAccountID === moneyRequestReport?.managerID; const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; - const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && (isManager || isAdmin); + const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && isAdmin; const shouldShowSettlementButton = (shouldShowPayButton || shouldShowApproveButton) && !allHavePendingRTERViolation && !shouldShowExportIntegrationButton; diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index b9d824375c42..ed64a088bea9 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -47,8 +47,6 @@ type ReportPreviewOnyxProps = { /** The policy tied to the expense report */ policy: OnyxEntry; - session: OnyxEntry; - /** ChatReport associated with iouReport */ chatReport: OnyxEntry; @@ -98,7 +96,6 @@ function ReportPreview({ iouReport, policy, iouReportID, - session, policyID, chatReportID, chatReport, @@ -118,7 +115,6 @@ function ReportPreview({ const {canUseViolations} = usePermissions(); const {isOffline} = useNetwork(); - const currentUserAccountID = session?.accountID; const {hasMissingSmartscanFields, areAllRequestsBeingSmartScanned, hasOnlyTransactionsWithPendingRoutes, hasNonReimbursableTransactions} = useMemo( () => ({ hasMissingSmartscanFields: ReportUtils.hasMissingSmartscanFields(iouReportID), @@ -345,9 +341,8 @@ function ReportPreview({ */ const connectedIntegration = PolicyUtils.getConnectedIntegration(policy); - const isManager = currentUserAccountID === iouReport?.managerID; const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; - const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && (isManager || isAdmin); + const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && isAdmin; return ( ({ userWallet: { key: ONYXKEYS.USER_WALLET, }, - session: { - key: ONYXKEYS.SESSION, - }, })(ReportPreview); diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index c06fdbf5f86c..49897928ffe9 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -358,7 +358,6 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro reportActions={reportActions} shouldUseNarrowLayout={shouldUseNarrowLayout} onBackButtonPress={onBackButtonPress} - currentUserAccountID={currentUserAccountID} /> ); } From d70cf3bcc6c5c82ecb6e015e87bd468a89c93854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 17 Jul 2024 15:17:48 +0200 Subject: [PATCH 090/119] fix lint --- src/components/ReportActionItem/ReportPreview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index ed64a088bea9..ae6ace23c64e 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -37,7 +37,7 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Policy, Report, ReportAction, Session, Transaction, TransactionViolations, UserWallet} from '@src/types/onyx'; +import type {Policy, Report, ReportAction, Transaction, TransactionViolations, UserWallet} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import ExportWithDropdownMenu from './ExportWithDropdownMenu'; import type {PendingMessageProps} from './MoneyRequestPreview/types'; From fa2ccf6578df78e17234facdc8dfb194fe12bcea Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Wed, 17 Jul 2024 12:37:07 -0300 Subject: [PATCH 091/119] adding modal for download error and removing download option outside web --- .../SearchActionOptionsUtils.native.tsx | 8 +++++ .../Search/SearchActionOptionsUtils.tsx | 17 ++++++++++ .../Search/SearchListWithHeader.tsx | 11 ++++++ src/components/Search/SearchPageHeader.tsx | 34 +++++++++++-------- src/languages/en.ts | 2 ++ src/languages/es.ts | 2 ++ src/libs/actions/Search.ts | 4 +-- src/libs/fileDownload/index.ts | 10 ++++-- src/libs/fileDownload/types.ts | 2 +- 9 files changed, 69 insertions(+), 21 deletions(-) create mode 100644 src/components/Search/SearchActionOptionsUtils.native.tsx create mode 100644 src/components/Search/SearchActionOptionsUtils.tsx diff --git a/src/components/Search/SearchActionOptionsUtils.native.tsx b/src/components/Search/SearchActionOptionsUtils.native.tsx new file mode 100644 index 000000000000..8b6b33c1936e --- /dev/null +++ b/src/components/Search/SearchActionOptionsUtils.native.tsx @@ -0,0 +1,8 @@ +import type {DropdownOption} from "@components/ButtonWithDropdownMenu/types"; +import {SearchHeaderOptionValue} from "@components/Search/SearchPageHeader"; + +function getDownloadOption(): DropdownOption | undefined { + return undefined; +} + +export default getDownloadOption; diff --git a/src/components/Search/SearchActionOptionsUtils.tsx b/src/components/Search/SearchActionOptionsUtils.tsx new file mode 100644 index 000000000000..60a7b3431ba7 --- /dev/null +++ b/src/components/Search/SearchActionOptionsUtils.tsx @@ -0,0 +1,17 @@ +import * as Expensicons from "@components/Icon/Expensicons"; +import CONST from "@src/CONST"; +import type {DropdownOption} from "@components/ButtonWithDropdownMenu/types"; +import {SearchHeaderOptionValue} from "@components/Search/SearchPageHeader"; + + +function getDownloadOption(text: string, onSelected?: () => void): DropdownOption { + return { + icon: Expensicons.Download, + text, + value: CONST.SEARCH.BULK_ACTION_TYPES.EXPORT, + shouldCloseModalOnSelect: true, + onSelected + } +} + +export default getDownloadOption; diff --git a/src/components/Search/SearchListWithHeader.tsx b/src/components/Search/SearchListWithHeader.tsx index e639b1fd50c6..25522d84fbf6 100644 --- a/src/components/Search/SearchListWithHeader.tsx +++ b/src/components/Search/SearchListWithHeader.tsx @@ -56,6 +56,7 @@ function SearchListWithHeader( const [selectedTransactionsToDelete, setSelectedTransactionsToDelete] = useState([]); const [deleteExpensesConfirmModalVisible, setDeleteExpensesConfirmModalVisible] = useState(false); const [offlineModalVisible, setOfflineModalVisible] = useState(false); + const [downloadErrorModalVisible, setDownloadErrorModalVisible] = useState(false); const handleOnSelectDeleteOption = (itemsToDelete: string[]) => { setSelectedTransactionsToDelete(itemsToDelete); @@ -190,6 +191,7 @@ function SearchListWithHeader( setIsMobileSelectionModeActive={setIsMobileSelectionModeActive} selectedReports={selectedReports} setOfflineModalOpen={() => setOfflineModalVisible(true)} + setDownloadErrorModalOpen={() => setDownloadErrorModalVisible(true)} /> // eslint-disable-next-line react/jsx-props-no-spreading @@ -222,6 +224,15 @@ function SearchListWithHeader( isVisible={offlineModalVisible} onClose={() => setOfflineModalVisible(false)} /> + setDownloadErrorModalVisible(false)} + secondOptionText={translate('common.buttonConfirm')} + isVisible={downloadErrorModalVisible} + onClose={() => setDownloadErrorModalVisible(false)} + /> void; setOfflineModalOpen?: () => void; + setDownloadErrorModalOpen?: () => void; }; type SearchHeaderOptionValue = DeepValueOf | undefined; @@ -42,6 +44,7 @@ function SearchPageHeader({ isMobileSelectionModeActive, setIsMobileSelectionModeActive, setOfflineModalOpen, + setDownloadErrorModalOpen, selectedReports, }: SearchPageHeaderProps) { const {translate} = useLocalize(); @@ -64,22 +67,23 @@ function SearchPageHeader({ return []; } - const options: Array> = [ - { - icon: Expensicons.Download, - text: translate('common.download'), - value: CONST.SEARCH.BULK_ACTION_TYPES.EXPORT, - shouldCloseModalOnSelect: true, - onSelected: () => { - if (isOffline) { - setOfflineModalOpen?.(); - return; - } + const options: Array> = []; - SearchActions.exportSearchItemsToCSV(query, selectedReports, selectedTransactionsKeys, [activeWorkspaceID ?? '']); - }, - }, - ]; + // Because of some problems with the lib we use for download on native we are only enabling download for web, we should remove the SearchActionOptionsUtils files when https://github.com/Expensify/App/issues/45511 is done + const downloadOption = getDownloadOption(translate('common.download'), () => { + if (isOffline) { + setOfflineModalOpen?.(); + return; + } + + SearchActions.exportSearchItemsToCSV(query, selectedReports, selectedTransactionsKeys, [activeWorkspaceID ?? ''], () => { + setDownloadErrorModalOpen?.() + }); + }) + + if (downloadOption) { + options.push(downloadOption); + } const itemsToDelete = Object.keys(selectedTransactions ?? {}).filter((id) => selectedTransactions[id].canDelete); diff --git a/src/languages/en.ts b/src/languages/en.ts index 400999d51824..9606b5cf5732 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -366,6 +366,8 @@ export default { initialValue: 'Initial value', currentDate: 'Current date', value: 'Value', + downloadFailedTitle: 'Download failed', + downloadFailedDescription: 'Your download couldn\'t be completed. Please try again later.', }, location: { useCurrent: 'Use current location', diff --git a/src/languages/es.ts b/src/languages/es.ts index 14fdc3c7cf1b..1524ea258348 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -356,6 +356,8 @@ export default { initialValue: 'Valor inicial', currentDate: 'Fecha actual', value: 'Valor', + downloadFailedTitle: 'Error en la descarga', + downloadFailedDescription: 'No se pudo completar la descarga. Por favor, inténtalo más tarde.', }, connectionComplete: { title: 'Conexión completa', diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 7c7d96bcdde0..24c75aef51eb 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -89,7 +89,7 @@ function deleteMoneyRequestOnSearch(hash: number, transactionIDList: string[]) { type Params = Record; -function exportSearchItemsToCSV(query: string, reportIDList: Array | undefined, transactionIDList: string[], policyIDs: string[]) { +function exportSearchItemsToCSV(query: string, reportIDList: Array | undefined, transactionIDList: string[], policyIDs: string[], onDownloadFailed: () => void) { const fileName = `Expensify_${query}.csv`; const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV, { @@ -108,6 +108,6 @@ function exportSearchItemsToCSV(query: string, reportIDList: Array { +const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false, formData = undefined, requestType = 'get', onDownloadFailed?: () => void) => { const resolvedUrl = tryResolveUrlFromApiRoot(url); if ( // we have two file download cases that we should allow 1. dowloading attachments 2. downloading Expensify package for Sage Intacct @@ -55,8 +55,12 @@ const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOp link.parentNode?.removeChild(link); }) .catch(() => { - // file could not be downloaded, open sourceURL in new tab - Link.openExternalLink(url); + if (onDownloadFailed) { + onDownloadFailed() + } else { + // file could not be downloaded, open sourceURL in new tab + Link.openExternalLink(url); + } }); }; diff --git a/src/libs/fileDownload/types.ts b/src/libs/fileDownload/types.ts index d8897331d21c..41a0c5f59fd2 100644 --- a/src/libs/fileDownload/types.ts +++ b/src/libs/fileDownload/types.ts @@ -1,7 +1,7 @@ import type {Asset} from 'react-native-image-picker'; import type {RequestType} from '@src/types/onyx/Request'; -type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean, formData?: FormData, requestType?: RequestType) => Promise; +type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean, formData?: FormData, requestType?: RequestType, onDownloadFailed?: () => void) => Promise; type ImageResolution = {width: number; height: number}; type GetImageResolution = (url: File | Asset) => Promise; From 6f1521469b0d1e73337f26846fcf10f2f06128c4 Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Wed, 17 Jul 2024 13:13:20 -0300 Subject: [PATCH 092/119] lint + prettier --- .../Search/SearchActionOptionsUtils.native.tsx | 4 ++-- src/components/Search/SearchActionOptionsUtils.tsx | 13 ++++++------- src/components/Search/SearchPageHeader.tsx | 5 +++-- src/languages/en.ts | 2 +- src/libs/fileDownload/index.ts | 2 +- src/libs/fileDownload/types.ts | 10 +++++++++- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/components/Search/SearchActionOptionsUtils.native.tsx b/src/components/Search/SearchActionOptionsUtils.native.tsx index 8b6b33c1936e..1e59543721e0 100644 --- a/src/components/Search/SearchActionOptionsUtils.native.tsx +++ b/src/components/Search/SearchActionOptionsUtils.native.tsx @@ -1,5 +1,5 @@ -import type {DropdownOption} from "@components/ButtonWithDropdownMenu/types"; -import {SearchHeaderOptionValue} from "@components/Search/SearchPageHeader"; +import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types'; +import type {SearchHeaderOptionValue} from './SearchPageHeader'; function getDownloadOption(): DropdownOption | undefined { return undefined; diff --git a/src/components/Search/SearchActionOptionsUtils.tsx b/src/components/Search/SearchActionOptionsUtils.tsx index 60a7b3431ba7..20601abd3696 100644 --- a/src/components/Search/SearchActionOptionsUtils.tsx +++ b/src/components/Search/SearchActionOptionsUtils.tsx @@ -1,8 +1,7 @@ -import * as Expensicons from "@components/Icon/Expensicons"; -import CONST from "@src/CONST"; -import type {DropdownOption} from "@components/ButtonWithDropdownMenu/types"; -import {SearchHeaderOptionValue} from "@components/Search/SearchPageHeader"; - +import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types'; +import * as Expensicons from '@components/Icon/Expensicons'; +import CONST from '@src/CONST'; +import type {SearchHeaderOptionValue} from './SearchPageHeader'; function getDownloadOption(text: string, onSelected?: () => void): DropdownOption { return { @@ -10,8 +9,8 @@ function getDownloadOption(text: string, onSelected?: () => void): DropdownOptio text, value: CONST.SEARCH.BULK_ACTION_TYPES.EXPORT, shouldCloseModalOnSelect: true, - onSelected - } + onSelected, + }; } export default getDownloadOption; diff --git a/src/components/Search/SearchPageHeader.tsx b/src/components/Search/SearchPageHeader.tsx index 9d54e62cb739..eeb4b7a8d29f 100644 --- a/src/components/Search/SearchPageHeader.tsx +++ b/src/components/Search/SearchPageHeader.tsx @@ -77,9 +77,9 @@ function SearchPageHeader({ } SearchActions.exportSearchItemsToCSV(query, selectedReports, selectedTransactionsKeys, [activeWorkspaceID ?? ''], () => { - setDownloadErrorModalOpen?.() + setDownloadErrorModalOpen?.(); }); - }) + }); if (downloadOption) { options.push(downloadOption); @@ -184,6 +184,7 @@ function SearchPageHeader({ query, isOffline, setOfflineModalOpen, + setDownloadErrorModalOpen, activeWorkspaceID, selectedReports, styles.textWrap, diff --git a/src/languages/en.ts b/src/languages/en.ts index 9606b5cf5732..59ae2eb59fb5 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -367,7 +367,7 @@ export default { currentDate: 'Current date', value: 'Value', downloadFailedTitle: 'Download failed', - downloadFailedDescription: 'Your download couldn\'t be completed. Please try again later.', + downloadFailedDescription: "Your download couldn't be completed. Please try again later.", }, location: { useCurrent: 'Use current location', diff --git a/src/libs/fileDownload/index.ts b/src/libs/fileDownload/index.ts index b95b6183ced3..133a18e146a5 100644 --- a/src/libs/fileDownload/index.ts +++ b/src/libs/fileDownload/index.ts @@ -56,7 +56,7 @@ const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOp }) .catch(() => { if (onDownloadFailed) { - onDownloadFailed() + onDownloadFailed(); } else { // file could not be downloaded, open sourceURL in new tab Link.openExternalLink(url); diff --git a/src/libs/fileDownload/types.ts b/src/libs/fileDownload/types.ts index 41a0c5f59fd2..6b8c1fe6be72 100644 --- a/src/libs/fileDownload/types.ts +++ b/src/libs/fileDownload/types.ts @@ -1,7 +1,15 @@ import type {Asset} from 'react-native-image-picker'; import type {RequestType} from '@src/types/onyx/Request'; -type FileDownload = (url: string, fileName?: string, successMessage?: string, shouldOpenExternalLink?: boolean, formData?: FormData, requestType?: RequestType, onDownloadFailed?: () => void) => Promise; +type FileDownload = ( + url: string, + fileName?: string, + successMessage?: string, + shouldOpenExternalLink?: boolean, + formData?: FormData, + requestType?: RequestType, + onDownloadFailed?: () => void, +) => Promise; type ImageResolution = {width: number; height: number}; type GetImageResolution = (url: File | Asset) => Promise; From ad6cbeb1db4826ca5f82b36e89e7f4032d26e6fd Mon Sep 17 00:00:00 2001 From: rory Date: Wed, 17 Jul 2024 09:53:58 -0700 Subject: [PATCH 093/119] comment and variable name improvement --- src/libs/PolicyUtils.ts | 2 +- src/libs/actions/Policy/Policy.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index f0eed5375658..fe53a7bcd5ce 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -355,7 +355,7 @@ function getCorrectedAutoReportingFrequency(policy: OnyxInputOrEntry): V } if (policy?.harvesting?.enabled) { - // this is actually not really "immediate". It's "daily". Surprise! + // This is actually not really "immediate". It's "daily". Surprise! return CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE; } diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 996c196ac9d3..7ea6e9b8b74a 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -342,7 +342,7 @@ function deleteWorkspace(policyID: string, policyName: string) { function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf) { const policy = getPolicy(policyID); - const wasPolicyManuallyReported = PolicyUtils.getCorrectedAutoReportingFrequency(policy) === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL; + const wasPolicyOnManualReporting = PolicyUtils.getCorrectedAutoReportingFrequency(policy) === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL; const optimisticData: OnyxUpdate[] = [ { @@ -360,9 +360,9 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf }, }), - // If the policy was manually reported before, and now will be auto-reported, + // If the policy was on manual reporting before, and now will be auto-reported, // then we must re-enable harvesting - ...(wasPolicyManuallyReported && + ...(wasPolicyOnManualReporting && frequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL && { harvesting: { enabled: true, From 0e7b879efd30ff908c2c744bfc8df09c7632e027 Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa <5201282+rlinoz@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:30:53 -0300 Subject: [PATCH 094/119] Update src/languages/en.ts Co-authored-by: Rushat Gabhane --- src/languages/en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 59ae2eb59fb5..bfc20ff81cbb 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3507,7 +3507,7 @@ export default { unhold: 'Unhold', noOptionsAvailable: 'No options available for the selected group of expenses.', }, - offlinePrompt: 'You can’t take this action right now because you appear to be offline.', + offlinePrompt: 'You can’t take this action right now.', }, genericErrorPage: { title: 'Uh-oh, something went wrong!', From 990d6d901446590e3f43ac3b9d48feba95b32eaa Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa <5201282+rlinoz@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:31:00 -0300 Subject: [PATCH 095/119] Update src/languages/es.ts Co-authored-by: Rushat Gabhane --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 1524ea258348..fda8e817eb12 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3562,7 +3562,7 @@ export default { unhold: 'Desbloquear', noOptionsAvailable: 'No hay opciones disponibles para el grupo de gastos seleccionado.', }, - offlinePrompt: 'No puedes realizar esta acción ahora mismo porque parece que estás desconectado.', + offlinePrompt: 'No puedes realizar esta acción ahora mismo.', }, genericErrorPage: { title: '¡Oh-oh, algo salió mal!', From e416cbf183a73dcf1b9d9bed64aaa3d9c91ebc4a Mon Sep 17 00:00:00 2001 From: James Dean Date: Wed, 17 Jul 2024 10:47:11 -0700 Subject: [PATCH 096/119] Update src/languages/es.ts Co-authored-by: Rocio Perez-Cano --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 0d8801deee8f..35119f08136f 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2285,7 +2285,7 @@ export default { }, reimbursableExpenses: { label: 'Exportar gastos de bolsillo como', - description: 'Establezca cómo se exportan los gastos de bolsillo a Sage Intacct.', + description: 'Establece cómo se exportan los gastos por cuenta propia a Sage Intacct.', values: { [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT]: 'Informes de gastos', [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL]: 'Facturas de proveedores', From c0312166e0f09fafc48514649e580733b070bd91 Mon Sep 17 00:00:00 2001 From: James Dean Date: Wed, 17 Jul 2024 10:47:27 -0700 Subject: [PATCH 097/119] Update src/languages/es.ts Co-authored-by: Rocio Perez-Cano --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 35119f08136f..447089b7e8ac 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2284,7 +2284,7 @@ export default { }, }, reimbursableExpenses: { - label: 'Exportar gastos de bolsillo como', + label: 'Exportar gastos por cuenta propia como', description: 'Establece cómo se exportan los gastos por cuenta propia a Sage Intacct.', values: { [CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT]: 'Informes de gastos', From bed35a5a7420e0b2e31f96cec03561d9fe5edeb6 Mon Sep 17 00:00:00 2001 From: maddylewis <38016013+maddylewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 13:50:41 -0400 Subject: [PATCH 098/119] Update and rename Reimbursement.md to Configure-Reimbursement-Settings.md updates to content + changing title - https://github.com/Expensify/Expensify/issues/408716 --- .../Configure-Reimbursement-Settings.md | 55 +++++++++++++++++++ .../workspaces/Reimbursement.md | 48 ---------------- 2 files changed, 55 insertions(+), 48 deletions(-) create mode 100644 docs/articles/expensify-classic/workspaces/Configure-Reimbursement-Settings.md delete mode 100644 docs/articles/expensify-classic/workspaces/Reimbursement.md diff --git a/docs/articles/expensify-classic/workspaces/Configure-Reimbursement-Settings.md b/docs/articles/expensify-classic/workspaces/Configure-Reimbursement-Settings.md new file mode 100644 index 000000000000..aea84d338934 --- /dev/null +++ b/docs/articles/expensify-classic/workspaces/Configure-Reimbursement-Settings.md @@ -0,0 +1,55 @@ +--- +title: Configure Reimbursement Settings +description: Set up direct or indirect reimbursements for your workspace. +--- + + +Reimbursing employees in Expensify is quick, easy, and completely free. Let Expensify do the tedious work for you by taking advantage of the features available to automate employee reimbursement. + +# Configure a Workspace's Reimbursement Settings +There are a few ways to reimburse employees in Expensify. The option that's best suited for you and your business will depend on a few different factors: +- **Direct Reimbursement**: For companies with a business bank account located in the US that reimburse employees within the US. +- **Indirect Reimbursement**: This option is available to all members, and connecting a bank account to Expensify is not required. Indirect reimbursement indicates that all reports are reimbursed outside of Expensify. +- **Global Reimbursement**: If your company’s business bank account is in the US, Canada, the UK, Europe, or Australia, you can reimburse employees directly in nearly any country worldwide. + +## Set Up Direct Reimbursement + +Once a [business bank account is connected to Expensify](https://help.expensify.com/articles/expensify-classic/bank-accounts-and-payments/Business-Bank-Accounts-USD#how-to-add-a-verified-business-bank-account), a workspace admin can enable indirect reimbursement via **Settings > Workspaces > Workspace Name > Reimbursement > Direct**. + +#### Additional features available with Direct Reimbursement: +- **Select a default reimburser for the Workspace from the dropdown menu**: + - The default reimburser will receive notifications to reimburse reports in Expensify. + - Any workspace admin who also has access to the business bank account can be added as a default reimburser. +- **Set a default withdrawal account for the Workspace**: + - The default bank account is used to reimburse all of the reports submitted on the corresponding workspace. +- **Set a manual reimbursement threshold to automate reimbursement**: + - If the total of a given report is less than the threshold set, reimbursement will occur automatically upon final approval. + - If the total of a given report is more than the threshold, it will need to be reimbursed manually. + +## Set Up Indirect Reimbursement + +A Workspace admin can enable indirect reimbursement via **Settings > Workspaces > Workspace Name > Reimbursement > Indirect**. + +**Additional features under Reimbursement > Indirect:** +If you reimburse through a separate system or through payroll, Expensify can collect and export employee bank account details for you. Reach out to your Account Manager or Concierge to have the Reimbursement Details Export format added to the account. + +## Set Up Global Reimbursement + +Once [a business bank account is connected to Expensify](https://help.expensify.com/articles/expensify-classic/bank-accounts-and-payments/Business-Bank-Accounts-USD#how-to-add-a-verified-business-bank-account), a workspace admin can enable indirect reimbursement via **Settings > Workspaces > Workspace Name > Reimbursement > Direct > Enable Global Reimbursements**. + +More information on setting up global reimbursements can be found **[here](https://help.expensify.com/articles/expensify-classic/bank-accounts-and-payments/Global-Reimbursements)**. + +{% include faq-begin.md %} + +## How do I export employee bank account details once the Reimbursement Details Export format is added to my account? + +Employee bank account details can be exported from the Reports page by selecting the relevant Approved reports and then clicking **Export to > Reimbursement Details Export**. + +## Is it possible to change the name of a verified business bank account in Expensify? + +Bank account names can be updated by going to _**Settings > Accounts > Payments**_ and clicking the pencil icon next to the bank account name. + +## What is the benefit of setting a default reimburser? + +Setting a default reimburser on the Workspace ensures that all outstanding reports are reimbursed as this member will receive notifications alerting them to reports that require their action. +{% include faq-end.md %} diff --git a/docs/articles/expensify-classic/workspaces/Reimbursement.md b/docs/articles/expensify-classic/workspaces/Reimbursement.md deleted file mode 100644 index ed2384d12006..000000000000 --- a/docs/articles/expensify-classic/workspaces/Reimbursement.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: Reimbursement -description: Enable reimbursement and reimburse expense reports ---- - - -# Overview -Reimbursement in Expensify is quick, easy, and completely free. Let Expensify do the tedious work for you by taking advantage of features to automate employee reimbursement. - -# How to Enable Reimbursement -There are several options for reimbursing employees in Expensify. The options available will depend on which country your business bank account is domiciled in. - -## Direct Reimbursement - -Direct reimbursement is available to companies who have a verified US bank account and are reimbursing employees within the US. To use direct reimbursement, you must have a US business bank account verified in Expensify. - -A Workspace admin can enable direct reimbursement via **Settings > Workspaces > Workspace Name > Reimbursement > Direct**. - -**Additional features under Reimbursement > Direct:** - - Select a **default reimburser** for the Workspace from the dropdown menu. The default reimburser is the person who will receive notifications to reimburse reports in Expensify. You’ll be able to choose among all Workspace Admins who have access to the business bank account. - - Set a **default withdrawal account** for the Workspace. This will set a default bank account that report reimbursements are withdrawn from. - - Set a **manual reimbursement threshold** to automate reimbursement. Reports whose total falls under the manual reimbursement threshhold will be reimbursed automatocally upon final approval; reports whose total falls above the threshhold will need to be reimbursed manually by the default reimburser. - -Expensify also offers direct global reimbursement to some companies with verified bank accounts in USD, GBP, EUR and AUD who are reimbursing employees internationally. For more information about Global Reimbursement, see LINK - -## Indirect Reimbursement - -Indirect reimbursement is available to all companies in Expensify and no bank account is required. Indirect reimbursement indicates that the report will be reimbursed outside of Expensify. - -A Workspace admin can enanble indirect reimbursement via **Settings > Workspaces > Workspace Name > Reimbursement > Indirect**. - -**Additional features under Reimbursement > Indirect:** -If you reimburse through a seperate system or through payroll, Expensify can collect and export employee bank account details for you. Just reach out to your Account Manager or concierge@expensify.com for us to add the Reimbursement Details Export format to the account. - -{% include faq-begin.md %} - -## How do I export employee bank account details once the Reimbursement Details Export format is added to my account? - -Employee bank account details can be exported from the Reports page by selecting the relevant Approved reports and then clicking **Export to > Reimbursement Details Export**. - -## Is it possible to change the name of a verified business bank account in Expensify? - -Bank account names can be updated via **Settings > Accounts > Payments** and clicking the pencil icon next to the bank account name. - -## What is the benefit of setting a default reimburser? - -The main benefit of being defined as the "reimburser" in the Workspace settings is that this user will receive notifications on their Home page alerting them when reports need to be reimbursed. -{% include faq-end.md %} From a48397dc100a7dde3cb41b78e859431064cc4553 Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Wed, 17 Jul 2024 15:05:38 -0300 Subject: [PATCH 099/119] removing download option from desktop --- src/components/Search/SearchActionOptionsUtils.desktop.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/components/Search/SearchActionOptionsUtils.desktop.ts diff --git a/src/components/Search/SearchActionOptionsUtils.desktop.ts b/src/components/Search/SearchActionOptionsUtils.desktop.ts new file mode 100644 index 000000000000..1e59543721e0 --- /dev/null +++ b/src/components/Search/SearchActionOptionsUtils.desktop.ts @@ -0,0 +1,8 @@ +import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types'; +import type {SearchHeaderOptionValue} from './SearchPageHeader'; + +function getDownloadOption(): DropdownOption | undefined { + return undefined; +} + +export default getDownloadOption; From 40a6a2b669cd38da2997da14581617cc459859c8 Mon Sep 17 00:00:00 2001 From: Rafe Colton Date: Wed, 17 Jul 2024 11:14:03 -0700 Subject: [PATCH 100/119] Revert "Full screen for composer" --- src/pages/home/report/ReportActionsList.tsx | 2 +- src/styles/index.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 8b629c8d4b6f..34b0eecf7b35 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -688,7 +688,7 @@ function ReportActionsList({ isActive={(isFloatingMessageCounterVisible && !!currentUnreadMarker) || canScrollToNewerComments} onClick={scrollToBottomAndMarkReportAsRead} /> - + }, chatFooterFullCompose: { - height: '100%', - paddingTop: 20, + flex: 1, }, chatItemDraft: { From 59cb196e53ed870a77dd08aee28ac7d0d1eb633b Mon Sep 17 00:00:00 2001 From: maddylewis <38016013+maddylewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:32:47 -0400 Subject: [PATCH 101/119] Update redirects.csv --- docs/redirects.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/redirects.csv b/docs/redirects.csv index c1249773bb82..bb3cad52b66c 100644 --- a/docs/redirects.csv +++ b/docs/redirects.csv @@ -221,3 +221,4 @@ https://help.expensify.com/articles/expensify-classic/workspaces/tax-tracking,ht https://help.expensify.com/articles/expensify-classic/copilots-and-delegates/Approval-Workflows,https://help.expensify.com/articles/expensify-classic/reports/Assign-report-approvers-to-specific-employees https://help.expensify.com/articles/expensify-classic/settings/Notification-Troubleshooting,https://help.expensify.com/articles/expensify-classic/settings/account-settings/Set-Notifications https://help.expensify.com/articles/new-expensify/expenses/Validate-a-Business-Bank-Account,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Validate-a-Business-Bank-Account +https://help.expensify.com/articles/expensify-classic/workspaces/Reimbursement,https://help.expensify.com/articles/expensify-classic/workspaces/Configure-Reimbursement-Settings From 389409b95d61d5c07955ac3dc803f5819745aa8c Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Wed, 17 Jul 2024 15:35:14 -0300 Subject: [PATCH 102/119] fix extension --- ...tionsUtils.desktop.ts => SearchActionOptionsUtils.desktop.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/components/Search/{SearchActionOptionsUtils.desktop.ts => SearchActionOptionsUtils.desktop.tsx} (100%) diff --git a/src/components/Search/SearchActionOptionsUtils.desktop.ts b/src/components/Search/SearchActionOptionsUtils.desktop.tsx similarity index 100% rename from src/components/Search/SearchActionOptionsUtils.desktop.ts rename to src/components/Search/SearchActionOptionsUtils.desktop.tsx From 0815754c9fc704ad199c0758b94628fcfcddfb98 Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa <5201282+rlinoz@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:12:03 -0300 Subject: [PATCH 103/119] Update src/languages/en.ts Co-authored-by: Carlos Martins --- src/languages/en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 119fe7b339b4..2c210530f06c 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3530,7 +3530,7 @@ export default { unhold: 'Unhold', noOptionsAvailable: 'No options available for the selected group of expenses.', }, - offlinePrompt: 'You can’t take this action right now.', + offlinePrompt: 'You can't take this action right now.', }, genericErrorPage: { title: 'Uh-oh, something went wrong!', From 2002c3d89e3e83a2c4718b76d23bfcd0812a0f30 Mon Sep 17 00:00:00 2001 From: maddylewis <38016013+maddylewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:26:58 -0400 Subject: [PATCH 104/119] Update and rename Expenses.md to Expense-Settings.md updating content + title of article https://github.com/Expensify/Expensify/issues/408716 --- .../{Expenses.md => Expense-Settings.md} | 84 ++++++++++--------- 1 file changed, 43 insertions(+), 41 deletions(-) rename docs/articles/expensify-classic/workspaces/{Expenses.md => Expense-Settings.md} (61%) diff --git a/docs/articles/expensify-classic/workspaces/Expenses.md b/docs/articles/expensify-classic/workspaces/Expense-Settings.md similarity index 61% rename from docs/articles/expensify-classic/workspaces/Expenses.md rename to docs/articles/expensify-classic/workspaces/Expense-Settings.md index 4a2dc56c430f..c3a8ab31394d 100644 --- a/docs/articles/expensify-classic/workspaces/Expenses.md +++ b/docs/articles/expensify-classic/workspaces/Expense-Settings.md @@ -2,19 +2,29 @@ title: Expensify Workspace Expense Settings description: Expense Settings --- -# Overview +Expensify offers multiple ways to customize how expenses are created and managed at the workspace level. Whether you’re using an individual workspace or managing expenses in a group workspace, there are various expense settings you can customize. -Expensify offers multiple ways to customize how expenses are created in your workspace. In this doc, you’ll learn how to set up expense basics, distance expenses, and time expenses. +# Set up the expense settings on a workspace -Whether you’re flying solo with your Individual workspace or submitting with a team on your Group workspace, we have settings to support how you use Expensify. +You can manage the expense settings on a workspace under **Settings** > **Workspaces** > **Individual** or **Group** > [_Workspace Name_] > **Expenses**. From here you can customize the following expense-level settings: +- **Violations**: When enabled, employee expenses that fall outside of workspace preferences are flagged as violations. +- **Preferences**: Configure the reimbursable and billable settings for the expenses submitted to the corresponding workspace. +- **Distance**: This is where you can set the reimbursable mileage rates for yourself or your employees. +- **Time**: Set an hourly billable rate so members of the workspace can create time expenses for reimbursement. -# How to manage expense settings in your workspace +## Violations +A workspace admin can customize the following parameters at the expense level: +- **Max Expense Age (Days)** +- **Max Expense Amount** +- **Receipt Required Amount** -Let’s cover the expense basics first! In the following sections, we’ll go through each part of managing expense settings in your workspace. +If an expense is submitted that falls outside of those parameters, Expensify will automatically detect it as a violation and alert both the expense creator and reviewer that it needs to be corrected. -## Controlling cash expenses +More information on violations can be found [**here**](https://help.expensify.com/articles/expensify-classic/workspaces/Enable-and-set-up-expense-violations). -A cash expense is any expense created manually or by uploading a receipt for SmartScan; a cash expense does not mean the expense was paid for with cash. The other type of expense you’ll most commonly see is credit card expenses, which means the expenses imported from a credit card or bank connection. +## Preferences + +A cash expense is any expense created manually or by uploading a receipt for SmartScan; it does not mean the expense was paid for with cash. The other type of expense you’ll most commonly see is credit card expenses, which are expenses imported from a credit card or bank connection. There are four options for cash expenses: @@ -23,7 +33,7 @@ There are four options for cash expenses: - **Forced always reimbursable** - All cash expenses are forced to be reimbursable; they cannot be marked as non-reimbursable. - **Forced always non-reimbursable** - All cash expenses are forced to be non-reimbursable; they cannot be marked as reimbursable. -## Setting up billable expenses +### Billable expenses Billable expenses refer to expenses you or your employees incur that need to be re-billed to a specific client or vendor. @@ -37,7 +47,7 @@ Under Expense Basics, you can choose the setting that is best for you. If your Group workspace is connected to Xero, QuickBooks Online, NetSuite, or Sage Intacct, you can export billable expenses to be invoiced to customers. To set this up, go to the Coding tab in the connection configuration settings. -## Using eReceipts +### eReceipts eReceipts are full digital replacements of their paper equivalents for purchases of $75 or less. @@ -46,65 +56,57 @@ Click the toggle to your preferred configuration. - **Enabled** - All imported credit card expenses in US dollars of $75 or less will have eReceipts in the receipt image. - **Disabled** - No expenses will generate an eReceipt. -Note: _We will not generate an eReceipt for lodging expenses._ +Note: Expensify will not generate an eReceipt for lodging expenses. -## Securing receipt images +### Secure receipt images Whether you’re sharing your receipts with your accountant, having an auditor review exported expenses, or simply wanting to export to keep a hard copy for yourself, receipt visibility will be an essential consideration. Under _Public Receipt Visibility_, you can determine who can view receipts on your workspace. - **Enabled** means receipts are viewable by anyone with the URL. They don't need to be an Expensify user or a workspace member to view receipts. -- **Disabled** means receipts are viewable by users of Expensify, who would have access to view the receipt in the application. You must be an Expensify user with access to the report a receipt is on and logged into your account to view a receipt image via URL. +- **Disabled** means receipts are viewable by Expensify users, who would have access to view the receipt in the application. You must be an Expensify user with access to the report a receipt is on and logged into your account to view a receipt image via URL. -## Track mileage expenses +## Distance Expenses +How to set up distance expenses: +1. Select whether you want to capture _miles_ or _kilometers_, +2. Set the default category to be used on distance expenses, +3. Click **Add A Mileage Rate** to add as many rates as you need, +4. Set the reimbursable amount per mile or kilometer. -Whether using the Individual or Group workspace, you can create distance rates to capture expenses in miles or kilometers. +**Note:** If a rate is toggled off it is immediately disabled. This means that users are no longer able to select it when creating a new distance expense. If only one rate is available then that rate will be toggled on by default. -Preliminary setup steps include: +### Track tax on mileage expenses +If you’re tracking tax in Expensify you can also track tax on distance expenses. The first step is to enable tax in the workspace. You can do this by going to **Settings** > **Workspaces** > **Individual** or **Group** > [_Workspace Name_] > **Tax**. -1. Selecting whether you want to capture _miles_ or _kilometers_, -2. Setting the default category to be used on distance expenses, -3. Click **Add A Mileage Rate** to add as many rates as you need, -4. Set the reimbursable amount per mile or kilometer. +Once tax is enabled on a workspace level you will see a toggle to _Track Tax_ in the Distance section of the workspace settings. If tax is disabled on the workspace the Track Tax toggle will not display. -Note: _If a rate is toggled off it is immediately disabled. This means that users are no longer able to select it when creating a new distance expense. If only one rate is available then that rate will be toggled on by default._ +When Track Tax is enabled, you will need to enter additional information about the rates you have set. This includes the _Tax Reclaimable on_ and _Tax Rate_ fields. With that information, Expensify will work out the correct tax reclaim for each expense. -## Set an hourly rate +If you enable tax but don’t select a tax rate or enter a tax reclaimable amount, we will not calculate any tax amount for that rate. If, at any point, you switch the tax rate or enter a different reclaimable portion for an existing distance rate, the mileage rate will need to be re-selected on expenses for the tax amount to update according to the new values. -Using Expensify you can track time-based expenses to bill your clients at an hourly rate or allow employees to claim an hourly stipend. +**Note:** Expensify won’t automatically track cumulative mileage. If you need to track cumulative mileage per employee, we recommend building a mileage report using our custom export formulas. -Click the toggle under the _Time_ section to enable the feature and set a default hourly rate. After that, you and your users will be able to create time-based expenses from the [**Expenses**](https://expensify.com/expenses) page of the account. +## Time Expenses -# Deep dives +Using Expensify you can track time-based expenses to bill your clients at an hourly rate or allow employees to claim an hourly stipend. -## What is Concierge Receipt Audit for the Control Plan? +Click the toggle under the _Time_ section to enable the feature and set a default hourly rate. Then, you and your users can create time-based expenses from the [**Expenses**](https://expensify.com/expenses) page of the account. -Concierge Receipt Audit is a real-time audit and compliance of receipts submitted by employees and workspace users. Concierge checks every receipt for accuracy and compliance, flagging any expenses that seem fishy before expense reports are even submitted for approval. All risky expenses are highlighted for manual review, leaving you with more control over and visibility into expenses. When a report is submitted and there are risky expenses on it, you will be immediately prompted to review the risky expenses and determine the next steps. +## Concierge Receipt Audit -**Why you should use Concierge Receipt Audit** +Concierge Receipt Audit is a real-time audit and compliance of receipts submitted by employees and workspace users. Concierge checks every receipt for accuracy and compliance, flagging any expenses that seem fishy before expense reports are even submitted for approval. All risky expenses are highlighted for manual review, leaving you with more control over and visibility into expenses. When a report is submitted and there are risky expenses on it, you will be immediately prompted to review the risky expenses and determine the next steps. +**Benefits of Concierge Receipt Audit** - To make sure you don't miss any risky expenses that need human oversight. - To avoid needing to manually review all your company receipts. - It's included at no extra cost with the [Control Plan](https://www.expensify.com/pricing). - Instead of paying someone to audit your company expenses or being concerned that your expenses might be audited by a government agency. -- It's easy to use! Concierge will alert you to the risky expense and present it to you in an easy-to-follow review tutorial. +- It's easy -- Concierge will alert you to the risky expense and present it to you in an easy-to-follow review tutorial. - In addition to the risky expense alerts, Expensify will include a Note with audit details on every report. -Note: _If a report has audit alerts on it, you'll need to Review the report and Accept the alerts before it can be approved._ - -## Tracking tax on mileage expenses - -If you’re tracking tax in Expensify you can also track tax on distance expenses. The first step is to enable tax in the workspace. You can do this by going to **Settings** > **Workspaces** > **Individual** or **Group** > [_Workspace Name_] > **Tax**. - -Once tax is enabled on a workspace level you will see a toggle to _Track Tax_ in the Distance section of the workspace settings. If tax is disabled on the workspace the Track Tax toggle will not display. - -When Track Tax is enabled you will need to enter additional information to the rates you have set, this includes the _Tax Reclaimable on_ and _Tax Rate_ fields. With that information, Expensify will work out the correct tax reclaim for each expense. - -If you enable tax but don’t select a tax rate or enter a tax reclaimable amount, we will not calculate any tax amount for that rate. If, at any point, you switch the tax rate or enter a different reclaimable portion for an existing distance rate, the mileage rate will need to be re-selected on expenses for the tax amount to update according to the new values. - -Note: _Expensify won’t automatically track cumulative mileage. If you need to track cumulative mileage per employee, we recommend building a mileage report using our custom export formulas._ +**Note:** If a report has audit alerts on it, you'll need to Review the report and Accept the alerts before it can be approved. {% include faq-begin.md %} From 24fc807a962242312a0103bcfab63ab73a33c15f Mon Sep 17 00:00:00 2001 From: maddylewis <38016013+maddylewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:28:44 -0400 Subject: [PATCH 105/119] Update redirects.csv added redirect --- docs/redirects.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/redirects.csv b/docs/redirects.csv index c1249773bb82..562e76d6d881 100644 --- a/docs/redirects.csv +++ b/docs/redirects.csv @@ -221,3 +221,4 @@ https://help.expensify.com/articles/expensify-classic/workspaces/tax-tracking,ht https://help.expensify.com/articles/expensify-classic/copilots-and-delegates/Approval-Workflows,https://help.expensify.com/articles/expensify-classic/reports/Assign-report-approvers-to-specific-employees https://help.expensify.com/articles/expensify-classic/settings/Notification-Troubleshooting,https://help.expensify.com/articles/expensify-classic/settings/account-settings/Set-Notifications https://help.expensify.com/articles/new-expensify/expenses/Validate-a-Business-Bank-Account,https://help.expensify.com/articles/new-expensify/expenses-&-payments/Validate-a-Business-Bank-Account +https://help.expensify.com/articles/expensify-classic/workspaces/Expenses,https://help.expensify.com/articles/expensify-classic/workspaces/Expense-Settings From 340e92260c755d325395bbe623778a38569079be Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Wed, 17 Jul 2024 16:56:42 -0300 Subject: [PATCH 106/119] fix language --- src/languages/en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 2c210530f06c..0cc3cb3ea011 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3530,7 +3530,7 @@ export default { unhold: 'Unhold', noOptionsAvailable: 'No options available for the selected group of expenses.', }, - offlinePrompt: 'You can't take this action right now.', + offlinePrompt: 'You can\'t take this action right now.', }, genericErrorPage: { title: 'Uh-oh, something went wrong!', From 8885dc5105864ff957ca2e6c30ae386968ccd66c Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Wed, 17 Jul 2024 19:06:18 -0300 Subject: [PATCH 107/119] pr comments --- src/languages/en.ts | 2 +- src/libs/actions/Search.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 0cc3cb3ea011..a4dcddcac9c3 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3530,7 +3530,7 @@ export default { unhold: 'Unhold', noOptionsAvailable: 'No options available for the selected group of expenses.', }, - offlinePrompt: 'You can\'t take this action right now.', + offlinePrompt: "You can't take this action right now.", }, genericErrorPage: { title: 'Uh-oh, something went wrong!', diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 24c75aef51eb..969812b02b02 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -90,8 +90,6 @@ function deleteMoneyRequestOnSearch(hash: number, transactionIDList: string[]) { type Params = Record; function exportSearchItemsToCSV(query: string, reportIDList: Array | undefined, transactionIDList: string[], policyIDs: string[], onDownloadFailed: () => void) { - const fileName = `Expensify_${query}.csv`; - const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV, { query, reportIDList, @@ -108,6 +106,6 @@ function exportSearchItemsToCSV(query: string, reportIDList: Array Date: Wed, 17 Jul 2024 19:31:17 -0300 Subject: [PATCH 108/119] fix reportIDs --- .../Search/SearchListWithHeader.tsx | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/components/Search/SearchListWithHeader.tsx b/src/components/Search/SearchListWithHeader.tsx index 25522d84fbf6..87a39fdd504b 100644 --- a/src/components/Search/SearchListWithHeader.tsx +++ b/src/components/Search/SearchListWithHeader.tsx @@ -52,12 +52,23 @@ function SearchListWithHeader( const [isModalVisible, setIsModalVisible] = useState(false); const [longPressedItem, setLongPressedItem] = useState(null); const [selectedTransactions, setSelectedTransactions] = useState({}); - const [selectedReports, setSelectedReports] = useState>([]); const [selectedTransactionsToDelete, setSelectedTransactionsToDelete] = useState([]); const [deleteExpensesConfirmModalVisible, setDeleteExpensesConfirmModalVisible] = useState(false); const [offlineModalVisible, setOfflineModalVisible] = useState(false); const [downloadErrorModalVisible, setDownloadErrorModalVisible] = useState(false); + const selectedReports: Array = useMemo(() => { + if (searchType !== CONST.SEARCH.DATA_TYPES.REPORT) { + return []; + } + + return data + .filter( + (item) => !SearchUtils.isTransactionListItemType(item) && item.reportID && item.transactions.every((transaction) => selectedTransactions[transaction.keyForList]?.isSelected), + ) + .map((item) => item.reportID); + }, [selectedTransactions, data, searchType]); + const handleOnSelectDeleteOption = (itemsToDelete: string[]) => { setSelectedTransactionsToDelete(itemsToDelete); setDeleteExpensesConfirmModalVisible(true); @@ -68,10 +79,7 @@ function SearchListWithHeader( setDeleteExpensesConfirmModalVisible(false); }; - const clearSelectedItems = () => { - setSelectedTransactions({}); - setSelectedReports([]); - }; + const clearSelectedItems = () => setSelectedTransactions({}); const handleDeleteExpenses = () => { if (selectedTransactionsToDelete.length === 0) { @@ -107,7 +115,6 @@ function SearchListWithHeader( if (item.transactions.every((transaction) => selectedTransactions[transaction.keyForList]?.isSelected)) { const reducedSelectedTransactions: SelectedTransactions = {...selectedTransactions}; - setSelectedReports((prevReports) => prevReports.filter((reportID) => reportID !== item.reportID)); item.transactions.forEach((transaction) => { delete reducedSelectedTransactions[transaction.keyForList]; @@ -117,15 +124,12 @@ function SearchListWithHeader( return; } - if (item.reportID) { - setSelectedReports([...selectedReports, item.reportID]); - } setSelectedTransactions({ ...selectedTransactions, ...Object.fromEntries(item.transactions.map(mapTransactionItemToSelectedEntry)), }); }, - [selectedTransactions, selectedReports], + [selectedTransactions], ); const openBottomModal = (item: TransactionListItemType | ReportListItemType | null) => { From dbbc072ba986c6e1cf141e3afb6cbfe8d3538bfd Mon Sep 17 00:00:00 2001 From: Jack Nam <30609178+thienlnam@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:11:27 -0700 Subject: [PATCH 109/119] Revert "[Wave Collect][Xero] Enforce 2FA for xero" --- .storybook/webpack.config.ts | 5 - src/Expensify.tsx | 24 +---- src/ROUTES.ts | 3 +- .../ConnectToXeroButton/index.native.tsx | 26 +----- src/components/ConnectToXeroButton/index.tsx | 26 ------ .../RequireTwoFactorAuthenticationModal.tsx | 91 ------------------- src/languages/en.ts | 5 - src/languages/es.ts | 6 -- src/libs/API/types.ts | 4 +- src/libs/Navigation/types.ts | 19 +--- src/libs/actions/Session/index.ts | 22 +---- .../TwoFactorAuth/Steps/SuccessStep.tsx | 15 +-- .../TwoFactorAuth/TwoFactorAuthSteps.tsx | 9 +- src/types/onyx/Account.ts | 3 - 14 files changed, 14 insertions(+), 244 deletions(-) delete mode 100644 src/components/RequireTwoFactorAuthenticationModal.tsx diff --git a/.storybook/webpack.config.ts b/.storybook/webpack.config.ts index 0aa38f2e3b82..a7811a5a387d 100644 --- a/.storybook/webpack.config.ts +++ b/.storybook/webpack.config.ts @@ -100,11 +100,6 @@ const webpackConfig = ({config}: {config: Configuration}) => { }), ); - config.module.rules?.push({ - test: /\.lottie$/, - type: 'asset/resource', - }); - return config; }; diff --git a/src/Expensify.tsx b/src/Expensify.tsx index f9fd379d94ce..6151f983e8d0 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -3,13 +3,12 @@ import React, {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useStat import type {NativeEventSubscription} from 'react-native'; import {AppState, Linking, NativeModules} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import Onyx, {useOnyx, withOnyx} from 'react-native-onyx'; +import Onyx, {withOnyx} from 'react-native-onyx'; import ConfirmModal from './components/ConfirmModal'; import DeeplinkWrapper from './components/DeeplinkWrapper'; import EmojiPicker from './components/EmojiPicker/EmojiPicker'; import FocusModeNotification from './components/FocusModeNotification'; import GrowlNotification from './components/GrowlNotification'; -import RequireTwoFactorAuthenticationModal from './components/RequireTwoFactorAuthenticationModal'; import AppleAuthWrapper from './components/SignInButtons/AppleAuthWrapper'; import SplashScreenHider from './components/SplashScreenHider'; import UpdateAppModal from './components/UpdateAppModal'; @@ -38,7 +37,6 @@ import ONYXKEYS from './ONYXKEYS'; import PopoverReportActionContextMenu from './pages/home/report/ContextMenu/PopoverReportActionContextMenu'; import * as ReportActionContextMenu from './pages/home/report/ContextMenu/ReportActionContextMenu'; import type {Route} from './ROUTES'; -import ROUTES from './ROUTES'; import type {ScreenShareRequest, Session} from './types/onyx'; Onyx.registerLogger(({level, message}) => { @@ -103,16 +101,6 @@ function Expensify({ const [isSplashHidden, setIsSplashHidden] = useState(false); const [hasAttemptedToOpenPublicRoom, setAttemptedToOpenPublicRoom] = useState(false); const {translate} = useLocalize(); - const [account] = useOnyx(ONYXKEYS.ACCOUNT); - const [shouldShowRequire2FAModal, setShouldShowRequire2FAModal] = useState(false); - - useEffect(() => { - if (!account?.needsTwoFactorAuthSetup || account.requiresTwoFactorAuth) { - return; - } - setShouldShowRequire2FAModal(true); - }, [account?.needsTwoFactorAuthSetup, account?.requiresTwoFactorAuth]); - const [initialUrl, setInitialUrl] = useState(null); useEffect(() => { @@ -265,16 +253,6 @@ function Expensify({ /> ) : null} {focusModeNotification ? : null} - {shouldShowRequire2FAModal ? ( - { - setShouldShowRequire2FAModal(false); - Navigation.navigate(ROUTES.SETTINGS_2FA.getRoute(ROUTES.HOME)); - }} - isVisible - description={translate('twoFactorAuth.twoFactorAuthIsRequiredForAdminsDescription')} - /> - ) : null} )} diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 4d977ea8e219..21171caaa6b6 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -198,8 +198,7 @@ const ROUTES = { }, SETTINGS_2FA: { route: 'settings/security/two-factor-auth', - getRoute: (backTo?: string, forwardTo?: string) => - getUrlWithBackToParam(forwardTo ? `settings/security/two-factor-auth?forwardTo=${encodeURIComponent(forwardTo)}` : 'settings/security/two-factor-auth', backTo), + getRoute: (backTo?: string) => getUrlWithBackToParam('settings/security/two-factor-auth', backTo), }, SETTINGS_STATUS: 'settings/profile/status', diff --git a/src/components/ConnectToXeroButton/index.native.tsx b/src/components/ConnectToXeroButton/index.native.tsx index 04b5f8722ea5..15fe201f2ac9 100644 --- a/src/components/ConnectToXeroButton/index.native.tsx +++ b/src/components/ConnectToXeroButton/index.native.tsx @@ -1,6 +1,6 @@ import React, {useRef, useState} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; -import {useOnyx, withOnyx} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import {WebView} from 'react-native-webview'; import AccountingConnectionConfirmationModal from '@components/AccountingConnectionConfirmationModal'; import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; @@ -8,17 +8,14 @@ import Button from '@components/Button'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import Modal from '@components/Modal'; -import RequireTwoFactorAuthenticationModal from '@components/RequireTwoFactorAuthenticationModal'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import {removePolicyConnection} from '@libs/actions/connections'; import {getXeroSetupLink} from '@libs/actions/connections/ConnectToXero'; import getUAForWebView from '@libs/getUAForWebView'; -import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; import type {Session} from '@src/types/onyx'; import type {ConnectToXeroButtonProps} from './types'; @@ -36,22 +33,13 @@ function ConnectToXeroButton({policyID, session, shouldDisconnectIntegrationBefo const authToken = session?.authToken ?? null; const {isOffline} = useNetwork(); - const [account] = useOnyx(ONYXKEYS.ACCOUNT); - const is2FAEnabled = account?.requiresTwoFactorAuth ?? false; - const renderLoading = () => ; const [isDisconnectModalOpen, setIsDisconnectModalOpen] = useState(false); - const [isRequire2FAModalOpen, setIsRequire2FAModalOpen] = useState(false); return ( <>