From 5023b92feb26a21a114438cdc55363dd81bf04b0 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 16:04:13 +0700 Subject: [PATCH 01/41] fix: app goes back to confirmation page from category page --- src/ROUTES.ts | 4 ++-- src/libs/Navigation/types.ts | 1 + src/libs/ReportUtils.ts | 2 +- src/pages/iou/request/step/IOURequestStepConfirmation.tsx | 6 +++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 5a8f4a2cd4d0..622106bdb01c 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -346,8 +346,8 @@ const ROUTES = { }, MONEY_REQUEST_STEP_CONFIRMATION: { route: ':action/:iouType/confirmation/:transactionID/:reportID', - getRoute: (action: IOUAction, iouType: IOUType, transactionID: string, reportID: string) => - `${action as string}/${iouType as string}/confirmation/${transactionID}/${reportID}` as const, + getRoute: (action: IOUAction, iouType: IOUType, transactionID: string, reportID: string, participantsAutoAssigned?: boolean) => + `${action as string}/${iouType as string}/confirmation/${transactionID}/${reportID}${participantsAutoAssigned ? '?participantsAutoAssigned=true' : ''}` as const, }, MONEY_REQUEST_STEP_AMOUNT: { route: ':action/:iouType/amount/:transactionID/:reportID', diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 2267d2d38fb7..d4de39b993de 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -613,6 +613,7 @@ type MoneyRequestNavigatorParamList = { reportID: string; pageIndex?: string; backTo?: string; + participantsAutoAssigned?: string; }; [SCREENS.MONEY_REQUEST.STEP_SCAN]: { action: IOUAction; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index b128c6cf9153..73bcbc17769b 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6728,7 +6728,7 @@ function createDraftWorkspaceAndNavigateToConfirmationScreen(transactionID: stri searchText: policyName, }, ]); - const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID); + const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID, true); if (isCategorizing) { Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID, iouConfirmationPageRoute)); } else { diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index 939589598701..89afd72bd17e 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -65,7 +65,7 @@ function IOURequestStepConfirmation({ report: reportReal, reportDraft, route: { - params: {iouType, reportID, transactionID, action}, + params: {iouType, reportID, transactionID, action, participantsAutoAssigned: participantsAutoAssignedFromRoute}, }, transaction, }: IOURequestStepConfirmationProps) { @@ -186,12 +186,12 @@ function IOURequestStepConfirmation({ const navigateBack = useCallback(() => { // If there is not a report attached to the IOU with a reportID, then the participants were manually selected and the user needs taken // back to the participants step - if (!transaction?.participantsAutoAssigned) { + if (!transaction?.participantsAutoAssigned && participantsAutoAssignedFromRoute !== 'true') { Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_PARTICIPANTS.getRoute(iouType, transactionID, reportID, undefined, action)); return; } IOUUtils.navigateToStartMoneyRequestStep(requestType, iouType, transactionID, reportID, action); - }, [transaction, iouType, requestType, transactionID, reportID, action]); + }, [transaction, iouType, requestType, transactionID, reportID, action, participantsAutoAssignedFromRoute]); const navigateToAddReceipt = useCallback(() => { Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_SCAN.getRoute(action, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams())); From 57422f82763c119375a43b04560040aeb2c170e8 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 16:31:23 +0700 Subject: [PATCH 02/41] fix in category page --- src/libs/ReportUtils.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 73bcbc17769b..4389bc205f36 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6728,11 +6728,10 @@ function createDraftWorkspaceAndNavigateToConfirmationScreen(transactionID: stri searchText: policyName, }, ]); - const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID, true); if (isCategorizing) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID, iouConfirmationPageRoute)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID)); } else { - Navigation.navigate(iouConfirmationPageRoute); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID, true)); } } From 57401aad6e8ba8d3cbfc0ec7cf9fabf30dc568a6 Mon Sep 17 00:00:00 2001 From: Sonia Liapounova Date: Tue, 9 Jul 2024 18:26:36 +0200 Subject: [PATCH 03/41] Update Invite-members-to-a-chat-group-or-room.md --- .../chat/Invite-members-to-a-chat-group-or-room.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/new-expensify/chat/Invite-members-to-a-chat-group-or-room.md b/docs/articles/new-expensify/chat/Invite-members-to-a-chat-group-or-room.md index d6877f71be07..c26ecf979b32 100644 --- a/docs/articles/new-expensify/chat/Invite-members-to-a-chat-group-or-room.md +++ b/docs/articles/new-expensify/chat/Invite-members-to-a-chat-group-or-room.md @@ -68,7 +68,7 @@ If your group/room is Private, you can only share the chat link with other membe {% include option.html value="desktop" %} 1. Open the chat group or room you want to invite someone to. 2. Click the room or group header. -3. Click **Share code**. +3. Click **Share**. 4. Copy the link or share the QR code. - **Copy link**: Click **Copy URL** and paste the link into another chat, email, Slack, etc. - **Share QR Code**: Present your device to another user so they can scan the QR code with their device. From 9eb225f20df0457345fdb53568517eb9d78f0338 Mon Sep 17 00:00:00 2001 From: Sonia Liapounova Date: Tue, 9 Jul 2024 18:27:28 +0200 Subject: [PATCH 04/41] Update Leave-a-chat-room.md --- docs/articles/new-expensify/chat/Leave-a-chat-room.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/new-expensify/chat/Leave-a-chat-room.md b/docs/articles/new-expensify/chat/Leave-a-chat-room.md index 252e7e94f1ac..ae6610b53be0 100644 --- a/docs/articles/new-expensify/chat/Leave-a-chat-room.md +++ b/docs/articles/new-expensify/chat/Leave-a-chat-room.md @@ -15,7 +15,7 @@ If you wish to no longer be part of a chat room, you can leave the room. This me {% include option.html value="mobile" %} 1. Open the chat room. -2. Tap the 3 dot menu icon in the top right and select **Leave**. +2. Tap the header and select **Leave**. {% include end-option.html %} {% include end-selector.html %} From 086e464eda1d76fe94858aadd75feb6ac4af0b07 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Fri, 19 Jul 2024 17:47:42 +0500 Subject: [PATCH 05/41] feat: log network response and request. Allow filtering option in Debug Console --- src/libs/actions/OnyxUpdates.ts | 3 +- src/pages/settings/AboutPage/ConsolePage.tsx | 48 +++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/OnyxUpdates.ts b/src/libs/actions/OnyxUpdates.ts index 73c8b3d592bf..6769fa7e64a3 100644 --- a/src/libs/actions/OnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdates.ts @@ -35,7 +35,8 @@ function applyHTTPSOnyxUpdates(request: Request, response: Response) { // apply successData or failureData. This ensures that we do not update any pending, loading, or other UI states contained // in successData/failureData until after the component has received and API data. const onyxDataUpdatePromise = response.onyxData ? updateHandler(response.onyxData) : Promise.resolve(); - + Log.info('[OnyxUpdateManager]-[Network]-[Request]', false, request); + Log.info('[OnyxUpdateManager]-[Network]-[Response]', false, response); return onyxDataUpdatePromise .then(() => { // Handle the request's success/failure data (client-side data) diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx index aee11c89f22c..6f5942293f61 100644 --- a/src/pages/settings/AboutPage/ConsolePage.tsx +++ b/src/pages/settings/AboutPage/ConsolePage.tsx @@ -11,11 +11,13 @@ import ConfirmModal from '@components/ConfirmModal'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import InvertedFlatList from '@components/InvertedFlatList'; +import type {PopoverMenuItem} from '@components/PopoverMenu'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useKeyboardShortcut from '@hooks/useKeyboardShortcut'; import useLocalize from '@hooks/useLocalize'; +import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import {addLog} from '@libs/actions/Console'; import {createLog, parseStringifiedMessages, sanitizeConsoleInput} from '@libs/Console'; @@ -40,16 +42,56 @@ type ConsolePageOnyxProps = { type ConsolePageProps = ConsolePageOnyxProps; +const filterBy = { + all: '', + network: '-[Network]-', +} as const; +type FilterBy = (typeof filterBy)[keyof typeof filterBy]; + function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { const [input, setInput] = useState(''); const [logs, setLogs] = useState(capturedLogs); const [isGeneratingLogsFile, setIsGeneratingLogsFile] = useState(false); const [isLimitModalVisible, setIsLimitModalVisible] = useState(false); + const [activeFilterIndex, setActiveFilterIndex] = useState(filterBy.all); const {translate} = useLocalize(); const styles = useThemeStyles(); + const theme = useTheme(); const route = useRoute>(); + const menuItems: PopoverMenuItem[] = useMemo( + () => [ + { + text: translate('common.filterLogs'), + disabled: true, + }, + { + icon: Expensicons.All, + text: translate('common.all'), + iconFill: activeFilterIndex === filterBy.all ? theme.iconSuccessFill : theme.icon, + iconRight: Expensicons.Checkmark, + shouldShowRightIcon: activeFilterIndex === filterBy.all, + success: activeFilterIndex === filterBy.all, + onSelected: () => { + setActiveFilterIndex(filterBy.all); + }, + }, + { + icon: Expensicons.CardsAndDomains, + text: translate('common.network'), + iconFill: activeFilterIndex === filterBy.network ? theme.iconSuccessFill : theme.icon, + iconRight: Expensicons.CheckCircle, + shouldShowRightIcon: activeFilterIndex === filterBy.network, + success: activeFilterIndex === filterBy.network, + onSelected: () => { + setActiveFilterIndex(filterBy.network); + }, + }, + ], + [activeFilterIndex, theme.icon, theme.iconSuccessFill, translate], + ); + const logsList = useMemo( () => Object.entries(logs ?? {}) @@ -58,6 +100,8 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { [logs], ); + const filteredLogsList = useMemo(() => logsList.filter((log) => log.message.includes(activeFilterIndex)), [activeFilterIndex, logsList]); + useEffect(() => { if (!shouldStoreLogs) { return; @@ -121,10 +165,12 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { Navigation.goBack(route.params?.backTo)} + shouldShowThreeDotsButton + threeDotsMenuItems={menuItems} /> {translate('initialSettingsPage.debugConsole.noLogsAvailable')}} From 766f922bc0c50d5dc83dd01908c9232016ae8bcb Mon Sep 17 00:00:00 2001 From: hurali97 Date: Fri, 19 Jul 2024 17:48:06 +0500 Subject: [PATCH 06/41] feat: add locale values for filter options --- src/languages/en.ts | 2 ++ src/languages/es.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index a8281e609305..5e2654ebc847 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -368,6 +368,8 @@ export default { value: 'Value', downloadFailedTitle: 'Download failed', downloadFailedDescription: "Your download couldn't be completed. Please try again later.", + filterLogs: 'Filter Logs', + network: 'Network', }, location: { useCurrent: 'Use current location', diff --git a/src/languages/es.ts b/src/languages/es.ts index bbbbbfc79bac..2e383d04e451 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -358,6 +358,8 @@ export default { value: 'Valor', downloadFailedTitle: 'Error en la descarga', downloadFailedDescription: 'No se pudo completar la descarga. Por favor, inténtalo más tarde.', + filterLogs: 'Registros de filtrado', + network: 'La red', }, connectionComplete: { title: 'Conexión completa', From 347f9b26fc2f18ae3bd15f730299a7b04c175e71 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Mon, 22 Jul 2024 13:18:15 +0500 Subject: [PATCH 07/41] feat: use correct icons --- src/pages/settings/AboutPage/ConsolePage.tsx | 2 +- src/pages/settings/Troubleshoot/TroubleshootPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx index 6f5942293f61..d6880a3ff052 100644 --- a/src/pages/settings/AboutPage/ConsolePage.tsx +++ b/src/pages/settings/AboutPage/ConsolePage.tsx @@ -78,7 +78,7 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { }, }, { - icon: Expensicons.CardsAndDomains, + icon: Expensicons.Globe, text: translate('common.network'), iconFill: activeFilterIndex === filterBy.network ? theme.iconSuccessFill : theme.icon, iconRight: Expensicons.CheckCircle, diff --git a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx index a3b914192284..10cce86ac08e 100644 --- a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx +++ b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx @@ -69,7 +69,7 @@ function TroubleshootPage({shouldStoreLogs, shouldMaskOnyxState}: TroubleshootPa const menuItems = useMemo(() => { const debugConsoleItem: BaseMenuItem = { translationKey: 'initialSettingsPage.troubleshoot.viewConsole', - icon: Expensicons.Gear, + icon: Expensicons.Bug, action: waitForNavigate(() => Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(ROUTES.SETTINGS_TROUBLESHOOT))), }; From c158a4a643be3232dfe5f905c20d8f65182dc21d Mon Sep 17 00:00:00 2001 From: hurali97 Date: Wed, 24 Jul 2024 17:21:48 +0500 Subject: [PATCH 08/41] feat: add filter option to debug console --- src/pages/settings/AboutPage/ConsolePage.tsx | 33 +++++++++----------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx index d6880a3ff052..97961138b280 100644 --- a/src/pages/settings/AboutPage/ConsolePage.tsx +++ b/src/pages/settings/AboutPage/ConsolePage.tsx @@ -1,7 +1,7 @@ import type {RouteProp} from '@react-navigation/native'; import {useRoute} from '@react-navigation/native'; import {format} from 'date-fns'; -import React, {useCallback, useEffect, useMemo, useState} from 'react'; +import React, {useCallback, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {ListRenderItem, ListRenderItemInfo} from 'react-native'; import {withOnyx} from 'react-native-onyx'; @@ -44,13 +44,12 @@ type ConsolePageProps = ConsolePageOnyxProps; const filterBy = { all: '', - network: '-[Network]-', + network: '[Network]', } as const; type FilterBy = (typeof filterBy)[keyof typeof filterBy]; function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { const [input, setInput] = useState(''); - const [logs, setLogs] = useState(capturedLogs); const [isGeneratingLogsFile, setIsGeneratingLogsFile] = useState(false); const [isLimitModalVisible, setIsLimitModalVisible] = useState(false); const [activeFilterIndex, setActiveFilterIndex] = useState(filterBy.all); @@ -92,24 +91,22 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { [activeFilterIndex, theme.icon, theme.iconSuccessFill, translate], ); - const logsList = useMemo( - () => - Object.entries(logs ?? {}) - .map(([key, value]) => ({key, ...value})) - .reverse(), - [logs], - ); - - const filteredLogsList = useMemo(() => logsList.filter((log) => log.message.includes(activeFilterIndex)), [activeFilterIndex, logsList]); - - useEffect(() => { + const prevLogs = useRef>({}); + const getLogs = useCallback(() => { if (!shouldStoreLogs) { - return; + return []; } - setLogs((prevLogs) => ({...prevLogs, ...capturedLogs})); + prevLogs.current = {...prevLogs.current, ...capturedLogs}; + return Object.entries(prevLogs.current ?? {}) + .map(([key, value]) => ({key, ...value})) + .reverse(); }, [capturedLogs, shouldStoreLogs]); + const logsList = useMemo(() => getLogs(), [getLogs]); + + const filteredLogsList = useMemo(() => logsList.filter((log) => log.message.includes(activeFilterIndex)), [activeFilterIndex, logsList]); + const executeArbitraryCode = () => { const sanitizedInput = sanitizeConsoleInput(input); @@ -121,14 +118,14 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, executeArbitraryCode); const saveLogs = () => { - const logsWithParsedMessages = parseStringifiedMessages(logsList); + const logsWithParsedMessages = parseStringifiedMessages(filteredLogsList); localFileDownload('logs', JSON.stringify(logsWithParsedMessages, null, 2)); }; const shareLogs = () => { setIsGeneratingLogsFile(true); - const logsWithParsedMessages = parseStringifiedMessages(logsList); + const logsWithParsedMessages = parseStringifiedMessages(filteredLogsList); // Generate a file with the logs and pass its path to the list of reports to share it with localFileCreate('logs', JSON.stringify(logsWithParsedMessages, null, 2)).then(({path, size}) => { From fa2d0b34ffa6ddccc03e7fadb824b75b5456d28f Mon Sep 17 00:00:00 2001 From: hurali97 Date: Wed, 24 Jul 2024 17:22:34 +0500 Subject: [PATCH 09/41] feat: add extraData parameter for Logs --- src/libs/Console/index.ts | 12 ++++++------ src/libs/Log.ts | 6 +++--- src/types/onyx/Console.ts | 3 +++ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/libs/Console/index.ts b/src/libs/Console/index.ts index 9bbdb173e61b..153008e2b785 100644 --- a/src/libs/Console/index.ts +++ b/src/libs/Console/index.ts @@ -53,7 +53,7 @@ function logMessage(args: unknown[]) { return String(arg); }) .join(' '); - const newLog = {time: new Date(), level: CONST.DEBUG_CONSOLE.LEVELS.INFO, message}; + const newLog = {time: new Date(), level: CONST.DEBUG_CONSOLE.LEVELS.INFO, message, extraData: ''}; addLog(newLog); } @@ -105,15 +105,15 @@ function createLog(text: string) { if (result !== undefined) { return [ - {time, level: CONST.DEBUG_CONSOLE.LEVELS.INFO, message: `> ${text}`}, - {time, level: CONST.DEBUG_CONSOLE.LEVELS.RESULT, message: String(result)}, + {time, level: CONST.DEBUG_CONSOLE.LEVELS.INFO, message: `> ${text}`, extraData: ''}, + {time, level: CONST.DEBUG_CONSOLE.LEVELS.RESULT, message: String(result), extraData: ''}, ]; } - return [{time, level: CONST.DEBUG_CONSOLE.LEVELS.INFO, message: `> ${text}`}]; + return [{time, level: CONST.DEBUG_CONSOLE.LEVELS.INFO, message: `> ${text}`, extraData: ''}]; } catch (error) { return [ - {time, level: CONST.DEBUG_CONSOLE.LEVELS.ERROR, message: `> ${text}`}, - {time, level: CONST.DEBUG_CONSOLE.LEVELS.ERROR, message: `Error: ${(error as Error).message}`}, + {time, level: CONST.DEBUG_CONSOLE.LEVELS.ERROR, message: `> ${text}`, extraData: ''}, + {time, level: CONST.DEBUG_CONSOLE.LEVELS.ERROR, message: `Error: ${(error as Error).message}`, extraData: ''}, ]; } } diff --git a/src/libs/Log.ts b/src/libs/Log.ts index 83965807263a..eefe383034e1 100644 --- a/src/libs/Log.ts +++ b/src/libs/Log.ts @@ -66,15 +66,15 @@ function serverLoggingCallback(logger: Logger, params: ServerLoggingCallbackOpti // callback methods are passed in here so we can decouple the logging library from the logging methods. const Log = new Logger({ serverLoggingCallback, - clientLoggingCallback: (message) => { + clientLoggingCallback: (message, extraData) => { if (!shouldAttachLog(message)) { return; } - console.debug(message); + console.debug(message, extraData); if (shouldCollectLogs) { - addLog({time: new Date(), level: CONST.DEBUG_CONSOLE.LEVELS.DEBUG, message}); + addLog({time: new Date(), level: CONST.DEBUG_CONSOLE.LEVELS.DEBUG, message, extraData}); } }, isDebug: true, diff --git a/src/types/onyx/Console.ts b/src/types/onyx/Console.ts index c8d2b714ae2b..03c76b6912b5 100644 --- a/src/types/onyx/Console.ts +++ b/src/types/onyx/Console.ts @@ -10,6 +10,9 @@ type Log = { /** Log message */ message: string; + + /** Additional data */ + extraData: string | Record | Array> | Error; }; /** Record of captured logs */ From 7249b23a947d74e070c4f31103e4a1e5d2b6e4f7 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Wed, 24 Jul 2024 18:02:08 +0500 Subject: [PATCH 10/41] feat: clear the Logs onyx state each time the app is launched --- src/libs/actions/Console.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Console.ts b/src/libs/actions/Console.ts index 79276d3307ac..e2c4047c43b5 100644 --- a/src/libs/actions/Console.ts +++ b/src/libs/actions/Console.ts @@ -2,14 +2,27 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Log} from '@src/types/onyx'; +let isNewAppLaunch = true; /** * Merge the new log into the existing logs in Onyx * @param log the log to add */ function addLog(log: Log) { - Onyx.merge(ONYXKEYS.LOGS, { - [log.time.getTime()]: log, - }); + /** + * If this is the new app launch, we want to reset the log state in Onyx. + * This is because we don't want to keep logs from previous sessions and + * blow up the Onyx state. + */ + if (isNewAppLaunch) { + isNewAppLaunch = false; + Onyx.set(ONYXKEYS.LOGS, { + [log.time.getTime()]: log, + }); + } else { + Onyx.merge(ONYXKEYS.LOGS, { + [log.time.getTime()]: log, + }); + } } /** From eeb7f33d9b4ce2e5f8c6f8895266bc662848e6e6 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Wed, 24 Jul 2024 18:04:23 +0500 Subject: [PATCH 11/41] feat: Do not include request and response for Pusher authentication --- src/libs/Middleware/Logging.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/libs/Middleware/Logging.ts b/src/libs/Middleware/Logging.ts index f10e8d2f5120..d327dd06becc 100644 --- a/src/libs/Middleware/Logging.ts +++ b/src/libs/Middleware/Logging.ts @@ -32,15 +32,25 @@ function logRequestDetails(message: string, request: Request, response?: Respons logParams.requestID = response.requestID; } - Log.info(message, false, logParams); + const extraData: Record = {}; + /** + * We don't want to log the request and response data for AuthenticatePusher + * requests because they contain sensitive information. + */ + if (request.command !== 'AuthenticatePusher') { + extraData.request = request; + extraData.response = response; + } + + Log.info(message, false, logParams, false, extraData); } const Logging: Middleware = (response, request) => { const startTime = Date.now(); - logRequestDetails('Making API request', request); + logRequestDetails('[Network] Making API request', request); return response .then((data) => { - logRequestDetails(`Finished API request in ${Date.now() - startTime}ms`, request, data); + logRequestDetails(`[Network] Finished API request in ${Date.now() - startTime}ms`, request, data); return data; }) .catch((error: HttpsError) => { From fe66ee143bcdeede810359f5c4f4e224140d490e Mon Sep 17 00:00:00 2001 From: hurali97 Date: Wed, 24 Jul 2024 18:04:47 +0500 Subject: [PATCH 12/41] refactor: remove unused code --- src/libs/actions/OnyxUpdates.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/actions/OnyxUpdates.ts b/src/libs/actions/OnyxUpdates.ts index 6769fa7e64a3..672f325be58a 100644 --- a/src/libs/actions/OnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdates.ts @@ -35,8 +35,6 @@ function applyHTTPSOnyxUpdates(request: Request, response: Response) { // apply successData or failureData. This ensures that we do not update any pending, loading, or other UI states contained // in successData/failureData until after the component has received and API data. const onyxDataUpdatePromise = response.onyxData ? updateHandler(response.onyxData) : Promise.resolve(); - Log.info('[OnyxUpdateManager]-[Network]-[Request]', false, request); - Log.info('[OnyxUpdateManager]-[Network]-[Response]', false, response); return onyxDataUpdatePromise .then(() => { // Handle the request's success/failure data (client-side data) From 46c3f7832638cfe40dadb42eeaab3bd7eb272aa8 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Thu, 25 Jul 2024 15:58:53 +0500 Subject: [PATCH 13/41] feat: flush all logs on each app launch --- src/libs/Log.ts | 13 +++++++------ src/libs/actions/Console.ts | 33 +++++++++++++++++---------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/libs/Log.ts b/src/libs/Log.ts index eefe383034e1..72673b8d3f79 100644 --- a/src/libs/Log.ts +++ b/src/libs/Log.ts @@ -8,7 +8,7 @@ import type {Merge} from 'type-fest'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import pkg from '../../package.json'; -import {addLog} from './actions/Console'; +import {addLog, flushAllLogsOnAppLaunch} from './actions/Console'; import {shouldAttachLog} from './Console'; import getPlatform from './getPlatform'; import * as Network from './Network'; @@ -71,11 +71,12 @@ const Log = new Logger({ return; } - console.debug(message, extraData); - - if (shouldCollectLogs) { - addLog({time: new Date(), level: CONST.DEBUG_CONSOLE.LEVELS.DEBUG, message, extraData}); - } + flushAllLogsOnAppLaunch().then(() => { + console.debug(message, extraData); + if (shouldCollectLogs) { + addLog({time: new Date(), level: CONST.DEBUG_CONSOLE.LEVELS.DEBUG, message, extraData}); + } + }); }, isDebug: true, }); diff --git a/src/libs/actions/Console.ts b/src/libs/actions/Console.ts index e2c4047c43b5..6e585c6ad12d 100644 --- a/src/libs/actions/Console.ts +++ b/src/libs/actions/Console.ts @@ -8,21 +8,9 @@ let isNewAppLaunch = true; * @param log the log to add */ function addLog(log: Log) { - /** - * If this is the new app launch, we want to reset the log state in Onyx. - * This is because we don't want to keep logs from previous sessions and - * blow up the Onyx state. - */ - if (isNewAppLaunch) { - isNewAppLaunch = false; - Onyx.set(ONYXKEYS.LOGS, { - [log.time.getTime()]: log, - }); - } else { - Onyx.merge(ONYXKEYS.LOGS, { - [log.time.getTime()]: log, - }); - } + Onyx.merge(ONYXKEYS.LOGS, { + [log.time.getTime()]: log, + }); } /** @@ -41,4 +29,17 @@ function disableLoggingAndFlushLogs() { Onyx.set(ONYXKEYS.LOGS, null); } -export {addLog, setShouldStoreLogs, disableLoggingAndFlushLogs}; +/** + * Clears the persisted logs on app launch, + * so that we have fresh logs for the new app session. + */ +function flushAllLogsOnAppLaunch() { + if (!isNewAppLaunch) { + return Promise.resolve(); + } + + isNewAppLaunch = false; + return Onyx.set(ONYXKEYS.LOGS, {}); +} + +export {addLog, setShouldStoreLogs, disableLoggingAndFlushLogs, flushAllLogsOnAppLaunch}; From 50fb3dc6e55d4ed2f0335276a5671106605a3496 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Fri, 26 Jul 2024 15:05:07 +0500 Subject: [PATCH 14/41] feat: use correct filter icon and adjust the popup position for web and desktop --- assets/images/filter.svg | 11 +++++++++++ src/components/HeaderWithBackButton/index.tsx | 4 ++++ src/components/HeaderWithBackButton/types.ts | 6 ++++++ src/components/Icon/Expensicons.ts | 2 ++ src/pages/settings/AboutPage/ConsolePage.tsx | 6 +++++- 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 assets/images/filter.svg diff --git a/assets/images/filter.svg b/assets/images/filter.svg new file mode 100644 index 000000000000..9323573df12c --- /dev/null +++ b/assets/images/filter.svg @@ -0,0 +1,11 @@ + + + + + diff --git a/src/components/HeaderWithBackButton/index.tsx b/src/components/HeaderWithBackButton/index.tsx index 2d73e3c2dd24..f1e715bface8 100755 --- a/src/components/HeaderWithBackButton/index.tsx +++ b/src/components/HeaderWithBackButton/index.tsx @@ -53,6 +53,8 @@ function HeaderWithBackButton({ horizontal: 0, }, threeDotsMenuItems = [], + threeDotsMenuIcon, + threeDotsMenuIconFill, shouldEnableDetailPageNavigation = false, children = null, shouldOverlayDots = false, @@ -234,6 +236,8 @@ function HeaderWithBackButton({ {shouldShowPinButton && !!report && } {shouldShowThreeDotsButton && ( & { /** The anchor position of the menu */ threeDotsAnchorPosition?: AnchorPosition; + /** Icon displayed on the right of the title */ + threeDotsMenuIcon?: IconAsset; + + /** The fill color to pass into the icon. */ + threeDotsMenuIconFill?: string; + /** Whether we should show a close button */ shouldShowCloseButton?: boolean; diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index 487df5594212..bd5fb88112fb 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -81,6 +81,7 @@ import ExpensifyLogoNew from '@assets/images/expensify-logo-new.svg'; import ExpensifyWordmark from '@assets/images/expensify-wordmark.svg'; import EyeDisabled from '@assets/images/eye-disabled.svg'; import Eye from '@assets/images/eye.svg'; +import Filter from '@assets/images/filter.svg'; import Flag from '@assets/images/flag.svg'; import FlagLevelOne from '@assets/images/flag_level_01.svg'; import FlagLevelTwo from '@assets/images/flag_level_02.svg'; @@ -372,4 +373,5 @@ export { CheckCircle, CheckmarkCircle, NetSuiteSquare, + Filter, }; diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx index 97961138b280..eb9b13608039 100644 --- a/src/pages/settings/AboutPage/ConsolePage.tsx +++ b/src/pages/settings/AboutPage/ConsolePage.tsx @@ -19,6 +19,7 @@ import useKeyboardShortcut from '@hooks/useKeyboardShortcut'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; import {addLog} from '@libs/actions/Console'; import {createLog, parseStringifiedMessages, sanitizeConsoleInput} from '@libs/Console'; import type {Log} from '@libs/Console'; @@ -56,7 +57,7 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const theme = useTheme(); - + const {windowWidth} = useWindowDimensions(); const route = useRoute>(); const menuItems: PopoverMenuItem[] = useMemo( @@ -164,6 +165,9 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) { onBackButtonPress={() => Navigation.goBack(route.params?.backTo)} shouldShowThreeDotsButton threeDotsMenuItems={menuItems} + threeDotsAnchorPosition={styles.threeDotsPopoverOffset(windowWidth)} + threeDotsMenuIcon={Expensicons.Filter} + threeDotsMenuIconFill={theme.icon} /> Date: Sat, 27 Jul 2024 01:19:14 +0900 Subject: [PATCH 15/41] fix: null check instead of setting an empty value --- src/components/ButtonWithDropdownMenu/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 094c26a2b387..8096ff8fe4d1 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -139,7 +139,12 @@ function ButtonWithDropdownMenu({ onClose={() => setIsMenuVisible(false)} onItemSelected={() => setIsMenuVisible(false)} anchorPosition={popoverAnchorPosition} - anchorRef={caretButton} + anchorRef={() => { + if (caretButton === null) { + return; + } + return caretButton; + }} withoutOverlay anchorAlignment={anchorAlignment} headerText={menuHeaderText} From 64c133933c2bdf26a77146be3d3c0205b3d1b64a Mon Sep 17 00:00:00 2001 From: jacobkim9881 Date: Sat, 27 Jul 2024 02:35:19 +0900 Subject: [PATCH 16/41] fix: type check failed --- src/components/ButtonWithDropdownMenu/index.tsx | 2 +- src/components/PopoverMenu.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 8096ff8fe4d1..63be95626420 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -141,7 +141,7 @@ function ButtonWithDropdownMenu({ anchorPosition={popoverAnchorPosition} anchorRef={() => { if (caretButton === null) { - return; + return null; } return caretButton; }} diff --git a/src/components/PopoverMenu.tsx b/src/components/PopoverMenu.tsx index bcec153491c9..34d988cc5b58 100644 --- a/src/components/PopoverMenu.tsx +++ b/src/components/PopoverMenu.tsx @@ -61,7 +61,7 @@ type PopoverMenuProps = Partial & { anchorPosition: AnchorPosition; /** Ref of the anchor */ - anchorRef: RefObject; + anchorRef: RefObject; /** Where the popover should be positioned relative to the anchor points. */ anchorAlignment?: AnchorAlignment; From ceb7b4152cec0125957cc63b6894d50eb611a37b Mon Sep 17 00:00:00 2001 From: jacobkim9881 Date: Sat, 27 Jul 2024 02:55:38 +0900 Subject: [PATCH 17/41] canceled null check --- src/components/ButtonWithDropdownMenu/index.tsx | 2 +- src/components/PopoverMenu.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 8096ff8fe4d1..63be95626420 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -141,7 +141,7 @@ function ButtonWithDropdownMenu({ anchorPosition={popoverAnchorPosition} anchorRef={() => { if (caretButton === null) { - return; + return null; } return caretButton; }} diff --git a/src/components/PopoverMenu.tsx b/src/components/PopoverMenu.tsx index bcec153491c9..34d988cc5b58 100644 --- a/src/components/PopoverMenu.tsx +++ b/src/components/PopoverMenu.tsx @@ -61,7 +61,7 @@ type PopoverMenuProps = Partial & { anchorPosition: AnchorPosition; /** Ref of the anchor */ - anchorRef: RefObject; + anchorRef: RefObject; /** Where the popover should be positioned relative to the anchor points. */ anchorAlignment?: AnchorAlignment; From a52a9975698ca43d3ad8c06bead7b4700f8280c8 Mon Sep 17 00:00:00 2001 From: jacobkim9881 Date: Sat, 27 Jul 2024 03:03:59 +0900 Subject: [PATCH 18/41] canceled null check --- src/components/ButtonWithDropdownMenu/index.tsx | 2 +- src/components/PopoverMenu.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 63be95626420..8096ff8fe4d1 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -141,7 +141,7 @@ function ButtonWithDropdownMenu({ anchorPosition={popoverAnchorPosition} anchorRef={() => { if (caretButton === null) { - return null; + return; } return caretButton; }} diff --git a/src/components/PopoverMenu.tsx b/src/components/PopoverMenu.tsx index 34d988cc5b58..bcec153491c9 100644 --- a/src/components/PopoverMenu.tsx +++ b/src/components/PopoverMenu.tsx @@ -61,7 +61,7 @@ type PopoverMenuProps = Partial & { anchorPosition: AnchorPosition; /** Ref of the anchor */ - anchorRef: RefObject; + anchorRef: RefObject; /** Where the popover should be positioned relative to the anchor points. */ anchorAlignment?: AnchorAlignment; From 89d1ae18e01d3e32c24f3d606e5a0c2ca508ec11 Mon Sep 17 00:00:00 2001 From: jacobkim9881 Date: Sun, 28 Jul 2024 10:00:42 +0900 Subject: [PATCH 19/41] fix typecheck, lint not passed --- src/components/ButtonWithDropdownMenu/index.tsx | 9 +++------ src/types/utils/nullCheckRef.ts | 11 +++++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 src/types/utils/nullCheckRef.ts diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 8096ff8fe4d1..379458db0729 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -10,6 +10,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import CONST from '@src/CONST'; import type {AnchorPosition} from '@src/styles'; +import nullCheckRef from '@src/types/utils/nullCheckRef'; import type {ButtonWithDropdownMenuProps} from './types'; function ButtonWithDropdownMenu({ @@ -42,6 +43,7 @@ function ButtonWithDropdownMenu({ const [popoverAnchorPosition, setPopoverAnchorPosition] = useState(null); const {windowWidth, windowHeight} = useWindowDimensions(); const caretButton = useRef(null); + const nullRef = useRef(null); const selectedItem = options[selectedItemIndex] || options[0]; const innerStyleDropButton = StyleUtils.getDropDownButtonHeight(buttonSize); const isButtonSizeLarge = buttonSize === CONST.DROPDOWN_BUTTON_SIZE.LARGE; @@ -139,12 +141,7 @@ function ButtonWithDropdownMenu({ onClose={() => setIsMenuVisible(false)} onItemSelected={() => setIsMenuVisible(false)} anchorPosition={popoverAnchorPosition} - anchorRef={() => { - if (caretButton === null) { - return; - } - return caretButton; - }} + anchorRef={nullCheckRef(caretButton, nullRef)} withoutOverlay anchorAlignment={anchorAlignment} headerText={menuHeaderText} diff --git a/src/types/utils/nullCheckRef.ts b/src/types/utils/nullCheckRef.ts new file mode 100644 index 000000000000..f43db5d8e922 --- /dev/null +++ b/src/types/utils/nullCheckRef.ts @@ -0,0 +1,11 @@ +import type {MutableRefObject} from 'react'; +import type {View} from 'react-native'; + +function nullCheckRef(ref: MutableRefObject, nullRef: MutableRefObject): MutableRefObject { + if (ref === null) { + return nullRef; + } + return ref; +} + +export default nullCheckRef; From e1404d0afc7a60eed85605d9a4378844ebd91585 Mon Sep 17 00:00:00 2001 From: jacobkim9881 Date: Sun, 28 Jul 2024 14:38:27 +0900 Subject: [PATCH 20/41] fix added null check in the script --- src/components/ButtonWithDropdownMenu/index.tsx | 6 +++--- src/types/utils/nullCheckRef.ts | 11 ----------- 2 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 src/types/utils/nullCheckRef.ts diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 379458db0729..5e65875a7e40 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -1,3 +1,4 @@ +import type {MutableRefObject} from 'react'; import React, {useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; import Button from '@components/Button'; @@ -10,7 +11,6 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import CONST from '@src/CONST'; import type {AnchorPosition} from '@src/styles'; -import nullCheckRef from '@src/types/utils/nullCheckRef'; import type {ButtonWithDropdownMenuProps} from './types'; function ButtonWithDropdownMenu({ @@ -43,10 +43,10 @@ function ButtonWithDropdownMenu({ const [popoverAnchorPosition, setPopoverAnchorPosition] = useState(null); const {windowWidth, windowHeight} = useWindowDimensions(); const caretButton = useRef(null); - const nullRef = useRef(null); const selectedItem = options[selectedItemIndex] || options[0]; const innerStyleDropButton = StyleUtils.getDropDownButtonHeight(buttonSize); const isButtonSizeLarge = buttonSize === CONST.DROPDOWN_BUTTON_SIZE.LARGE; + const nullCheckRef = (ref: MutableRefObject) => ref ?? null; useEffect(() => { if (!caretButton.current) { @@ -141,7 +141,7 @@ function ButtonWithDropdownMenu({ onClose={() => setIsMenuVisible(false)} onItemSelected={() => setIsMenuVisible(false)} anchorPosition={popoverAnchorPosition} - anchorRef={nullCheckRef(caretButton, nullRef)} + anchorRef={nullCheckRef(caretButton)} withoutOverlay anchorAlignment={anchorAlignment} headerText={menuHeaderText} diff --git a/src/types/utils/nullCheckRef.ts b/src/types/utils/nullCheckRef.ts deleted file mode 100644 index f43db5d8e922..000000000000 --- a/src/types/utils/nullCheckRef.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type {MutableRefObject} from 'react'; -import type {View} from 'react-native'; - -function nullCheckRef(ref: MutableRefObject, nullRef: MutableRefObject): MutableRefObject { - if (ref === null) { - return nullRef; - } - return ref; -} - -export default nullCheckRef; From 5609006d769bebccf4d632d251b88f1060941e93 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Tue, 30 Jul 2024 15:37:07 +0500 Subject: [PATCH 21/41] chore: bump expensify-common --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index beea26ff027a..95a2888f1706 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "2.0.49", + "expensify-common": "2.0.60", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.11.0", @@ -25759,9 +25759,9 @@ } }, "node_modules/expensify-common": { - "version": "2.0.49", - "resolved": "https://registry.npmjs.org/expensify-common/-/expensify-common-2.0.49.tgz", - "integrity": "sha512-67QbRuR2XEl2RoNLSbyqGWATIbOXPV42azAfs2sqNT6iyWKcOgHUqRkWPhxA0GmSW35lwq66bvgPVsQUfMGCow==", + "version": "2.0.60", + "resolved": "https://registry.npmjs.org/expensify-common/-/expensify-common-2.0.60.tgz", + "integrity": "sha512-s09uSewbOpPFwqvkw/sQA/T30joE6nAhQSWu1I6elUxIp0evw/Gj7IKTU+1F3vWr3u9N+KlZgCn5YJex9us2yw==", "dependencies": { "awesome-phonenumber": "^5.4.0", "classnames": "2.5.0", diff --git a/package.json b/package.json index 896d6695cca0..49b31fe7d401 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "2.0.49", + "expensify-common": "2.0.60", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.11.0", From 7d342ce703ff35ce7ea4652dad85219a5753702c Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Tue, 30 Jul 2024 12:38:04 +0200 Subject: [PATCH 22/41] map empty entity to top level --- src/languages/en.ts | 1 + .../accounting/PolicyAccountingPage.tsx | 2 +- .../intacct/SageIntacctEntityPage.tsx | 21 ++++++++++++------- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 32b9a9eff2b6..a8ef5452af18 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2077,6 +2077,7 @@ export default { letsDoubleCheck: "Let's double check that everything looks right.", lineItemLevel: 'Line-item level', reportLevel: 'Report level', + topLevel: 'Top level', appliedOnExport: 'Not imported into Expensify, applied on export', shareNote: { header: 'Easily share your workspace with other members.', diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index 89bbfd75d538..46a8b53e3fc4 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -276,7 +276,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) { : { description: translate('workspace.intacct.entity'), iconRight: Expensicons.ArrowRight, - title: getCurrentSageIntacctEntityName(policy), + title: getCurrentSageIntacctEntityName(policy) ?? translate('workspace.common.topLevel'), wrapperStyle: [styles.sectionMenuItemTopDescription], titleStyle: styles.fontWeightNormal, shouldShowRightIcon: true, diff --git a/src/pages/workspace/accounting/intacct/SageIntacctEntityPage.tsx b/src/pages/workspace/accounting/intacct/SageIntacctEntityPage.tsx index abdea52d0df9..837a9d900cd2 100644 --- a/src/pages/workspace/accounting/intacct/SageIntacctEntityPage.tsx +++ b/src/pages/workspace/accounting/intacct/SageIntacctEntityPage.tsx @@ -2,6 +2,7 @@ import React from 'react'; import RadioListItem from '@components/SelectionList/RadioListItem'; import type {ListItem} from '@components/SelectionList/types'; import SelectionScreen from '@components/SelectionScreen'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import {clearSageIntacctErrorField, updateSageIntacctEntity} from '@libs/actions/connections/SageIntacct'; import * as ErrorUtils from '@libs/ErrorUtils'; @@ -14,22 +15,28 @@ function SageIntacctEntityPage({policy}: WithPolicyProps) { const styles = useThemeStyles(); const config = policy?.connections?.intacct?.config; const entityID = config?.entity ?? ''; + const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; - const sections = - policy?.connections?.intacct?.data?.entities.map((entity) => ({ + const sections = [ + { + text: translate('workspace.common.topLevel'), + value: translate('workspace.common.topLevel'), + keyForList: '', + isSelected: entityID === '', + }, + ]; + policy?.connections?.intacct?.data?.entities.forEach((entity) => { + sections.push({ text: entity.name, value: entity.name, keyForList: entity.id, isSelected: entity.id === entityID, - })) ?? []; + }); + }); const saveSelection = ({keyForList}: ListItem) => { - if (!keyForList) { - return; - } - updateSageIntacctEntity(policyID, keyForList ?? ''); Navigation.goBack(); }; From 90b3b9df920026aeaf1fdd9934ba591246b8f405 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Tue, 30 Jul 2024 12:46:10 +0200 Subject: [PATCH 23/41] add intacctImportDimensions translation --- src/languages/en.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index a8ef5452af18..9272633a2fb0 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3205,6 +3205,8 @@ export default { return 'Marking NetSuite bills and invoices as paid'; case 'intacctCheckConnection': return 'Checking Sage Intacct connection'; + case 'intacctImportDimensions': + return 'Importing Sage Intacct dimensions'; case 'intacctImportTitle': return 'Importing Sage Intacct data'; default: { From 70d4ae2aebf89fce2c86252759e7ca718d30eb0e Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Tue, 30 Jul 2024 13:06:24 +0200 Subject: [PATCH 24/41] add spanish translation --- src/languages/es.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/languages/es.ts b/src/languages/es.ts index 1636512a6fa4..4b49251b228d 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2125,6 +2125,7 @@ export default { reuseExistingConnection: 'Reutilizar la conexión existente', existingConnections: 'Conexiones existentes', lastSyncDate: (connectionName: string, formattedDate: string) => `${connectionName} - Última sincronización ${formattedDate}`, + topLevel: 'Nivel superior', }, qbo: { importDescription: 'Elige que configuraciónes de codificación son importadas desde QuickBooks Online a Expensify.', From 5913244652b5637e5bc951880cd7b245b7591f79 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Tue, 30 Jul 2024 15:24:11 +0200 Subject: [PATCH 25/41] make employee default option only viable for departments, classes and locations mappings --- .../import/SageIntacctMappingsTypePage.tsx | 53 +++++++++++-------- .../import/SageIntacctToggleMappingsPage.tsx | 2 +- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx index 57ebac617393..7e0decc5243e 100644 --- a/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx +++ b/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx @@ -23,33 +23,44 @@ function SageIntacctMappingsTypePage({route}: SageIntacctMappingsTypePageProps) const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${route.params.policyID ?? '-1'}`); const policyID = policy?.id ?? '-1'; const mappings = policy?.connections?.intacct?.config?.mappings; + const exportConfig = policy?.connections?.intacct?.config?.export; - const selectionOptions = useMemo( - () => [ - { + const selectionOptions = useMemo(() => { + const mappingOptions: SelectorType[] = []; + if ( + mappingName !== CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CUSTOMERS && + mappingName !== CONST.SAGE_INTACCT_CONFIG.MAPPINGS.PROJECTS && + exportConfig?.reimbursable !== CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL + ) { + mappingOptions.push({ value: CONST.SAGE_INTACCT_MAPPING_VALUE.DEFAULT, text: translate('workspace.intacct.employeeDefault'), alternateText: translate('workspace.common.appliedOnExport'), keyForList: CONST.SAGE_INTACCT_MAPPING_VALUE.DEFAULT, isSelected: mappings?.[mappingName] === CONST.SAGE_INTACCT_MAPPING_VALUE.DEFAULT, - }, - { - value: CONST.SAGE_INTACCT_MAPPING_VALUE.TAG, - text: translate('workspace.common.tags'), - alternateText: translate('workspace.common.lineItemLevel'), - keyForList: CONST.SAGE_INTACCT_MAPPING_VALUE.TAG, - isSelected: mappings?.[mappingName] === CONST.SAGE_INTACCT_MAPPING_VALUE.TAG, - }, - { - value: CONST.SAGE_INTACCT_MAPPING_VALUE.REPORT_FIELD, - text: translate('workspace.common.reportFields'), - alternateText: translate('workspace.common.reportLevel'), - keyForList: CONST.SAGE_INTACCT_MAPPING_VALUE.REPORT_FIELD, - isSelected: mappings?.[mappingName] === CONST.SAGE_INTACCT_MAPPING_VALUE.REPORT_FIELD, - }, - ], - [mappingName, mappings, translate], - ); + }); + } + mappingOptions.push( + ...[ + { + value: CONST.SAGE_INTACCT_MAPPING_VALUE.TAG, + text: translate('workspace.common.tags'), + alternateText: translate('workspace.common.lineItemLevel'), + keyForList: CONST.SAGE_INTACCT_MAPPING_VALUE.TAG, + isSelected: mappings?.[mappingName] === CONST.SAGE_INTACCT_MAPPING_VALUE.TAG, + }, + { + value: CONST.SAGE_INTACCT_MAPPING_VALUE.REPORT_FIELD, + text: translate('workspace.common.reportFields'), + alternateText: translate('workspace.common.reportLevel'), + keyForList: CONST.SAGE_INTACCT_MAPPING_VALUE.REPORT_FIELD, + isSelected: mappings?.[mappingName] === CONST.SAGE_INTACCT_MAPPING_VALUE.REPORT_FIELD, + }, + ], + ); + + return mappingOptions; + }, [exportConfig?.reimbursable, mappingName, mappings, translate]); const updateMapping = useCallback( ({value}: SelectorType) => { diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage.tsx index c76a9f0e26bc..1d43f3431db4 100644 --- a/src/pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage.tsx +++ b/src/pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage.tsx @@ -92,7 +92,7 @@ function SageIntacctToggleMappingsPage({route}: SageIntacctToggleMappingsPagePro updateSageIntacctMappingValue(policyID, mappingName, CONST.SAGE_INTACCT_MAPPING_VALUE.NONE); } else { setImportMapping(true); - updateSageIntacctMappingValue(policyID, mappingName, CONST.SAGE_INTACCT_MAPPING_VALUE.DEFAULT); + updateSageIntacctMappingValue(policyID, mappingName, CONST.SAGE_INTACCT_MAPPING_VALUE.TAG); } }} /> From 8d197bf783332e5cdfaa0c80a99aec4bf804ebd4 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Tue, 30 Jul 2024 16:32:26 +0200 Subject: [PATCH 26/41] change mapping value to tag when setting reimbrusaible reports to VENDOR_BILL --- src/libs/actions/connections/SageIntacct.ts | 13 +++++++++++++ .../export/SageIntacctReimbursableExpensesPage.tsx | 6 ++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/connections/SageIntacct.ts b/src/libs/actions/connections/SageIntacct.ts index 5ba12173c4e2..9e6dff071699 100644 --- a/src/libs/actions/connections/SageIntacct.ts +++ b/src/libs/actions/connections/SageIntacct.ts @@ -142,6 +142,18 @@ function updateSageIntacctMappingValue(policyID: string, mappingName: SageIntacc ); } +function changeMappingsValueFromDefaultToTag(policyID: string, mappings?: SageIntacctMappingType) { + if (mappings?.departments === CONST.SAGE_INTACCT_MAPPING_VALUE.DEFAULT) { + updateSageIntacctMappingValue(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.DEPARTMENTS, CONST.SAGE_INTACCT_MAPPING_VALUE.TAG); + } + if (mappings?.classes === CONST.SAGE_INTACCT_MAPPING_VALUE.DEFAULT) { + updateSageIntacctMappingValue(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CLASSES, CONST.SAGE_INTACCT_MAPPING_VALUE.TAG); + } + if (mappings?.locations === CONST.SAGE_INTACCT_MAPPING_VALUE.DEFAULT) { + updateSageIntacctMappingValue(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.LOCATIONS, CONST.SAGE_INTACCT_MAPPING_VALUE.TAG); + } +} + function updateSageIntacctSyncTaxConfiguration(policyID: string, enabled: boolean) { const optimisticData: OnyxUpdate[] = [ { @@ -769,4 +781,5 @@ export { updateSageIntacctSyncReimbursedReports, updateSageIntacctSyncReimbursementAccountID, updateSageIntacctEntity, + changeMappingsValueFromDefaultToTag, }; diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx index 7ade41b47a9a..c42a8888070d 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx @@ -15,7 +15,7 @@ import Navigation from '@navigation/Navigation'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; -import {updateSageIntacctDefaultVendor, updateSageIntacctReimbursableExpensesExportDestination} from '@userActions/connections/SageIntacct'; +import {changeMappingsValueFromDefaultToTag, updateSageIntacctDefaultVendor, updateSageIntacctReimbursableExpensesExportDestination} from '@userActions/connections/SageIntacct'; import * as Policy from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -49,10 +49,12 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { updateSageIntacctReimbursableExpensesExportDestination(policyID, row.value); } if (row.value === CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL) { + // Employee default mapping value is not allowed when expense type is VENDOR_BILL, so we have to change mapping value to Tag + changeMappingsValueFromDefaultToTag(policyID, config?.mappings); Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID)); } }, - [reimbursable, policyID], + [reimbursable, policyID, config?.mappings], ); const defaultVendor = useMemo(() => { From e12f06053ed5dbbe3feac9c3c279fe224315d72d Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Wed, 31 Jul 2024 13:10:13 +0700 Subject: [PATCH 27/41] fix: not redirect to workspace chat when pay iou with business account --- src/components/KYCWall/BaseKYCWall.tsx | 10 +++++++--- src/libs/actions/Policy/Policy.ts | 10 ++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index 818b4aff6b00..dcad0e0ba533 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -18,6 +18,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {BankAccountList, FundList, ReimbursementAccount, UserWallet, WalletTerms} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import viewRef from '@src/types/utils/viewRef'; import type {AnchorPosition, DomRect, KYCWallProps, PaymentMethod} from './types'; @@ -67,7 +68,7 @@ function KYCWall({ source, userWallet, walletTerms, - shouldShowPersonalBankAccountOption = false, + shouldShowPersonalBankAccountOption = true, }: BaseKYCWallProps) { const anchorRef = useRef(null); const transferBalanceButtonRef = useRef(null); @@ -127,7 +128,10 @@ function KYCWall({ Navigation.navigate(addDebitCardRoute); } else if (paymentMethod === CONST.PAYMENT_METHODS.BUSINESS_BANK_ACCOUNT) { if (iouReport && ReportUtils.isIOUReport(iouReport)) { - const policyID = Policy.createWorkspaceFromIOUPayment(iouReport); + const {policyID, workspaceChatReportID, reportPreviewReportActionID} = Policy.createWorkspaceFromIOUPayment(iouReport) ?? {}; + if (workspaceChatReportID) { + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(workspaceChatReportID, reportPreviewReportActionID)); + } // Navigate to the bank account set up flow for this specific policy Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('', policyID)); @@ -172,7 +176,7 @@ function KYCWall({ // Check to see if user has a valid payment method on file and display the add payment popover if they don't if ( (isExpenseReport && reimbursementAccount?.achData?.state !== CONST.BANK_ACCOUNT.STATE.OPEN) || - (!isExpenseReport && bankAccountList !== null && !PaymentUtils.hasExpensifyPaymentMethod(paymentCardList, bankAccountList, shouldIncludeDebitCard)) + (!isExpenseReport && isEmptyObject(bankAccountList) && !PaymentUtils.hasExpensifyPaymentMethod(paymentCardList, bankAccountList, shouldIncludeDebitCard)) ) { Log.info('[KYC Wallet] User does not have valid payment method'); diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 1bce525e22bf..49f6d8d03a73 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -107,6 +107,12 @@ type NewCustomUnit = { rates: Rate; }; +type WorkspaceFromIOUCreationData = { + policyID: string; + workspaceChatReportID: string; + reportPreviewReportActionID?: string; +}; + const allPolicies: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.POLICY, @@ -2066,7 +2072,7 @@ function dismissAddedWithPrimaryLoginMessages(policyID: string) { * * @returns policyID of the workspace we have created */ -function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): string | undefined { +function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): WorkspaceFromIOUCreationData | undefined { // This flow only works for IOU reports if (!ReportUtils.isIOUReportUsingReport(iouReport)) { return; @@ -2499,7 +2505,7 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): string | u API.write(WRITE_COMMANDS.CREATE_WORKSPACE_FROM_IOU_PAYMENT, params, {optimisticData, successData, failureData}); - return policyID; + return {policyID, workspaceChatReportID: memberData.workspaceChatReportID, reportPreviewReportActionID: reportPreview?.reportActionID}; } function enablePolicyConnections(policyID: string, enabled: boolean) { From 87834223b13ef182a7ddc79a43fee1362568912b Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Wed, 31 Jul 2024 13:11:21 +0700 Subject: [PATCH 28/41] fix: business bank account is always selected when pay with expensify --- src/components/AddPaymentMethodMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddPaymentMethodMenu.tsx b/src/components/AddPaymentMethodMenu.tsx index 451979b92efa..bd437cbb062d 100644 --- a/src/components/AddPaymentMethodMenu.tsx +++ b/src/components/AddPaymentMethodMenu.tsx @@ -74,7 +74,7 @@ function AddPaymentMethodMenu({ // We temporarily disabled P2P debit cards so we will automatically select the personal bank account option if there is no other option to select. useEffect(() => { - if (!isVisible) { + if (!isVisible || !isPersonalOnlyOption) { return; } From 57a157d15cbb70202dbaf92d595dedb55f3df4bc Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Wed, 31 Jul 2024 13:51:36 +0700 Subject: [PATCH 29/41] revert redundant changes --- src/components/KYCWall/BaseKYCWall.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index dcad0e0ba533..fd681546c470 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -18,7 +18,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {BankAccountList, FundList, ReimbursementAccount, UserWallet, WalletTerms} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; import viewRef from '@src/types/utils/viewRef'; import type {AnchorPosition, DomRect, KYCWallProps, PaymentMethod} from './types'; @@ -68,7 +67,7 @@ function KYCWall({ source, userWallet, walletTerms, - shouldShowPersonalBankAccountOption = true, + shouldShowPersonalBankAccountOption = false, }: BaseKYCWallProps) { const anchorRef = useRef(null); const transferBalanceButtonRef = useRef(null); @@ -176,7 +175,7 @@ function KYCWall({ // Check to see if user has a valid payment method on file and display the add payment popover if they don't if ( (isExpenseReport && reimbursementAccount?.achData?.state !== CONST.BANK_ACCOUNT.STATE.OPEN) || - (!isExpenseReport && isEmptyObject(bankAccountList) && !PaymentUtils.hasExpensifyPaymentMethod(paymentCardList, bankAccountList, shouldIncludeDebitCard)) + (!isExpenseReport && bankAccountList !== null && !PaymentUtils.hasExpensifyPaymentMethod(paymentCardList, bankAccountList, shouldIncludeDebitCard)) ) { Log.info('[KYC Wallet] User does not have valid payment method'); From 6900273fea8a8d0b0faac30c58193b5d9d15c0fd Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Wed, 31 Jul 2024 10:06:49 +0200 Subject: [PATCH 30/41] fix lint --- src/languages/en.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index 9272633a2fb0..c24d33c5b878 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3210,6 +3210,7 @@ export default { case 'intacctImportTitle': return 'Importing Sage Intacct data'; default: { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions return `Translation missing for stage: ${stage}`; } } From 5ce5a41fe5085aaac778456a8ed959013151ea94 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Wed, 31 Jul 2024 10:52:16 +0200 Subject: [PATCH 31/41] fix PR comments --- .../accounting/intacct/import/SageIntacctMappingsTypePage.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx index 7e0decc5243e..4f3de5390cea 100644 --- a/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx +++ b/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx @@ -28,8 +28,7 @@ function SageIntacctMappingsTypePage({route}: SageIntacctMappingsTypePageProps) const selectionOptions = useMemo(() => { const mappingOptions: SelectorType[] = []; if ( - mappingName !== CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CUSTOMERS && - mappingName !== CONST.SAGE_INTACCT_CONFIG.MAPPINGS.PROJECTS && + !([CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CUSTOMERS, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.PROJECTS] as string[]).includes(mappingName) && exportConfig?.reimbursable !== CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL ) { mappingOptions.push({ From 523591eb9aebfe786f80ff3b3570318676447a7c Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Wed, 31 Jul 2024 11:56:36 +0200 Subject: [PATCH 32/41] fix PR comments --- src/libs/PolicyUtils.ts | 5 ++++- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 2 +- .../accounting/intacct/advanced/SageIntacctAdvancedPage.tsx | 2 +- .../accounting/intacct/export/SageIntacctExportPage.tsx | 2 +- .../accounting/intacct/import/SageIntacctImportPage.tsx | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 2f27f0185759..97fd260b07d2 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -756,8 +756,11 @@ function getIntegrationLastSuccessfulDate(connection?: Connections[keyof Connect return (connection as ConnectionWithLastSyncData)?.lastSync?.successfulDate; } -function getCurrentSageIntacctEntityName(policy?: Policy): string | undefined { +function getCurrentSageIntacctEntityName(policy: Policy | undefined, translate: LocaleContextProps['translate']): string | undefined { const currentEntityID = policy?.connections?.intacct?.config?.entity; + if (!currentEntityID) { + return translate('workspace.common.topLevel'); + } const entities = policy?.connections?.intacct?.data?.entities; return entities?.find((entity) => entity.id === currentEntityID)?.name; } diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index 46a8b53e3fc4..79b0a5758ffb 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -276,7 +276,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) { : { description: translate('workspace.intacct.entity'), iconRight: Expensicons.ArrowRight, - title: getCurrentSageIntacctEntityName(policy) ?? translate('workspace.common.topLevel'), + title: getCurrentSageIntacctEntityName(policy, translate), wrapperStyle: [styles.sectionMenuItemTopDescription], titleStyle: styles.fontWeightNormal, shouldShowRightIcon: true, diff --git a/src/pages/workspace/accounting/intacct/advanced/SageIntacctAdvancedPage.tsx b/src/pages/workspace/accounting/intacct/advanced/SageIntacctAdvancedPage.tsx index 2458b8579539..b91791c2ddec 100644 --- a/src/pages/workspace/accounting/intacct/advanced/SageIntacctAdvancedPage.tsx +++ b/src/pages/workspace/accounting/intacct/advanced/SageIntacctAdvancedPage.tsx @@ -100,7 +100,7 @@ function SageIntacctAdvancedPage({policy}: WithPolicyProps) { Date: Wed, 31 Jul 2024 18:16:16 +0200 Subject: [PATCH 33/41] fix: test runner compilation --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 89d2a89aeb42..ec095f081770 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "workflow-test": "./workflow_tests/scripts/runWorkflowTests.sh", "workflow-test:generate": "ts-node workflow_tests/utils/preGenerateTest.ts", "setup-https": "mkcert -install && mkcert -cert-file config/webpack/certificate.pem -key-file config/webpack/key.pem dev.new.expensify.com localhost 127.0.0.1", - "e2e-test-runner-build": "ncc build tests/e2e/testRunner.ts -o tests/e2e/dist/", + "e2e-test-runner-build": "node --max-old-space-size=8192 node_modules/.bin/ncc build tests/e2e/testRunner.ts -o tests/e2e/dist/", "react-compiler-healthcheck": "react-compiler-healthcheck --verbose", "generate-search-parser": "peggy --format es -o src/libs/SearchParser/searchParser.js src/libs/SearchParser/searchParser.peggy " }, From f73e6a94f431f3a1418f1c81c05a7b77a1b7b810 Mon Sep 17 00:00:00 2001 From: jacobkim9881 Date: Thu, 1 Aug 2024 02:27:51 +0900 Subject: [PATCH 34/41] fix: parameter name edited --- src/components/ButtonWithDropdownMenu/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index d0f79a75e451..26b9f7aa1736 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -150,7 +150,7 @@ function ButtonWithDropdownMenu({ onModalShow={onOptionsMenuShow} onItemSelected={() => setIsMenuVisible(false)} anchorPosition={popoverAnchorPosition} - anchorRef={nullCheckRef(caretButton)} + anchorRef={nullCheckRef(dropdownAnchor)} withoutOverlay anchorAlignment={anchorAlignment} headerText={menuHeaderText} From 754fc97b056d9c403251ad81be27ac0b68fe91ca Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Thu, 1 Aug 2024 00:41:52 +0700 Subject: [PATCH 35/41] Revert "fix: business bank account is always selected when pay with expensify" This reverts commit 87834223b13ef182a7ddc79a43fee1362568912b. --- src/components/AddPaymentMethodMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddPaymentMethodMenu.tsx b/src/components/AddPaymentMethodMenu.tsx index bd437cbb062d..451979b92efa 100644 --- a/src/components/AddPaymentMethodMenu.tsx +++ b/src/components/AddPaymentMethodMenu.tsx @@ -74,7 +74,7 @@ function AddPaymentMethodMenu({ // We temporarily disabled P2P debit cards so we will automatically select the personal bank account option if there is no other option to select. useEffect(() => { - if (!isVisible || !isPersonalOnlyOption) { + if (!isVisible) { return; } From 183a1ece4726d7c1c79513b18e672f7b6fabb058 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 1 Aug 2024 19:02:20 +0800 Subject: [PATCH 36/41] don't close expense report when paying --- src/libs/actions/IOU.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index acaf37fc8bf4..b75a81f76775 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7201,7 +7201,6 @@ function payMoneyRequest(paymentType: PaymentMethodType, chatReport: OnyxTypes.R const apiCommand = paymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY ? WRITE_COMMANDS.PAY_MONEY_REQUEST_WITH_WALLET : WRITE_COMMANDS.PAY_MONEY_REQUEST; API.write(apiCommand, params, {optimisticData, successData, failureData}); - Navigation.dismissModalWithReport(chatReport); } function payInvoice(paymentMethodType: PaymentMethodType, chatReport: OnyxTypes.Report, invoiceReport: OnyxTypes.Report) { From 19a76a981e268d9a348b88dcd6a21096488e24f6 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Thu, 1 Aug 2024 13:37:19 +0200 Subject: [PATCH 37/41] fix: announce e2e build failures --- .../composite/buildAndroidE2EAPK/action.yml | 20 +++++++++++++++++++ .github/workflows/e2ePerformanceTests.yml | 4 +++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/.github/actions/composite/buildAndroidE2EAPK/action.yml b/.github/actions/composite/buildAndroidE2EAPK/action.yml index cfce0d3ec7d8..424f6150f01c 100644 --- a/.github/actions/composite/buildAndroidE2EAPK/action.yml +++ b/.github/actions/composite/buildAndroidE2EAPK/action.yml @@ -37,6 +37,9 @@ inputs: EXPENSIFY_PARTNER_PASSWORD_EMAIL: description: The email address of the Expensify partner to use for the build required: true + SLACK_WEBHOOK_URL: + description: 'URL of the slack webhook' + required: true runs: using: composite @@ -75,6 +78,23 @@ runs: env: RUBYOPT: '-rostruct' + - name: Announce failed workflow in Slack + if: failure() + uses: 8398a7/action-slack@v3 + with: + status: custom + custom_payload: | + { + channel: '#e2e-announce', + attachments: [{ + color: 'danger', + text: `💥 ${process.env.AS_REPO} E2E APK build run failed on workflow 💥`, + }] + } + env: + GITHUB_TOKEN: ${{ github.token }} + SLACK_WEBHOOK_URL: ${{ inputs.SLACK_WEBHOOK_URL }} + - name: Upload APK uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 617a7a0abe05..e57556143978 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -68,6 +68,7 @@ jobs: EXPENSIFY_PARTNER_USER_ID: ${{ secrets.EXPENSIFY_PARTNER_USER_ID }} EXPENSIFY_PARTNER_USER_SECRET: ${{ secrets.EXPENSIFY_PARTNER_USER_SECRET }} EXPENSIFY_PARTNER_PASSWORD_EMAIL: ${{ secrets.EXPENSIFY_PARTNER_PASSWORD_EMAIL }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} PATH_ENV_FILE: tests/e2e/.env.e2e buildDelta: @@ -137,6 +138,7 @@ jobs: EXPENSIFY_PARTNER_USER_ID: ${{ secrets.EXPENSIFY_PARTNER_USER_ID }} EXPENSIFY_PARTNER_USER_SECRET: ${{ secrets.EXPENSIFY_PARTNER_USER_SECRET }} EXPENSIFY_PARTNER_PASSWORD_EMAIL: ${{ secrets.EXPENSIFY_PARTNER_PASSWORD_EMAIL }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} PATH_ENV_FILE: tests/e2e/.env.e2edelta runTestsInAWS: @@ -239,7 +241,7 @@ jobs: channel: '#e2e-announce', attachments: [{ color: 'danger', - text: `💥 ${process.env.AS_REPO} E2E Test run failed failed on workflow 💥`, + text: `💥 ${process.env.AS_REPO} E2E Test run failed on workflow 💥`, }] } env: From ed21ec4ed7a3e1286796d0eea0dd301d6d37f580 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Thu, 1 Aug 2024 14:06:55 +0200 Subject: [PATCH 38/41] fix: change emoji to distinguish different error messages --- .github/actions/composite/buildAndroidE2EAPK/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/composite/buildAndroidE2EAPK/action.yml b/.github/actions/composite/buildAndroidE2EAPK/action.yml index 424f6150f01c..25fafcb7be7f 100644 --- a/.github/actions/composite/buildAndroidE2EAPK/action.yml +++ b/.github/actions/composite/buildAndroidE2EAPK/action.yml @@ -88,7 +88,7 @@ runs: channel: '#e2e-announce', attachments: [{ color: 'danger', - text: `💥 ${process.env.AS_REPO} E2E APK build run failed on workflow 💥`, + text: `🚧 ${process.env.AS_REPO} E2E APK build run failed on workflow 🚧`, }] } env: From 157afbf7720049e3b0a92836b440c35f17725c10 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Fri, 2 Aug 2024 01:06:16 +0000 Subject: [PATCH 39/41] Update version to 9.0.16-0 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 4 ++-- ios/NewExpensifyTests/Info.plist | 4 ++-- ios/NotificationServiceExtension/Info.plist | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index fde71504e0ad..7d6ca68780e1 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -108,8 +108,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009001509 - versionName "9.0.15-9" + versionCode 1009001600 + versionName "9.0.16-0" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 2a687935097b..62c5e55c54b8 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 9.0.15 + 9.0.16 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.15.9 + 9.0.16.0 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 255ada428adc..052e4f6b6363 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 9.0.15 + 9.0.16 CFBundleSignature ???? CFBundleVersion - 9.0.15.9 + 9.0.16.0 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 39199339f8e5..dea67213621d 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -11,9 +11,9 @@ CFBundleName $(PRODUCT_NAME) CFBundleShortVersionString - 9.0.15 + 9.0.16 CFBundleVersion - 9.0.15.9 + 9.0.16.0 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index e9908cf50717..d65919cba027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.15-9", + "version": "9.0.16-0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.15-9", + "version": "9.0.16-0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index ef53f2346666..599b7bd20944 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.15-9", + "version": "9.0.16-0", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 9eb969c2d09cb106587bd14f21e5fce87c4a2fad Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 2 Aug 2024 10:20:32 +0700 Subject: [PATCH 40/41] fix: Icons Overflow from Dropdown Button --- src/pages/Search/SearchStatusMenuNarrow.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/pages/Search/SearchStatusMenuNarrow.tsx b/src/pages/Search/SearchStatusMenuNarrow.tsx index 1d10dc1dd431..6e77e6311fb2 100644 --- a/src/pages/Search/SearchStatusMenuNarrow.tsx +++ b/src/pages/Search/SearchStatusMenuNarrow.tsx @@ -79,12 +79,14 @@ function SearchStatusMenuNarrow({statusMenuItems, activeItemIndex, title}: Searc src={menuIcon} fill={theme.icon} /> - - {menuTitle} - + + + {menuTitle} + + Date: Fri, 2 Aug 2024 10:52:17 +0200 Subject: [PATCH 41/41] fix PR comments --- src/libs/PolicyUtils.ts | 4 ++-- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 2 +- .../accounting/intacct/advanced/SageIntacctAdvancedPage.tsx | 2 +- .../accounting/intacct/export/SageIntacctExportPage.tsx | 2 +- .../accounting/intacct/import/SageIntacctImportPage.tsx | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 0cfea5ecb110..709c10d07f6c 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -761,10 +761,10 @@ function getIntegrationLastSuccessfulDate(connection?: Connections[keyof Connect return (connection as ConnectionWithLastSyncData)?.lastSync?.successfulDate; } -function getCurrentSageIntacctEntityName(policy: Policy | undefined, translate: LocaleContextProps['translate']): string | undefined { +function getCurrentSageIntacctEntityName(policy: Policy | undefined, defaultNameIfNoEntity: string): string | undefined { const currentEntityID = policy?.connections?.intacct?.config?.entity; if (!currentEntityID) { - return translate('workspace.common.topLevel'); + return defaultNameIfNoEntity; } const entities = policy?.connections?.intacct?.data?.entities; return entities?.find((entity) => entity.id === currentEntityID)?.name; diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index 551846ec92bc..9202591de7f2 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -303,7 +303,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) { : { description: translate('workspace.intacct.entity'), iconRight: Expensicons.ArrowRight, - title: getCurrentSageIntacctEntityName(policy, translate), + title: getCurrentSageIntacctEntityName(policy, translate('workspace.common.topLevel')), wrapperStyle: [styles.sectionMenuItemTopDescription], titleStyle: styles.fontWeightNormal, shouldShowRightIcon: true, diff --git a/src/pages/workspace/accounting/intacct/advanced/SageIntacctAdvancedPage.tsx b/src/pages/workspace/accounting/intacct/advanced/SageIntacctAdvancedPage.tsx index 2afd08eb53f8..5a0df17fc92c 100644 --- a/src/pages/workspace/accounting/intacct/advanced/SageIntacctAdvancedPage.tsx +++ b/src/pages/workspace/accounting/intacct/advanced/SageIntacctAdvancedPage.tsx @@ -88,7 +88,7 @@ function SageIntacctAdvancedPage({policy}: WithPolicyProps) {