From 46a6c3e52188ce55edad92a107ecbe4b930f825d Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Sun, 21 Apr 2024 18:07:24 +0530
Subject: [PATCH 001/207] Show console debug logs via test tools menu
---
ios/Podfile | 17 ++
src/CONST.ts | 3 +-
src/ROUTES.ts | 2 +-
.../BaseClientSideLoggingToolMenu.tsx | 21 +-
.../ConsoleComponents.tsx | 191 ++++++++++++++++++
.../ConsoleModal.tsx | 64 ++++++
.../index.android.tsx | 4 +-
.../ClientSideLoggingToolMenu/index.ios.tsx | 4 +-
.../ClientSideLoggingToolMenu/index.tsx | 4 +-
src/components/Modal/index.tsx | 2 +-
src/components/TestToolsModal.tsx | 2 +-
src/libs/Navigation/types.ts | 1 +
src/pages/settings/AboutPage/ConsolePage.tsx | 158 +--------------
.../ShareLogList/BaseShareLogList.tsx | 10 +-
.../AboutPage/ShareLogList/index.native.tsx | 4 +-
.../settings/AboutPage/ShareLogList/index.tsx | 4 +-
src/pages/settings/AboutPage/ShareLogPage.tsx | 2 +-
.../utils/generators/ModalStyleUtils.ts | 23 +++
18 files changed, 345 insertions(+), 171 deletions(-)
create mode 100644 src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
create mode 100644 src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
diff --git a/ios/Podfile b/ios/Podfile
index 4f00eb2adfdd..0c524878e5f7 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -1,3 +1,5 @@
+use_frameworks! :linkage => :static
+
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
# Set the type of Mapbox SDK to use
# This value is used by $RNMapboxMaps
@@ -111,6 +113,21 @@ target 'NewExpensify' do
end
end
end
+
+ deployment_target = '13.4'
+
+ installer.generated_projects.each do |project|
+ project.targets.each do |target|
+ target.build_configurations.each do |config|
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
+ end
+ end
+ project.build_configurations.each do |config|
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
+ end
+ end
+
+ `sed -i -e $'s/__IPHONE_10_0/__IPHONE_15_0/' #{installer.sandbox.root}/RCT-Folly/folly/portability/Time.h`
end
end
diff --git a/src/CONST.ts b/src/CONST.ts
index 2cd614b74816..4ded9e282d3e 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -860,6 +860,7 @@ const CONST = {
POPOVER: 'popover',
RIGHT_DOCKED: 'right_docked',
ONBOARDING: 'onboarding',
+ CENTERED_SMALL_AND_UNSWIPEABLE: 'centered_small_and_unswipeable'
},
ANCHOR_ORIGIN_VERTICAL: {
TOP: 'top',
@@ -3100,7 +3101,7 @@ const CONST = {
// Test tool menu parameters
TEST_TOOL: {
// Number of concurrent taps to open then the Test modal menu
- NUMBER_OF_TAPS: 4,
+ NUMBER_OF_TAPS: 2,
},
MENU_HELP_URLS: {
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index ceb4c217cb6e..71e673aea994 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -175,7 +175,7 @@ const ROUTES = {
SETTINGS_CONSOLE: 'settings/troubleshoot/console',
SETTINGS_SHARE_LOG: {
route: 'settings/troubleshoot/console/share-log',
- getRoute: (source: string) => `settings/troubleshoot/console/share-log?source=${encodeURI(source)}` as const,
+ getRoute: (source: string, isViaTestToolsModal = false) => `settings/troubleshoot/console/share-log?source=${encodeURI(source)}&isViaTestToolsModal=${isViaTestToolsModal}` as const,
},
SETTINGS_EXIT_SURVEY_REASON: 'settings/exit-survey/reason',
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index fcad770908a6..a6bb085c949a 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, {useState} from 'react';
import {Alert} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
@@ -12,6 +12,7 @@ import * as Console from '@libs/actions/Console';
import {parseStringifiedMessages} from '@libs/Console';
import ONYXKEYS from '@src/ONYXKEYS';
import type {CapturedLogs, Log} from '@src/types/onyx';
+import ConsoleModal from "@components/ClientSideLoggingToolMenu/ConsoleModal";
type BaseClientSideLoggingToolMenuOnyxProps = {
/** Logs captured on the current device */
@@ -30,9 +31,11 @@ type BaseClientSideLoggingToolProps = {
onDisableLogging: (logs: Log[]) => void;
/** Action to run when enabling logging */
onEnableLogging?: () => void;
+ /** Boolean to know if this was opened via test tools modal */
+ isViaTestToolsModal: boolean
} & BaseClientSideLoggingToolMenuOnyxProps;
-function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onShareLogs, onDisableLogging, onEnableLogging}: BaseClientSideLoggingToolProps) {
+function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onShareLogs, onDisableLogging, onEnableLogging, isViaTestToolsModal, closeTestToolsModal}: BaseClientSideLoggingToolProps) {
const {translate} = useLocalize();
const onToggle = () => {
@@ -59,6 +62,8 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
Console.disableLoggingAndFlushLogs();
};
const styles = useThemeStyles();
+ const [isConsoleModalVisible, setIsConsoleModalVisible] = useState(false);
+
return (
<>
@@ -68,6 +73,15 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
onToggle={onToggle}
/>
+ {!!shouldStoreLogs && isViaTestToolsModal &&
+
+
+ }
{!!file && (
<>
{`path: ${file.path}`}
@@ -80,6 +94,9 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
>
)}
+ {
+ setIsConsoleModalVisible(false)
+ }} closeTestToolsModal={closeTestToolsModal}/>
>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx b/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
new file mode 100644
index 000000000000..5de7de0e049e
--- /dev/null
+++ b/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
@@ -0,0 +1,191 @@
+import React, {useCallback, useEffect, useMemo, useState} from 'react';
+import {ListRenderItem, ListRenderItemInfo, View} from 'react-native';
+import CONST from "@src/CONST";
+import useThemeStyles from "@hooks/useThemeStyles";
+import useLocalize from "@hooks/useLocalize";
+import InvertedFlatList from "@components/InvertedFlatList";
+import Text from "@components/Text";
+import {CapturedLogs, Log} from "@src/types/onyx";
+import {format} from "date-fns";
+import {OnyxEntry, withOnyx} from "react-native-onyx";
+import ONYXKEYS from "@src/ONYXKEYS";
+import {createLog, parseStringifiedMessages, sanitizeConsoleInput} from "@libs/Console";
+import {addLog} from "@userActions/Console";
+import useKeyboardShortcut from "@hooks/useKeyboardShortcut";
+import localFileDownload from "@libs/localFileDownload";
+import localFileCreate from "@libs/localFileCreate";
+import Navigation from "@navigation/Navigation";
+import ROUTES from "@src/ROUTES";
+import Button from "@components/Button";
+import * as Expensicons from "@components/Icon/Expensicons";
+import TextInput from "@components/TextInput";
+import ConfirmModal from "@components/ConfirmModal";
+
+type ConsoleComponentsOnyxProps = {
+ /** Logs captured on the current device */
+ capturedLogs: OnyxEntry;
+
+ /** Whether or not logs should be stored */
+ shouldStoreLogs: OnyxEntry;
+};
+
+type ConsoleComponentsProps = {
+ /** Action to run when pressing Share button */
+ onClose?: () => void;
+ /** Boolean to know if console logs have been opened via test tools modal */
+ isViaTestToolsModal: boolean
+} & ConsoleComponentsOnyxProps;
+
+
+function ConsoleComponents({capturedLogs, shouldStoreLogs, onClose, isViaTestToolsModal}: ConsoleComponentsProps) {
+ const styles = useThemeStyles();
+ const {translate} = useLocalize();
+
+ const [input, setInput] = useState('');
+ const [logs, setLogs] = useState(capturedLogs);
+ const [isGeneratingLogsFile, setIsGeneratingLogsFile] = useState(false);
+ const [isLimitModalVisible, setIsLimitModalVisible] = useState(false);
+
+ const logsList = useMemo(
+ () =>
+ Object.entries(logs ?? {})
+ .map(([key, value]) => ({key, ...value}))
+ .reverse(),
+ [logs],
+ );
+
+ useEffect(() => {
+ if (!shouldStoreLogs) {
+ return;
+ }
+
+ setLogs((prevLogs) => ({...prevLogs, ...capturedLogs}));
+ }, [capturedLogs, shouldStoreLogs]);
+
+ const renderItem: ListRenderItem = useCallback(
+ ({item}: ListRenderItemInfo) => {
+ if (!item) {
+ return null;
+ }
+
+ return (
+
+ {`${format(new Date(item.time), CONST.DATE.FNS_DB_FORMAT_STRING)} ${item.message}`}
+
+ );
+ },
+ [styles.mb2],
+ );
+
+ const executeArbitraryCode = () => {
+ const sanitizedInput = sanitizeConsoleInput(input);
+
+ const output = createLog(sanitizedInput);
+ output.forEach((log) => addLog(log));
+ setInput('');
+ };
+
+ useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, executeArbitraryCode);
+
+ const saveLogs = () => {
+ const logsWithParsedMessages = parseStringifiedMessages(logsList);
+
+ localFileDownload('logs', JSON.stringify(logsWithParsedMessages, null, 2));
+ };
+
+ const shareLogs = () => {
+ setIsGeneratingLogsFile(true);
+ const logsWithParsedMessages = parseStringifiedMessages(logsList);
+
+ // 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}) => {
+ setIsGeneratingLogsFile(false);
+
+ // if the file size is too large to send it as an attachment, show a modal and return
+ if (size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) {
+ setIsLimitModalVisible(true);
+
+ return;
+ }
+
+ if (onClose) {
+ onClose()
+ }
+ Navigation.navigate(ROUTES.SETTINGS_SHARE_LOG.getRoute(path, isViaTestToolsModal));
+ });
+ };
+
+ const mhModal = isViaTestToolsModal ? styles.mh2 : undefined;
+
+ return (
+ <>
+
+
+ {translate('initialSettingsPage.debugConsole.noLogsAvailable')}}
+ />
+
+
+
+
+
+
+
+
+
+
+ setIsLimitModalVisible(false)}
+ prompt={translate('initialSettingsPage.debugConsole.logSizeTooLarge', {
+ size: CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE / 1024 / 1024,
+ })}
+ shouldShowCancelButton={false}
+ confirmText={translate('common.ok')}
+ />
+ >
+ );
+}
+
+ConsoleComponents.displayName = 'ConsoleModal';
+
+
+export default withOnyx({
+ capturedLogs: {
+ key: ONYXKEYS.LOGS,
+ },
+ shouldStoreLogs: {
+ key: ONYXKEYS.SHOULD_STORE_LOGS,
+ },
+})(ConsoleComponents);
diff --git a/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx b/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
new file mode 100644
index 000000000000..d2ee0c30271a
--- /dev/null
+++ b/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
@@ -0,0 +1,64 @@
+import React, {useCallback, useEffect, useMemo, useState} from 'react';
+import {ListRenderItem, ListRenderItemInfo, View} from 'react-native';
+import ConsolePage from "@pages/settings/AboutPage/ConsolePage";
+import CONST from "@src/CONST";
+import Modal from "@components/Modal";
+import useWindowDimensions from "@hooks/useWindowDimensions";
+import useStyleUtils from "@hooks/useStyleUtils";
+import useThemeStyles from "@hooks/useThemeStyles";
+import useLocalize from "@hooks/useLocalize";
+import InvertedFlatList from "@components/InvertedFlatList";
+import Text from "@components/Text";
+import {CapturedLogs, Log} from "@src/types/onyx";
+import {format} from "date-fns";
+import {OnyxEntry, withOnyx} from "react-native-onyx";
+import ONYXKEYS from "@src/ONYXKEYS";
+import {createLog, parseStringifiedMessages, sanitizeConsoleInput} from "@libs/Console";
+import {addLog} from "@userActions/Console";
+import useKeyboardShortcut from "@hooks/useKeyboardShortcut";
+import localFileDownload from "@libs/localFileDownload";
+import localFileCreate from "@libs/localFileCreate";
+import Navigation from "@navigation/Navigation";
+import ROUTES from "@src/ROUTES";
+import Button from "@components/Button";
+import * as Expensicons from "@components/Icon/Expensicons";
+import TextInput from "@components/TextInput";
+import ConfirmModal from "@components/ConfirmModal";
+import ShareLogList from "@pages/settings/AboutPage/ShareLogList";
+import ConsoleComponents from "@components/ClientSideLoggingToolMenu/ConsoleComponents";
+
+type ConsoleModalProps = {
+ /** Locally created file */
+ isVisible: boolean
+ /** Action to run when pressing Share button */
+ onClose?: () => void;
+};
+
+
+function ConsoleModal({isVisible, onClose, closeTestToolsModal}: ConsoleModalProps) {
+ const {windowWidth, windowHeight} = useWindowDimensions();
+ const StyleUtils = useStyleUtils();
+
+ return (
+
+
+
+ {
+ if (onClose) {
+ onClose()
+ }
+ closeTestToolsModal()
+ }}
+ isViaTestToolsModal/>
+
+
+ );
+}
+
+ConsoleModal.displayName = 'ConsoleModal';
+
+export default ConsoleModal;
diff --git a/src/components/ClientSideLoggingToolMenu/index.android.tsx b/src/components/ClientSideLoggingToolMenu/index.android.tsx
index 0be6e96fcafe..97cd9862fa20 100644
--- a/src/components/ClientSideLoggingToolMenu/index.android.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.android.tsx
@@ -5,7 +5,7 @@ import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-function ClientSideLoggingToolMenu() {
+function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
const createAndSaveFile = (logs: Log[]) => {
@@ -38,6 +38,8 @@ function ClientSideLoggingToolMenu() {
onEnableLogging={() => setFile(undefined)}
onDisableLogging={createAndSaveFile}
onShareLogs={shareLogs}
+ isViaTestToolsModal={isViaTestToolsModal}
+ closeTestToolsModal={closeTestToolsModal}
/>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/index.ios.tsx b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
index cc596e54a973..34adf8fdf244 100644
--- a/src/components/ClientSideLoggingToolMenu/index.ios.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
@@ -4,7 +4,7 @@ import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-function ClientSideLoggingToolMenu() {
+function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
const createFile = (logs: Log[]) => {
@@ -28,6 +28,8 @@ function ClientSideLoggingToolMenu() {
onEnableLogging={() => setFile(undefined)}
onDisableLogging={createFile}
onShareLogs={shareLogs}
+ isViaTestToolsModal={isViaTestToolsModal}
+ closeTestToolsModal={closeTestToolsModal}
/>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/index.tsx b/src/components/ClientSideLoggingToolMenu/index.tsx
index 182c3bf99b74..99468ea32089 100644
--- a/src/components/ClientSideLoggingToolMenu/index.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.tsx
@@ -3,12 +3,12 @@ import type {Log} from '@libs/Console';
import localFileDownload from '@libs/localFileDownload';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-function ClientSideLoggingToolMenu() {
+function ClientSideLoggingToolMenu({isViaTestToolsModal = false}) {
const downloadFile = (logs: Log[]) => {
localFileDownload('logs', JSON.stringify(logs, null, 2));
};
- return ;
+ return ;
}
ClientSideLoggingToolMenu.displayName = 'ClientSideLoggingToolMenu';
diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx
index 76f4b251ec83..5c31ac60d39d 100644
--- a/src/components/Modal/index.tsx
+++ b/src/components/Modal/index.tsx
@@ -34,7 +34,7 @@ function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = (
const showModal = () => {
const statusBarColor = StatusBar.getBackgroundColor() ?? theme.appBG;
- const isFullScreenModal = type === CONST.MODAL.MODAL_TYPE.CENTERED || type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED;
+ const isFullScreenModal = type === CONST.MODAL.MODAL_TYPE.CENTERED || type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED || type === CONST.MODAL.MODAL_TYPE.CENTERED_SMALL_AND_UNSWIPEABLE;
if (statusBarColor) {
setPreviousStatusBarColor(statusBarColor);
diff --git a/src/components/TestToolsModal.tsx b/src/components/TestToolsModal.tsx
index 026eafc7a13d..2d2ec9eb599d 100644
--- a/src/components/TestToolsModal.tsx
+++ b/src/components/TestToolsModal.tsx
@@ -45,7 +45,7 @@ function TestToolsModal({isTestToolsModalOpen = false}: TestToolsModalProps) {
{translate('initialSettingsPage.troubleshoot.releaseOptions')}
-
+
);
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index bc3d0bba637e..492df5354613 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -115,6 +115,7 @@ type SettingsNavigatorParamList = {
[SCREENS.SETTINGS.SHARE_LOG]: {
/** URL of the generated file to share logs in a report */
source: string;
+ isViaTestToolsModal: boolean;
};
[SCREENS.SETTINGS.WALLET.ROOT]: undefined;
[SCREENS.SETTINGS.WALLET.CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS]: undefined;
diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx
index c9532fa041a0..350b9c088dfe 100644
--- a/src/pages/settings/AboutPage/ConsolePage.tsx
+++ b/src/pages/settings/AboutPage/ConsolePage.tsx
@@ -1,114 +1,15 @@
-import {format} from 'date-fns';
-import React, {useCallback, useEffect, useMemo, useState} from 'react';
-import {View} from 'react-native';
-import type {ListRenderItem, ListRenderItemInfo} from 'react-native';
+import React from 'react';
import {withOnyx} from 'react-native-onyx';
-import type {OnyxEntry} from 'react-native-onyx';
-import Button from '@components/Button';
-import ConfirmModal from '@components/ConfirmModal';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
-import * as Expensicons from '@components/Icon/Expensicons';
-import InvertedFlatList from '@components/InvertedFlatList';
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 useThemeStyles from '@hooks/useThemeStyles';
-import {addLog} from '@libs/actions/Console';
-import {createLog, parseStringifiedMessages, sanitizeConsoleInput} from '@libs/Console';
-import type {Log} from '@libs/Console';
-import localFileCreate from '@libs/localFileCreate';
-import localFileDownload from '@libs/localFileDownload';
import Navigation from '@libs/Navigation/Navigation';
-import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
-import type {CapturedLogs} from '@src/types/onyx';
+import ConsoleComponents from "@components/ClientSideLoggingToolMenu/ConsoleComponents";
-type ConsolePageOnyxProps = {
- /** Logs captured on the current device */
- capturedLogs: OnyxEntry;
-
- /** Whether or not logs should be stored */
- shouldStoreLogs: OnyxEntry;
-};
-
-type ConsolePageProps = ConsolePageOnyxProps;
-
-function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) {
- const [input, setInput] = useState('');
- const [logs, setLogs] = useState(capturedLogs);
- const [isGeneratingLogsFile, setIsGeneratingLogsFile] = useState(false);
- const [isLimitModalVisible, setIsLimitModalVisible] = useState(false);
+function ConsolePage() {
const {translate} = useLocalize();
- const styles = useThemeStyles();
-
- const logsList = useMemo(
- () =>
- Object.entries(logs ?? {})
- .map(([key, value]) => ({key, ...value}))
- .reverse(),
- [logs],
- );
-
- useEffect(() => {
- if (!shouldStoreLogs) {
- return;
- }
-
- setLogs((prevLogs) => ({...prevLogs, ...capturedLogs}));
- }, [capturedLogs, shouldStoreLogs]);
-
- const executeArbitraryCode = () => {
- const sanitizedInput = sanitizeConsoleInput(input);
-
- const output = createLog(sanitizedInput);
- output.forEach((log) => addLog(log));
- setInput('');
- };
-
- useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, executeArbitraryCode);
-
- const saveLogs = () => {
- const logsWithParsedMessages = parseStringifiedMessages(logsList);
-
- localFileDownload('logs', JSON.stringify(logsWithParsedMessages, null, 2));
- };
-
- const shareLogs = () => {
- setIsGeneratingLogsFile(true);
- const logsWithParsedMessages = parseStringifiedMessages(logsList);
-
- // 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}) => {
- setIsGeneratingLogsFile(false);
-
- // if the file size is too large to send it as an attachment, show a modal and return
- if (size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) {
- setIsLimitModalVisible(true);
-
- return;
- }
-
- Navigation.navigate(ROUTES.SETTINGS_SHARE_LOG.getRoute(path));
- });
- };
-
- const renderItem: ListRenderItem = useCallback(
- ({item}: ListRenderItemInfo) => {
- if (!item) {
- return null;
- }
-
- return (
-
- {`${format(new Date(item.time), CONST.DATE.FNS_DB_FORMAT_STRING)} ${item.message}`}
-
- );
- },
- [styles.mb2],
- );
return (
@@ -116,58 +17,7 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) {
title={translate('initialSettingsPage.troubleshoot.debugConsole')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_TROUBLESHOOT)}
/>
-
- {translate('initialSettingsPage.debugConsole.noLogsAvailable')}}
- />
-
-
-
-
-
-
-
-
-
- setIsLimitModalVisible(false)}
- prompt={translate('initialSettingsPage.debugConsole.logSizeTooLarge', {
- size: CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE / 1024 / 1024,
- })}
- shouldShowCancelButton={false}
- confirmText={translate('common.ok')}
- />
+
);
}
diff --git a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
index 578efbe5317b..58ddac79321b 100644
--- a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
@@ -16,7 +16,7 @@ import ROUTES from '@src/ROUTES';
import type {Report} from '@src/types/onyx';
import type {BaseShareLogListProps} from './types';
-function BaseShareLogList({onAttachLogToReport}: BaseShareLogListProps) {
+function BaseShareLogList({onAttachLogToReport, isViaTestToolsModal = false}: BaseShareLogListProps) {
const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState('');
const {isOffline} = useNetwork();
const {translate} = useLocalize();
@@ -91,7 +91,13 @@ function BaseShareLogList({onAttachLogToReport}: BaseShareLogListProps) {
<>
Navigation.goBack(ROUTES.SETTINGS_CONSOLE)}
+ onBackButtonPress={() => {
+ if (isViaTestToolsModal) {
+ Navigation.goBack();
+ return;
+ }
+ Navigation.goBack(ROUTES.SETTINGS_CONSOLE)
+ }}
/>
{
if (!reportID || !logSource) {
return;
@@ -17,7 +17,7 @@ function ShareLogList({logSource}: ShareLogListProps) {
Navigation.navigate(routeToNavigate);
};
- return ;
+ return ;
}
export default ShareLogList;
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.tsx b/src/pages/settings/AboutPage/ShareLogList/index.tsx
index 555e44e53747..87657575a35c 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.tsx
@@ -6,7 +6,7 @@ import ROUTES from '@src/ROUTES';
import BaseShareLogList from './BaseShareLogList';
import type {ShareLogListProps} from './types';
-function ShareLogList({logSource}: ShareLogListProps) {
+function ShareLogList({logSource, isViaTestToolsModal = false}: ShareLogListProps) {
const onAttachLogToReport = (reportID: string, filename: string) => {
FileUtils.readFileAsync(
logSource,
@@ -20,7 +20,7 @@ function ShareLogList({logSource}: ShareLogListProps) {
() => {},
);
};
- return ;
+ return ;
}
export default ShareLogList;
diff --git a/src/pages/settings/AboutPage/ShareLogPage.tsx b/src/pages/settings/AboutPage/ShareLogPage.tsx
index 8f0623f99d32..5c402f023819 100644
--- a/src/pages/settings/AboutPage/ShareLogPage.tsx
+++ b/src/pages/settings/AboutPage/ShareLogPage.tsx
@@ -7,7 +7,7 @@ import ShareLogList from './ShareLogList';
type ShareLogPageProps = StackScreenProps;
function ShareLogPage({route}: ShareLogPageProps) {
- return ;
+ return ;
}
export default ShareLogPage;
diff --git a/src/styles/utils/generators/ModalStyleUtils.ts b/src/styles/utils/generators/ModalStyleUtils.ts
index 335ef8382941..94b39a400367 100644
--- a/src/styles/utils/generators/ModalStyleUtils.ts
+++ b/src/styles/utils/generators/ModalStyleUtils.ts
@@ -164,6 +164,29 @@ const createModalStyleUtils: StyleUtilGenerator = ({the
shouldAddTopSafeAreaPadding = false;
shouldAddBottomSafeAreaPadding = false;
break;
+ case CONST.MODAL.MODAL_TYPE.CENTERED_SMALL_AND_UNSWIPEABLE:
+ // A centered modal that takes up the minimum possible screen space on all devices and is unswipeable
+ modalStyle = {
+ ...modalStyle,
+ ...{
+ alignItems: 'center',
+ },
+ };
+ modalContainerStyle = {
+ boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)',
+ borderRadius: 12,
+ borderWidth: 0,
+ };
+
+ // Allow this modal to be dismissed with a swipe down or swipe right
+ swipeDirection = undefined;
+ animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn';
+ animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut';
+ shouldAddTopSafeAreaMargin = false;
+ shouldAddBottomSafeAreaMargin = false;
+ shouldAddTopSafeAreaPadding = false;
+ shouldAddBottomSafeAreaPadding = false;
+ break;
case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED:
modalStyle = {
...modalStyle,
From a323a21b0bbc837bb650a1d915c68efe3899c9a2 Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Mon, 22 Apr 2024 01:19:04 +0530
Subject: [PATCH 002/207] Update
---
ios/Podfile | 17 --------
.../BaseClientSideLoggingToolMenu.tsx | 6 +--
.../ConsoleComponents.tsx | 42 +++----------------
.../ConsoleModal.tsx | 30 ++-----------
src/components/TestToolsModal.tsx | 2 +-
src/languages/en.ts | 1 +
src/languages/es.ts | 1 +
7 files changed, 15 insertions(+), 84 deletions(-)
diff --git a/ios/Podfile b/ios/Podfile
index 0c524878e5f7..4f00eb2adfdd 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -1,5 +1,3 @@
-use_frameworks! :linkage => :static
-
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
# Set the type of Mapbox SDK to use
# This value is used by $RNMapboxMaps
@@ -113,21 +111,6 @@ target 'NewExpensify' do
end
end
end
-
- deployment_target = '13.4'
-
- installer.generated_projects.each do |project|
- project.targets.each do |target|
- target.build_configurations.each do |config|
- config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
- end
- end
- project.build_configurations.each do |config|
- config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
- end
- end
-
- `sed -i -e $'s/__IPHONE_10_0/__IPHONE_15_0/' #{installer.sandbox.root}/RCT-Folly/folly/portability/Time.h`
end
end
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index a6bb085c949a..0a64f8f6c353 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -12,7 +12,7 @@ import * as Console from '@libs/actions/Console';
import {parseStringifiedMessages} from '@libs/Console';
import ONYXKEYS from '@src/ONYXKEYS';
import type {CapturedLogs, Log} from '@src/types/onyx';
-import ConsoleModal from "@components/ClientSideLoggingToolMenu/ConsoleModal";
+import ConsoleModal from "./ConsoleModal";
type BaseClientSideLoggingToolMenuOnyxProps = {
/** Logs captured on the current device */
@@ -74,10 +74,10 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
/>
{!!shouldStoreLogs && isViaTestToolsModal &&
-
+
diff --git a/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx b/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
index 5de7de0e049e..b14a1e94c9f3 100644
--- a/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
+++ b/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
@@ -1,13 +1,15 @@
import React, {useCallback, useEffect, useMemo, useState} from 'react';
-import {ListRenderItem, ListRenderItemInfo, View} from 'react-native';
+import type {ListRenderItem, ListRenderItemInfo} from 'react-native';
+import {View} from 'react-native';
import CONST from "@src/CONST";
import useThemeStyles from "@hooks/useThemeStyles";
import useLocalize from "@hooks/useLocalize";
import InvertedFlatList from "@components/InvertedFlatList";
import Text from "@components/Text";
-import {CapturedLogs, Log} from "@src/types/onyx";
+import type {CapturedLogs, Log} from "@src/types/onyx";
import {format} from "date-fns";
-import {OnyxEntry, withOnyx} from "react-native-onyx";
+import {withOnyx} from "react-native-onyx";
+import type {OnyxEntry} from "react-native-onyx";
import ONYXKEYS from "@src/ONYXKEYS";
import {createLog, parseStringifiedMessages, sanitizeConsoleInput} from "@libs/Console";
import {addLog} from "@userActions/Console";
@@ -130,40 +132,6 @@ function ConsoleComponents({capturedLogs, shouldStoreLogs, onClose, isViaTestToo
/>
-
-
-
-
-
-
-
-
+ }} isViaTestToolsModal/>
);
diff --git a/src/components/TestToolsModal.tsx b/src/components/TestToolsModal.tsx
index 2d2ec9eb599d..aa05a56f3aaf 100644
--- a/src/components/TestToolsModal.tsx
+++ b/src/components/TestToolsModal.tsx
@@ -32,7 +32,7 @@ function TestToolsModal({isTestToolsModalOpen = false}: TestToolsModalProps) {
return (
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 87864e7e65f1..730a71631a37 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -914,6 +914,7 @@ export default {
noLogsAvailable: 'No logs available',
logSizeTooLarge: ({size}: LogSizeParams) => `Log size exceeds the limit of ${size} MB. Please use "Save log" to download the log file instead.`,
logs: 'Logs',
+ viewConsole: 'View console',
},
security: 'Security',
signOut: 'Sign out',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 7572c7f7d28b..d6d89bcdea27 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -909,6 +909,7 @@ export default {
noLogsAvailable: 'No hay registros disponibles',
logSizeTooLarge: ({size}: LogSizeParams) => `El tamaño del registro excede el límite de ${size} MB. Utilice "Guardar registro" para descargar el archivo de registro.`,
logs: 'Logs',
+ viewConsole: 'Ver consola',
},
security: 'Seguridad',
restoreStashed: 'Restablecer login guardado',
From d9ec2143ec81fa277e606611a1b24d5b33540fda Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Mon, 22 Apr 2024 01:19:55 +0530
Subject: [PATCH 003/207] Fix number of taps
---
src/CONST.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index 4ded9e282d3e..893dc008786b 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -3101,7 +3101,7 @@ const CONST = {
// Test tool menu parameters
TEST_TOOL: {
// Number of concurrent taps to open then the Test modal menu
- NUMBER_OF_TAPS: 2,
+ NUMBER_OF_TAPS: 4,
},
MENU_HELP_URLS: {
From 64873ddd18eda80972b63c95c8518e29e308b3ef Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Mon, 22 Apr 2024 01:20:52 +0530
Subject: [PATCH 004/207] Fix test tools modal visibility condition
---
src/components/TestToolsModal.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/TestToolsModal.tsx b/src/components/TestToolsModal.tsx
index aa05a56f3aaf..2d2ec9eb599d 100644
--- a/src/components/TestToolsModal.tsx
+++ b/src/components/TestToolsModal.tsx
@@ -32,7 +32,7 @@ function TestToolsModal({isTestToolsModalOpen = false}: TestToolsModalProps) {
return (
From 65e43381b8e5f626618f315b338c6047202869d9 Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Mon, 22 Apr 2024 01:48:50 +0530
Subject: [PATCH 005/207] Typecheck fixes
---
.../BaseClientSideLoggingToolMenu.tsx | 14 +++++---
.../ConsoleComponents.tsx | 34 +++++++++++++++++++
.../ConsoleModal.tsx | 4 ++-
.../index.android.tsx | 3 +-
.../ClientSideLoggingToolMenu/index.ios.tsx | 3 +-
.../ClientSideLoggingToolMenu/index.tsx | 9 +++--
.../ClientSideLoggingToolMenu/types.ts | 8 +++++
src/pages/settings/AboutPage/ConsolePage.tsx | 9 +----
.../settings/AboutPage/ShareLogList/types.ts | 2 ++
9 files changed, 69 insertions(+), 17 deletions(-)
create mode 100644 src/components/ClientSideLoggingToolMenu/types.ts
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index 0a64f8f6c353..297d63dbc7fe 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -32,7 +32,9 @@ type BaseClientSideLoggingToolProps = {
/** Action to run when enabling logging */
onEnableLogging?: () => void;
/** Boolean to know if this was opened via test tools modal */
- isViaTestToolsModal: boolean
+ isViaTestToolsModal: boolean;
+ /** Action to close the test tools modal */
+ closeTestToolsModal: () => void;
} & BaseClientSideLoggingToolMenuOnyxProps;
function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onShareLogs, onDisableLogging, onEnableLogging, isViaTestToolsModal, closeTestToolsModal}: BaseClientSideLoggingToolProps) {
@@ -94,9 +96,13 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
>
)}
- {
- setIsConsoleModalVisible(false)
- }} closeTestToolsModal={closeTestToolsModal}/>
+ {
+ setIsConsoleModalVisible(false)
+ }}
+ closeTestToolsModal={closeTestToolsModal}
+ />
>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx b/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
index b14a1e94c9f3..d7e53223c3a5 100644
--- a/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
+++ b/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
@@ -132,6 +132,40 @@ function ConsoleComponents({capturedLogs, shouldStoreLogs, onClose, isViaTestToo
/>
+
+
+
+
+
+
+
+
void;
+ onClose: () => void;
+ /** Action to close the test tools modal */
+ closeTestToolsModal: () => void;
};
diff --git a/src/components/ClientSideLoggingToolMenu/index.android.tsx b/src/components/ClientSideLoggingToolMenu/index.android.tsx
index 97cd9862fa20..8970f92bae17 100644
--- a/src/components/ClientSideLoggingToolMenu/index.android.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.android.tsx
@@ -4,8 +4,9 @@ import Share from 'react-native-share';
import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
+import ClientSideLoggingToolMenuProps from "@components/ClientSideLoggingToolMenu/types";
-function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}) {
+function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
const createAndSaveFile = (logs: Log[]) => {
diff --git a/src/components/ClientSideLoggingToolMenu/index.ios.tsx b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
index 34adf8fdf244..1361be073b9f 100644
--- a/src/components/ClientSideLoggingToolMenu/index.ios.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
@@ -3,8 +3,9 @@ import Share from 'react-native-share';
import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
+import ClientSideLoggingToolMenuProps from "@components/ClientSideLoggingToolMenu/types";
-function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}) {
+function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
const createFile = (logs: Log[]) => {
diff --git a/src/components/ClientSideLoggingToolMenu/index.tsx b/src/components/ClientSideLoggingToolMenu/index.tsx
index 99468ea32089..33b0343936fc 100644
--- a/src/components/ClientSideLoggingToolMenu/index.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.tsx
@@ -2,13 +2,18 @@ import React from 'react';
import type {Log} from '@libs/Console';
import localFileDownload from '@libs/localFileDownload';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
+import type ClientSideLoggingToolMenuProps from "@components/ClientSideLoggingToolMenu/types";
-function ClientSideLoggingToolMenu({isViaTestToolsModal = false}) {
+function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const downloadFile = (logs: Log[]) => {
localFileDownload('logs', JSON.stringify(logs, null, 2));
};
- return ;
+ return ;
}
ClientSideLoggingToolMenu.displayName = 'ClientSideLoggingToolMenu';
diff --git a/src/components/ClientSideLoggingToolMenu/types.ts b/src/components/ClientSideLoggingToolMenu/types.ts
new file mode 100644
index 000000000000..0d5b9b43f977
--- /dev/null
+++ b/src/components/ClientSideLoggingToolMenu/types.ts
@@ -0,0 +1,8 @@
+type ClientSideLoggingToolMenuProps = {
+ /** Boolean to know if this was opened via test tools modal */
+ isViaTestToolsModal: boolean;
+ /** Action to close the test tools modal */
+ closeTestToolsModal: () => void;
+};
+
+export default ClientSideLoggingToolMenuProps;
diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx
index 350b9c088dfe..bd1456b61fb4 100644
--- a/src/pages/settings/AboutPage/ConsolePage.tsx
+++ b/src/pages/settings/AboutPage/ConsolePage.tsx
@@ -24,11 +24,4 @@ function ConsolePage() {
ConsolePage.displayName = 'ConsolePage';
-export default withOnyx({
- capturedLogs: {
- key: ONYXKEYS.LOGS,
- },
- shouldStoreLogs: {
- key: ONYXKEYS.SHOULD_STORE_LOGS,
- },
-})(ConsolePage);
+export default ConsolePage;
diff --git a/src/pages/settings/AboutPage/ShareLogList/types.ts b/src/pages/settings/AboutPage/ShareLogList/types.ts
index 500641a3da42..eea65dd368a0 100644
--- a/src/pages/settings/AboutPage/ShareLogList/types.ts
+++ b/src/pages/settings/AboutPage/ShareLogList/types.ts
@@ -1,6 +1,8 @@
type ShareLogListProps = {
/** The source of the log file to share */
logSource: string;
+ /** Boolean to know if this was opened via test tools modal */
+ isViaTestToolsModal: boolean;
};
type BaseShareLogListProps = {
From 8af99fe5c7b06289132b7d04e7ca1f9dfce8379d Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Mon, 22 Apr 2024 19:46:45 +0530
Subject: [PATCH 006/207] Update
---
.../BaseClientSideLoggingToolMenu.tsx | 2 +-
src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx | 8 ++++----
.../ClientSideLoggingToolMenu/index.android.tsx | 2 +-
src/components/ClientSideLoggingToolMenu/index.ios.tsx | 2 +-
src/components/ClientSideLoggingToolMenu/index.tsx | 4 ++--
src/components/ClientSideLoggingToolMenu/types.ts | 2 +-
src/pages/settings/AboutPage/ConsolePage.tsx | 4 +---
.../settings/AboutPage/ShareLogList/index.native.tsx | 2 +-
src/pages/settings/AboutPage/ShareLogList/index.tsx | 2 +-
src/pages/settings/AboutPage/ShareLogList/types.ts | 2 ++
src/pages/settings/AboutPage/ShareLogPage.tsx | 2 +-
src/pages/settings/Troubleshoot/TroubleshootPage.tsx | 2 +-
12 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index 297d63dbc7fe..9b5faac55bc4 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -34,7 +34,7 @@ type BaseClientSideLoggingToolProps = {
/** Boolean to know if this was opened via test tools modal */
isViaTestToolsModal: boolean;
/** Action to close the test tools modal */
- closeTestToolsModal: () => void;
+ closeTestToolsModal?: () => void;
} & BaseClientSideLoggingToolMenuOnyxProps;
function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onShareLogs, onDisableLogging, onEnableLogging, isViaTestToolsModal, closeTestToolsModal}: BaseClientSideLoggingToolProps) {
diff --git a/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx b/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
index 89aef6353f82..4d405db69226 100644
--- a/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
+++ b/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
@@ -12,7 +12,7 @@ type ConsoleModalProps = {
/** Action to run when pressing Share button */
onClose: () => void;
/** Action to close the test tools modal */
- closeTestToolsModal: () => void;
+ closeTestToolsModal?: () => void;
};
@@ -29,10 +29,10 @@ function ConsoleModal({isVisible, onClose, closeTestToolsModal}: ConsoleModalPro
{
- if (onClose) {
- onClose()
+ onClose()
+ if (closeTestToolsModal) {
+ closeTestToolsModal()
}
- closeTestToolsModal()
}} isViaTestToolsModal/>
diff --git a/src/components/ClientSideLoggingToolMenu/index.android.tsx b/src/components/ClientSideLoggingToolMenu/index.android.tsx
index 8970f92bae17..272c563f8e91 100644
--- a/src/components/ClientSideLoggingToolMenu/index.android.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.android.tsx
@@ -4,7 +4,7 @@ import Share from 'react-native-share';
import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-import ClientSideLoggingToolMenuProps from "@components/ClientSideLoggingToolMenu/types";
+import type ClientSideLoggingToolMenuProps from "./types";
function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
diff --git a/src/components/ClientSideLoggingToolMenu/index.ios.tsx b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
index 1361be073b9f..f5de90b00140 100644
--- a/src/components/ClientSideLoggingToolMenu/index.ios.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
@@ -3,7 +3,7 @@ import Share from 'react-native-share';
import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-import ClientSideLoggingToolMenuProps from "@components/ClientSideLoggingToolMenu/types";
+import type ClientSideLoggingToolMenuProps from "./types";
function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
diff --git a/src/components/ClientSideLoggingToolMenu/index.tsx b/src/components/ClientSideLoggingToolMenu/index.tsx
index 33b0343936fc..9cb86b46b797 100644
--- a/src/components/ClientSideLoggingToolMenu/index.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.tsx
@@ -1,10 +1,10 @@
import React from 'react';
import type {Log} from '@libs/Console';
import localFileDownload from '@libs/localFileDownload';
+import type ClientSideLoggingToolMenuProps from "./types";
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-import type ClientSideLoggingToolMenuProps from "@components/ClientSideLoggingToolMenu/types";
-function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
+function ClientSideLoggingToolMenu({isViaTestToolsModal, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const downloadFile = (logs: Log[]) => {
localFileDownload('logs', JSON.stringify(logs, null, 2));
};
diff --git a/src/components/ClientSideLoggingToolMenu/types.ts b/src/components/ClientSideLoggingToolMenu/types.ts
index 0d5b9b43f977..86ad66dfd33c 100644
--- a/src/components/ClientSideLoggingToolMenu/types.ts
+++ b/src/components/ClientSideLoggingToolMenu/types.ts
@@ -2,7 +2,7 @@ type ClientSideLoggingToolMenuProps = {
/** Boolean to know if this was opened via test tools modal */
isViaTestToolsModal: boolean;
/** Action to close the test tools modal */
- closeTestToolsModal: () => void;
+ closeTestToolsModal?: () => void;
};
export default ClientSideLoggingToolMenuProps;
diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx
index bd1456b61fb4..48847757dac4 100644
--- a/src/pages/settings/AboutPage/ConsolePage.tsx
+++ b/src/pages/settings/AboutPage/ConsolePage.tsx
@@ -1,10 +1,8 @@
import React from 'react';
-import {withOnyx} from 'react-native-onyx';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import useLocalize from '@hooks/useLocalize';
import Navigation from '@libs/Navigation/Navigation';
-import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import ConsoleComponents from "@components/ClientSideLoggingToolMenu/ConsoleComponents";
@@ -17,7 +15,7 @@ function ConsolePage() {
title={translate('initialSettingsPage.troubleshoot.debugConsole')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_TROUBLESHOOT)}
/>
-
+
);
}
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.native.tsx b/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
index 3badbe33b200..720209fe9fd2 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
@@ -5,7 +5,7 @@ import ROUTES from '@src/ROUTES';
import BaseShareLogList from './BaseShareLogList';
import type {ShareLogListProps} from './types';
-function ShareLogList({logSource, isViaTestToolsModal = false}: ShareLogListProps) {
+function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
const onAttachLogToReport = (reportID: string, filename: string) => {
if (!reportID || !logSource) {
return;
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.tsx b/src/pages/settings/AboutPage/ShareLogList/index.tsx
index 87657575a35c..e7bf191306d7 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.tsx
@@ -6,7 +6,7 @@ import ROUTES from '@src/ROUTES';
import BaseShareLogList from './BaseShareLogList';
import type {ShareLogListProps} from './types';
-function ShareLogList({logSource, isViaTestToolsModal = false}: ShareLogListProps) {
+function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
const onAttachLogToReport = (reportID: string, filename: string) => {
FileUtils.readFileAsync(
logSource,
diff --git a/src/pages/settings/AboutPage/ShareLogList/types.ts b/src/pages/settings/AboutPage/ShareLogList/types.ts
index eea65dd368a0..bab48c39cc27 100644
--- a/src/pages/settings/AboutPage/ShareLogList/types.ts
+++ b/src/pages/settings/AboutPage/ShareLogList/types.ts
@@ -7,6 +7,8 @@ type ShareLogListProps = {
type BaseShareLogListProps = {
onAttachLogToReport: (reportID: string, filename: string) => void;
+ /** Boolean to know if this was opened via test tools modal */
+ isViaTestToolsModal: boolean;
};
export type {BaseShareLogListProps, ShareLogListProps};
diff --git a/src/pages/settings/AboutPage/ShareLogPage.tsx b/src/pages/settings/AboutPage/ShareLogPage.tsx
index 5c402f023819..7123746059ea 100644
--- a/src/pages/settings/AboutPage/ShareLogPage.tsx
+++ b/src/pages/settings/AboutPage/ShareLogPage.tsx
@@ -7,7 +7,7 @@ import ShareLogList from './ShareLogList';
type ShareLogPageProps = StackScreenProps;
function ShareLogPage({route}: ShareLogPageProps) {
- return ;
+ return ;
}
export default ShareLogPage;
diff --git a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
index b2523a4e039c..e14d4ac13bb3 100644
--- a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
+++ b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
@@ -119,7 +119,7 @@ function TroubleshootPage({shouldStoreLogs}: TroubleshootPageProps) {
>
-
+
Date: Wed, 24 Apr 2024 07:28:10 +0700
Subject: [PATCH 007/207] fix error when clicking on attachment note
---
src/CONST.ts | 6 ++
src/ROUTES.ts | 6 +-
src/SCREENS.ts | 2 +-
src/components/AttachmentContext.ts | 17 ++++
.../HTMLRenderers/ImageRenderer.tsx | 36 +++++---
.../HTMLRenderers/VideoRenderer.tsx | 2 +-
src/libs/Middleware/SaveResponseInOnyx.ts | 1 +
.../Navigation/AppNavigator/AuthScreens.tsx | 2 +-
src/libs/Navigation/NavigationRoot.tsx | 1 +
src/libs/Navigation/dismissModal.ts | 2 +-
src/libs/Navigation/dismissModalWithReport.ts | 2 +-
src/libs/Navigation/linkTo.ts | 10 ++-
src/libs/Navigation/linkingConfig/config.ts | 3 +-
.../linkingConfig/getAdaptedStateFromPath.ts | 30 ++++---
src/libs/Navigation/types.ts | 5 +-
.../PrivateNotes/PrivateNotesListPage.tsx | 28 +++---
src/pages/home/report/ReportActionItem.tsx | 89 ++++++++++---------
src/pages/home/report/ReportAttachments.tsx | 7 +-
18 files changed, 155 insertions(+), 94 deletions(-)
create mode 100644 src/components/AttachmentContext.ts
diff --git a/src/CONST.ts b/src/CONST.ts
index 2cd614b74816..3d8545d74088 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -1132,6 +1132,12 @@ const CONST = {
WEBP: 'image/webp',
JPEG: 'image/jpeg',
},
+ ATTACHMENT_TYPE: {
+ REPORT: 'r',
+ REPORT_ACTION: 'a',
+ NOTE: 'n',
+ SINGLE: 's',
+ },
FILE_TYPE_REGEX: {
// Image MimeTypes allowed by iOS photos app.
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index ceb4c217cb6e..47fe2516c7d7 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -225,9 +225,9 @@ const ROUTES = {
route: 'r/:reportID/details/shareCode',
getRoute: (reportID: string) => `r/${reportID}/details/shareCode` as const,
},
- REPORT_ATTACHMENTS: {
- route: 'r/:reportID/attachment',
- getRoute: (reportID: string, source: string) => `r/${reportID}/attachment?source=${encodeURIComponent(source)}` as const,
+ ATTACHMENTS: {
+ route: 'attachment',
+ getRoute: (id: string, type: ValueOf, url: string) => `attachment?source=${encodeURIComponent(url)}&type=${type}${id ? `&id=${id}` : ''}`,
},
REPORT_PARTICIPANTS: {
route: 'r/:reportID/participants',
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index c839d9d05070..5fc6b8cbd8d8 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -7,7 +7,7 @@ import type DeepValueOf from './types/utils/DeepValueOf';
const PROTECTED_SCREENS = {
HOME: 'Home',
CONCIERGE: 'Concierge',
- REPORT_ATTACHMENTS: 'ReportAttachments',
+ ATTACHMENTS: 'Attachments',
} as const;
const SCREENS = {
diff --git a/src/components/AttachmentContext.ts b/src/components/AttachmentContext.ts
new file mode 100644
index 000000000000..5fcb9ce7b0a4
--- /dev/null
+++ b/src/components/AttachmentContext.ts
@@ -0,0 +1,17 @@
+import {createContext} from 'react';
+import {ValueOf} from 'type-fest';
+import CONST from '@src/CONST';
+
+type AttachmentContextProps = {
+ type?: ValueOf;
+ id?: string;
+};
+
+const AttachmentContext = createContext({
+ type: undefined,
+ id: undefined,
+});
+
+AttachmentContext.displayName = 'AttachmentContext';
+
+export {AttachmentContext};
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
index 79eaa30ee922..4e78f127d06c 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
@@ -2,6 +2,7 @@ import React, {memo} from 'react';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import type {CustomRendererProps, TBlock} from 'react-native-render-html';
+import {AttachmentContext} from '@components/AttachmentContext';
import * as Expensicons from '@components/Icon/Expensicons';
import PressableWithoutFocus from '@components/Pressable/PressableWithoutFocus';
import {ShowContextMenuContext, showContextMenuForReport} from '@components/ShowContextMenuContext';
@@ -78,19 +79,28 @@ function ImageRenderer({tnode}: ImageRendererProps) {
) : (
{({anchor, report, action, checkIfContextMenuActive}) => (
- {
- const route = ROUTES.REPORT_ATTACHMENTS.getRoute(report?.reportID ?? '', source);
- Navigation.navigate(route);
- }}
- onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
- shouldUseHapticsOnLongPress
- accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON}
- accessibilityLabel={translate('accessibilityHints.viewAttachment')}
- >
- {thumbnailImageComponent}
-
+
+ {({id, type}) => (
+ {
+ let route = '';
+ if (source && type) {
+ if (id) {
+ route = ROUTES.ATTACHMENTS?.getRoute(id, type, source);
+ Navigation.navigate(route);
+ }
+ }
+ }}
+ onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
+ shouldUseHapticsOnLongPress
+ accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON}
+ accessibilityLabel={translate('accessibilityHints.viewAttachment')}
+ >
+ {thumbnailImageComponent}
+
+ )}
+
)}
);
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VideoRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VideoRenderer.tsx
index 6802a4518ba1..cf8eebf81ac3 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VideoRenderer.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VideoRenderer.tsx
@@ -35,7 +35,7 @@ function VideoRenderer({tnode, key}: VideoRendererProps) {
videoDimensions={{width, height}}
videoDuration={duration}
onShowModalPress={() => {
- const route = ROUTES.REPORT_ATTACHMENTS.getRoute(report?.reportID ?? '', sourceURL);
+ const route = ROUTES.ATTACHMENTS.getRoute(report?.reportID ?? '', CONST.ATTACHMENT_TYPE.REPORT, sourceURL);
Navigation.navigate(route);
}}
/>
diff --git a/src/libs/Middleware/SaveResponseInOnyx.ts b/src/libs/Middleware/SaveResponseInOnyx.ts
index ffe4f8a9bea9..58052c971505 100644
--- a/src/libs/Middleware/SaveResponseInOnyx.ts
+++ b/src/libs/Middleware/SaveResponseInOnyx.ts
@@ -33,6 +33,7 @@ const SaveResponseInOnyx: Middleware = (requestResponse, request) =>
OnyxUpdates.saveUpdateInformation(responseToApply);
// Ensure the queue is paused while the client resolves the gap in onyx updates so that updates are guaranteed to happen in a specific order.
+ console.log("**********************", {command: request.command})
return Promise.resolve({
...response,
shouldPauseQueue: true,
diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx
index 9157d7486c9e..a3fb36cb73ef 100644
--- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx
+++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx
@@ -300,7 +300,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
getComponent={loadConciergePage}
/>
);
// Performance optimization to avoid context consumers to delay first render
setTimeout(() => {
diff --git a/src/libs/Navigation/dismissModal.ts b/src/libs/Navigation/dismissModal.ts
index 4e159f0284bd..e09629d6f8ce 100644
--- a/src/libs/Navigation/dismissModal.ts
+++ b/src/libs/Navigation/dismissModal.ts
@@ -23,7 +23,7 @@ function dismissModal(navigationRef: NavigationContainerRef)
case NAVIGATORS.RIGHT_MODAL_NAVIGATOR:
case NAVIGATORS.ONBOARDING_MODAL_NAVIGATOR:
case SCREENS.NOT_FOUND:
- case SCREENS.REPORT_ATTACHMENTS:
+ case SCREENS.ATTACHMENTS:
case SCREENS.TRANSACTION_RECEIPT:
case SCREENS.PROFILE_AVATAR:
case SCREENS.WORKSPACE_AVATAR:
diff --git a/src/libs/Navigation/dismissModalWithReport.ts b/src/libs/Navigation/dismissModalWithReport.ts
index c0405c2c9da0..fe6fd288a2f9 100644
--- a/src/libs/Navigation/dismissModalWithReport.ts
+++ b/src/libs/Navigation/dismissModalWithReport.ts
@@ -37,7 +37,7 @@ function dismissModalWithReport(targetReport: Report | EmptyObject, navigationRe
case NAVIGATORS.LEFT_MODAL_NAVIGATOR:
case NAVIGATORS.RIGHT_MODAL_NAVIGATOR:
case SCREENS.NOT_FOUND:
- case SCREENS.REPORT_ATTACHMENTS:
+ case SCREENS.ATTACHMENTS:
case SCREENS.TRANSACTION_RECEIPT:
case SCREENS.PROFILE_AVATAR:
case SCREENS.WORKSPACE_AVATAR:
diff --git a/src/libs/Navigation/linkTo.ts b/src/libs/Navigation/linkTo.ts
index 863cb102add4..e644127cac61 100644
--- a/src/libs/Navigation/linkTo.ts
+++ b/src/libs/Navigation/linkTo.ts
@@ -148,20 +148,23 @@ export default function linkTo(navigation: NavigationContainerRef['config'] = {
[SCREENS.SIGN_IN_WITH_GOOGLE_DESKTOP]: ROUTES.GOOGLE_SIGN_IN,
[SCREENS.SAML_SIGN_IN]: ROUTES.SAML_SIGN_IN,
[SCREENS.DESKTOP_SIGN_IN_REDIRECT]: ROUTES.DESKTOP_SIGN_IN_REDIRECT,
- [SCREENS.REPORT_ATTACHMENTS]: ROUTES.REPORT_ATTACHMENTS.route,
+ [SCREENS.ATTACHMENTS]: ROUTES.ATTACHMENTS.route,
[SCREENS.PROFILE_AVATAR]: ROUTES.PROFILE_AVATAR.route,
[SCREENS.WORKSPACE_AVATAR]: ROUTES.WORKSPACE_AVATAR.route,
[SCREENS.REPORT_AVATAR]: ROUTES.REPORT_AVATAR.route,
diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
index f18637d8e52e..73fc0a328963 100644
--- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
+++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
@@ -5,6 +5,7 @@ import getIsNarrowLayout from '@libs/getIsNarrowLayout';
import getTopmostNestedRHPRoute from '@libs/Navigation/getTopmostNestedRHPRoute';
import type {BottomTabName, CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types';
import {extractPolicyIDFromPath, getPathWithoutPolicyID} from '@libs/PolicyUtils';
+import CONST from '@src/CONST';
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import CENTRAL_PANE_TO_RHP_MAPPING from './CENTRAL_PANE_TO_RHP_MAPPING';
@@ -159,7 +160,8 @@ function getAdaptedState(state: PartialState
const lhpNavigator = state.routes.find((route) => route.name === NAVIGATORS.LEFT_MODAL_NAVIGATOR);
const onboardingModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.ONBOARDING_MODAL_NAVIGATOR);
const welcomeVideoModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.WELCOME_VIDEO_MODAL_NAVIGATOR);
- const reportAttachmentsScreen = state.routes.find((route) => route.name === SCREENS.REPORT_ATTACHMENTS);
+ const attachmentsScreen = state.routes.find((route) => route.name === SCREENS.ATTACHMENTS);
+ console.log('9999999999', state.routes);
if (isNarrowLayout) {
metainfo.isFullScreenNavigatorMandatory = false;
@@ -293,25 +295,27 @@ function getAdaptedState(state: PartialState
metainfo,
};
}
- if (reportAttachmentsScreen) {
+ if (attachmentsScreen) {
// Routes
// - matching bottom tab
// - central pane (report screen) of the attachment
// - found report attachments
const routes = [];
- const reportAttachments = reportAttachmentsScreen as Route<'ReportAttachments', RootStackParamList['ReportAttachments']>;
+ const reportAttachments = attachmentsScreen as Route<'Attachments', RootStackParamList['Attachments']>;
- const matchingBottomTabRoute = getMatchingBottomTabRouteForState(state);
- routes.push(createBottomTabNavigator(matchingBottomTabRoute, policyID));
- if (!isNarrowLayout) {
- routes.push(createCentralPaneNavigator({name: SCREENS.REPORT, params: {reportID: reportAttachments.params?.reportID ?? ''}}));
- }
- routes.push(reportAttachments);
+ if (reportAttachments.params?.type === CONST.ATTACHMENT_TYPE.REPORT) {
+ const matchingBottomTabRoute = getMatchingBottomTabRouteForState(state);
+ routes.push(createBottomTabNavigator(matchingBottomTabRoute, policyID));
+ if (!isNarrowLayout) {
+ routes.push(createCentralPaneNavigator({name: SCREENS.REPORT, params: {reportID: reportAttachments.params?.id ?? ''}}));
+ }
+ routes.push(reportAttachments);
- return {
- adaptedState: getRoutesWithIndex(routes),
- metainfo,
- };
+ return {
+ adaptedState: getRoutesWithIndex(routes),
+ metainfo,
+ };
+ }
}
// We need to make sure that this if only handles states where we deeplink to the bottom tab directly
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index bc3d0bba637e..b0df6085aff8 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -767,9 +767,10 @@ type PublicScreensParamList = SharedScreensParamList & {
type AuthScreensParamList = SharedScreensParamList & {
[NAVIGATORS.CENTRAL_PANE_NAVIGATOR]: NavigatorScreenParams;
[SCREENS.CONCIERGE]: undefined;
- [SCREENS.REPORT_ATTACHMENTS]: {
- reportID: string;
+ [SCREENS.ATTACHMENTS]: {
+ id: string;
source: string;
+ type: ValueOf;
};
[SCREENS.PROFILE_AVATAR]: {
accountID: string;
diff --git a/src/pages/PrivateNotes/PrivateNotesListPage.tsx b/src/pages/PrivateNotes/PrivateNotesListPage.tsx
index 1893f81da2fe..f8121af32076 100644
--- a/src/pages/PrivateNotes/PrivateNotesListPage.tsx
+++ b/src/pages/PrivateNotes/PrivateNotesListPage.tsx
@@ -2,6 +2,7 @@ import React, {useMemo} from 'react';
import {withOnyx} from 'react-native-onyx';
import type {OnyxCollection} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
+import {AttachmentContext} from '@components/AttachmentContext';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import ScreenWrapper from '@components/ScreenWrapper';
@@ -29,6 +30,7 @@ type PrivateNotesListPageProps = WithReportAndPrivateNotesOrNotFoundProps &
};
type NoteListItem = {
+ id: string;
title: string;
action: () => void;
brickRoadIndicator: ValueOf | undefined;
@@ -45,18 +47,20 @@ function PrivateNotesListPage({report, personalDetailsList, session}: PrivateNot
*/
function getMenuItem(item: NoteListItem) {
return (
-
+
+
+
);
}
diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx
index 8d11744740bd..df303b763282 100644
--- a/src/pages/home/report/ReportActionItem.tsx
+++ b/src/pages/home/report/ReportActionItem.tsx
@@ -5,6 +5,7 @@ import {InteractionManager, View} from 'react-native';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import type {Emoji} from '@assets/emojis/types';
+import {AttachmentContext} from '@components/AttachmentContext';
import Button from '@components/Button';
import DisplayNames from '@components/DisplayNames';
import Hoverable from '@components/Hoverable';
@@ -373,6 +374,8 @@ function ReportActionItem({
[report, action, toggleContextMenuFromActiveReportAction, transactionThreadReport],
);
+ const attachmentContextValue = useMemo(() => ({id: report.reportID, type: CONST.ATTACHMENT_TYPE.REPORT}), [report.reportID]);
+
const actionableItemButtons: ActionableItem[] = useMemo(() => {
const isWhisperResolution = (action?.originalMessage as OriginalMessageActionableMentionWhisper['originalMessage'])?.resolution !== null;
const isJoinChoice = (action?.originalMessage as OriginalMessageJoinPolicyChangeLog['originalMessage'])?.choice === '';
@@ -587,52 +590,56 @@ function ReportActionItem({
!ReportActionsUtils.isPendingRemove(action);
children = (
- {draftMessage === undefined ? (
-
-
- {hasBeenFlagged && (
-
- )}
- {/**
+
+ {isHidden ? translate('moderation.revealMessage') : translate('moderation.hideMessage')}
+
+
+ )}
+ {/**
These are the actionable buttons that appear at the bottom of a Concierge message
for example: Invite a user mentioned but not a member of the room
https://github.com/Expensify/App/issues/32741
*/}
- {actionableItemButtons.length > 0 && (
-
- )}
-
- ) : (
-
- )}
+ {actionableItemButtons.length > 0 && (
+
+ )}
+
+ ) : (
+
+ )}
+
);
}
diff --git a/src/pages/home/report/ReportAttachments.tsx b/src/pages/home/report/ReportAttachments.tsx
index 82b49d1e260c..e6dbd760e5af 100644
--- a/src/pages/home/report/ReportAttachments.tsx
+++ b/src/pages/home/report/ReportAttachments.tsx
@@ -6,13 +6,14 @@ import ComposerFocusManager from '@libs/ComposerFocusManager';
import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
import * as ReportUtils from '@libs/ReportUtils';
+import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
-type ReportAttachmentsProps = StackScreenProps;
+type ReportAttachmentsProps = StackScreenProps;
function ReportAttachments({route}: ReportAttachmentsProps) {
- const reportID = route.params.reportID;
+ const reportID = route.params.id;
const report = ReportUtils.getReport(reportID);
// In native the imported images sources are of type number. Ref: https://reactnative.dev/docs/image#imagesource
@@ -20,7 +21,7 @@ function ReportAttachments({route}: ReportAttachmentsProps) {
const onCarouselAttachmentChange = useCallback(
(attachment: Attachment) => {
- const routeToNavigate = ROUTES.REPORT_ATTACHMENTS.getRoute(reportID, String(attachment.source));
+ const routeToNavigate = ROUTES.ATTACHMENTS.getRoute(reportID, CONST.ATTACHMENT_TYPE.REPORT, String(attachment.source));
Navigation.navigate(routeToNavigate);
},
[reportID],
From 68f91157f2db2f337a342ea6244151f4ad0cd90f Mon Sep 17 00:00:00 2001
From: nkdengineer
Date: Thu, 25 Apr 2024 12:35:11 +0700
Subject: [PATCH 008/207] fix navigation issue
---
src/ROUTES.ts | 3 +-
src/components/AttachmentContext.ts | 15 ++--
src/components/AttachmentModal.tsx | 11 +++
.../extractAttachmentsFromNote.ts | 80 +++++++++++++++++++
.../Attachments/AttachmentCarousel/index.tsx | 20 +++--
.../Attachments/AttachmentCarousel/types.ts | 8 ++
.../HTMLRenderers/ImageRenderer.tsx | 14 ++--
src/libs/Middleware/SaveResponseInOnyx.ts | 2 +-
src/libs/Navigation/NavigationRoot.tsx | 2 +-
src/libs/Navigation/linkTo.ts | 10 +--
src/libs/Navigation/linkingConfig/config.ts | 1 -
.../linkingConfig/getAdaptedStateFromPath.ts | 1 -
src/libs/Navigation/types.ts | 3 +-
.../PrivateNotes/PrivateNotesListPage.tsx | 10 ++-
src/pages/home/report/ReportActionItem.tsx | 2 +-
src/pages/home/report/ReportAttachments.tsx | 11 ++-
16 files changed, 152 insertions(+), 41 deletions(-)
create mode 100644 src/components/Attachments/AttachmentCarousel/extractAttachmentsFromNote.ts
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 47fe2516c7d7..2e65cee4ebb0 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -227,7 +227,8 @@ const ROUTES = {
},
ATTACHMENTS: {
route: 'attachment',
- getRoute: (id: string, type: ValueOf, url: string) => `attachment?source=${encodeURIComponent(url)}&type=${type}${id ? `&id=${id}` : ''}`,
+ getRoute: (reportID: string, type: ValueOf, url: string, accountID?: number) =>
+ `attachment?source=${encodeURIComponent(url)}&type=${type}${reportID ? `&reportID=${reportID}` : ''}${accountID ? `&accountID=${accountID}` : ''}`,
},
REPORT_PARTICIPANTS: {
route: 'r/:reportID/participants',
diff --git a/src/components/AttachmentContext.ts b/src/components/AttachmentContext.ts
index 5fcb9ce7b0a4..4ed6bdc9084f 100644
--- a/src/components/AttachmentContext.ts
+++ b/src/components/AttachmentContext.ts
@@ -1,17 +1,22 @@
import {createContext} from 'react';
-import {ValueOf} from 'type-fest';
-import CONST from '@src/CONST';
+import type {ValueOf} from 'type-fest';
+import type CONST from '@src/CONST';
type AttachmentContextProps = {
type?: ValueOf;
- id?: string;
+ reportID?: string;
+ accountID?: number;
};
const AttachmentContext = createContext({
type: undefined,
- id: undefined,
+ reportID: undefined,
+ accountID: undefined,
});
AttachmentContext.displayName = 'AttachmentContext';
-export {AttachmentContext};
+export {
+ // eslint-disable-next-line import/prefer-default-export
+ AttachmentContext,
+};
diff --git a/src/components/AttachmentModal.tsx b/src/components/AttachmentModal.tsx
index 7d13524b78df..39a4ead98e15 100644
--- a/src/components/AttachmentModal.tsx
+++ b/src/components/AttachmentModal.tsx
@@ -5,6 +5,7 @@ import {GestureHandlerRootView} from 'react-native-gesture-handler';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import {useSharedValue} from 'react-native-reanimated';
+import type {ValueOf} from 'type-fest';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useStyleUtils from '@hooks/useStyleUtils';
@@ -106,6 +107,12 @@ type AttachmentModalProps = AttachmentModalOnyxProps & {
/** The report that has this attachment */
report?: OnyxEntry | EmptyObject;
+ /** The type of the attachment */
+ type?: ValueOf;
+
+ /** If the attachment originates from a note, the accountID will represent the author of that note. */
+ accountID?: number;
+
/** Optional callback to fire when we want to do something after modal show. */
onModalShow?: () => void;
@@ -163,6 +170,8 @@ function AttachmentModal({
onModalClose = () => {},
isLoading = false,
shouldShowNotFoundPage = false,
+ type = undefined,
+ accountID = undefined,
}: AttachmentModalProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
@@ -524,6 +533,8 @@ function AttachmentModal({
)}
{!isEmptyObject(report) && !isReceiptAttachment ? (
{
+ if (name === 'video') {
+ const source = tryResolveUrlFromApiRoot(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]);
+ if (uniqueSources.has(source)) {
+ return;
+ }
+
+ uniqueSources.add(source);
+ const splittedUrl = attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE].split('/');
+ attachments.unshift({
+ source: tryResolveUrlFromApiRoot(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]),
+ isAuthTokenRequired: Boolean(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]),
+ file: {name: splittedUrl[splittedUrl.length - 1]},
+ duration: Number(attribs[CONST.ATTACHMENT_DURATION_ATTRIBUTE]),
+ isReceipt: false,
+ hasBeenFlagged: false,
+ });
+ return;
+ }
+
+ if (name === 'img' && attribs.src) {
+ const expensifySource = attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE];
+ const source = tryResolveUrlFromApiRoot(expensifySource || attribs.src);
+ if (uniqueSources.has(source)) {
+ return;
+ }
+
+ uniqueSources.add(source);
+ let fileName = attribs[CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE] || FileUtils.getFileName(`${source}`);
+
+ // Public image URLs might lack a file extension in the source URL, without an extension our
+ // AttachmentView fails to recognize them as images and renders fallback content instead.
+ // We apply this small hack to add an image extension and ensure AttachmentView renders the image.
+ const fileInfo = FileUtils.splitExtensionFromFileName(fileName);
+ if (!fileInfo.fileExtension) {
+ fileName = `${fileInfo.fileName || 'image'}.jpg`;
+ }
+
+ // By iterating actions in chronological order and prepending each attachment
+ // we ensure correct order of attachments even across actions with multiple attachments.
+ attachments.unshift({
+ reportActionID: attribs['data-id'],
+ source,
+ isAuthTokenRequired: Boolean(expensifySource),
+ file: {name: fileName},
+ isReceipt: false,
+ hasBeenFlagged: attribs['data-flagged'] === 'true',
+ });
+ }
+ },
+ });
+
+ htmlParser.write(targetNote);
+ htmlParser.end();
+
+ return attachments.reverse();
+}
+
+export default extractAttachmentsFromNote;
diff --git a/src/components/Attachments/AttachmentCarousel/index.tsx b/src/components/Attachments/AttachmentCarousel/index.tsx
index 3a7e0f19c4cd..64d694683b9b 100644
--- a/src/components/Attachments/AttachmentCarousel/index.tsx
+++ b/src/components/Attachments/AttachmentCarousel/index.tsx
@@ -19,6 +19,7 @@ import AttachmentCarouselCellRenderer from './AttachmentCarouselCellRenderer';
import CarouselActions from './CarouselActions';
import CarouselButtons from './CarouselButtons';
import CarouselItem from './CarouselItem';
+import extractAttachmentsFromNote from './extractAttachmentsFromNote';
import extractAttachmentsFromReport from './extractAttachmentsFromReport';
import type {AttachmentCaraouselOnyxProps, AttachmentCarouselProps, UpdatePageProps} from './types';
import useCarouselArrows from './useCarouselArrows';
@@ -29,7 +30,7 @@ const viewabilityConfig = {
itemVisiblePercentThreshold: 95,
};
-function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility}: AttachmentCarouselProps) {
+function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility, type, accountID}: AttachmentCarouselProps) {
const theme = useTheme();
const {translate} = useLocalize();
const styles = useThemeStyles();
@@ -49,19 +50,24 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
useEffect(() => {
const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined;
const attachmentsFromReport = extractAttachmentsFromReport(parentReportAction, reportActions ?? undefined);
+ let attachmentsFromNote: Attachment[] = [];
+ if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) {
+ attachmentsFromNote = extractAttachmentsFromNote(report.reportID, accountID);
+ }
+ const targetAttachments = type === CONST.ATTACHMENT_TYPE.REPORT ? attachmentsFromReport : attachmentsFromNote;
- if (isEqual(attachments, attachmentsFromReport)) {
+ if (isEqual(attachments, targetAttachments)) {
return;
}
- const initialPage = attachmentsFromReport.findIndex(compareImage);
+ const initialPage = targetAttachments.findIndex(compareImage);
// Dismiss the modal when deleting an attachment during its display in preview.
if (initialPage === -1 && attachments.find(compareImage)) {
Navigation.dismissModal();
} else {
setPage(initialPage);
- setAttachments(attachmentsFromReport);
+ setAttachments(targetAttachments);
// Update the download button visibility in the parent modal
if (setDownloadButtonVisibility) {
@@ -69,11 +75,11 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
}
// Update the parent modal's state with the source and name from the mapped attachments
- if (attachmentsFromReport[initialPage] !== undefined && onNavigate) {
- onNavigate(attachmentsFromReport[initialPage]);
+ if (targetAttachments[initialPage] !== undefined && onNavigate) {
+ onNavigate(targetAttachments[initialPage]);
}
}
- }, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate]);
+ }, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, report.reportID]);
/** Updates the page state when the user navigates between attachments */
const updatePage = useCallback(
diff --git a/src/components/Attachments/AttachmentCarousel/types.ts b/src/components/Attachments/AttachmentCarousel/types.ts
index 8ba3489a5fcf..d31ebbd328cd 100644
--- a/src/components/Attachments/AttachmentCarousel/types.ts
+++ b/src/components/Attachments/AttachmentCarousel/types.ts
@@ -1,6 +1,8 @@
import type {ViewToken} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
+import type {ValueOf} from 'type-fest';
import type {Attachment, AttachmentSource} from '@components/Attachments/types';
+import type CONST from '@src/CONST';
import type {Report, ReportActions} from '@src/types/onyx';
type UpdatePageProps = {
@@ -28,6 +30,12 @@ type AttachmentCarouselProps = AttachmentCaraouselOnyxProps & {
/** The report currently being looked at */
report: Report;
+ /** The type of the attachment */
+ type?: ValueOf;
+
+ /** If the attachment originates from a note, the accountID will represent the author of that note. */
+ accountID?: number;
+
/** A callback that is called when swipe-down-to-close gesture happens */
onClose: () => void;
};
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
index 4e78f127d06c..36238d635d83 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
@@ -80,17 +80,19 @@ function ImageRenderer({tnode}: ImageRendererProps) {
{({anchor, report, action, checkIfContextMenuActive}) => (
- {({id, type}) => (
+ {({reportID, accountID, type}) => (
{
+ if (!source || !type) {
+ return;
+ }
let route = '';
- if (source && type) {
- if (id) {
- route = ROUTES.ATTACHMENTS?.getRoute(id, type, source);
- Navigation.navigate(route);
- }
+ if (reportID) {
+ route = ROUTES.ATTACHMENTS?.getRoute(reportID, type, source, accountID);
}
+
+ Navigation.navigate(route);
}}
onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
shouldUseHapticsOnLongPress
diff --git a/src/libs/Middleware/SaveResponseInOnyx.ts b/src/libs/Middleware/SaveResponseInOnyx.ts
index 58052c971505..4f06f206eb37 100644
--- a/src/libs/Middleware/SaveResponseInOnyx.ts
+++ b/src/libs/Middleware/SaveResponseInOnyx.ts
@@ -33,7 +33,7 @@ const SaveResponseInOnyx: Middleware = (requestResponse, request) =>
OnyxUpdates.saveUpdateInformation(responseToApply);
// Ensure the queue is paused while the client resolves the gap in onyx updates so that updates are guaranteed to happen in a specific order.
- console.log("**********************", {command: request.command})
+
return Promise.resolve({
...response,
shouldPauseQueue: true,
diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx
index 4c3084c5291a..f143d6b2bcc1 100644
--- a/src/libs/Navigation/NavigationRoot.tsx
+++ b/src/libs/Navigation/NavigationRoot.tsx
@@ -118,7 +118,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N
if (!state) {
return;
}
- console.log("777777777", state.routes)
+
const activeWorkspaceID = getPolicyIDFromState(state as NavigationState);
// Performance optimization to avoid context consumers to delay first render
setTimeout(() => {
diff --git a/src/libs/Navigation/linkTo.ts b/src/libs/Navigation/linkTo.ts
index e644127cac61..e08237c04601 100644
--- a/src/libs/Navigation/linkTo.ts
+++ b/src/libs/Navigation/linkTo.ts
@@ -148,23 +148,20 @@ export default function linkTo(navigation: NavigationContainerRef
const onboardingModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.ONBOARDING_MODAL_NAVIGATOR);
const welcomeVideoModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.WELCOME_VIDEO_MODAL_NAVIGATOR);
const attachmentsScreen = state.routes.find((route) => route.name === SCREENS.ATTACHMENTS);
- console.log('9999999999', state.routes);
if (isNarrowLayout) {
metainfo.isFullScreenNavigatorMandatory = false;
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index b0df6085aff8..20e1be99d5a1 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -768,9 +768,10 @@ type AuthScreensParamList = SharedScreensParamList & {
[NAVIGATORS.CENTRAL_PANE_NAVIGATOR]: NavigatorScreenParams;
[SCREENS.CONCIERGE]: undefined;
[SCREENS.ATTACHMENTS]: {
- id: string;
+ reportID: string;
source: string;
type: ValueOf;
+ accountID: string;
};
[SCREENS.PROFILE_AVATAR]: {
accountID: string;
diff --git a/src/pages/PrivateNotes/PrivateNotesListPage.tsx b/src/pages/PrivateNotes/PrivateNotesListPage.tsx
index f8121af32076..286c91d628fd 100644
--- a/src/pages/PrivateNotes/PrivateNotesListPage.tsx
+++ b/src/pages/PrivateNotes/PrivateNotesListPage.tsx
@@ -1,4 +1,4 @@
-import React, {useMemo} from 'react';
+import React, {useCallback, useMemo} from 'react';
import {withOnyx} from 'react-native-onyx';
import type {OnyxCollection} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
@@ -30,24 +30,26 @@ type PrivateNotesListPageProps = WithReportAndPrivateNotesOrNotFoundProps &
};
type NoteListItem = {
- id: string;
title: string;
action: () => void;
brickRoadIndicator: ValueOf | undefined;
note: string;
disabled: boolean;
+ reportID: string;
+ accountID: string;
};
function PrivateNotesListPage({report, personalDetailsList, session}: PrivateNotesListPageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
+ const getAttachmentValue = useCallback((item: NoteListItem) => ({reportID: item.reportID, accountID: Number(item.accountID), type: CONST.ATTACHMENT_TYPE.NOTE}), []);
/**
* Gets the menu item for each workspace
*/
function getMenuItem(item: NoteListItem) {
return (
-
+
{
const privateNote = report.privateNotes?.[Number(accountID)];
return {
+ reportID: report.reportID,
+ accountID,
title: Number(session?.accountID) === Number(accountID) ? translate('privateNotes.myNote') : personalDetailsList?.[accountID]?.login ?? '',
action: () => Navigation.navigate(ROUTES.PRIVATE_NOTES_EDIT.getRoute(report.reportID, accountID)),
brickRoadIndicator: privateNoteBrickRoadIndicator(Number(accountID)),
diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx
index df303b763282..60b86c209c68 100644
--- a/src/pages/home/report/ReportActionItem.tsx
+++ b/src/pages/home/report/ReportActionItem.tsx
@@ -374,7 +374,7 @@ function ReportActionItem({
[report, action, toggleContextMenuFromActiveReportAction, transactionThreadReport],
);
- const attachmentContextValue = useMemo(() => ({id: report.reportID, type: CONST.ATTACHMENT_TYPE.REPORT}), [report.reportID]);
+ const attachmentContextValue = useMemo(() => ({reportID: report.reportID, type: CONST.ATTACHMENT_TYPE.REPORT}), [report.reportID]);
const actionableItemButtons: ActionableItem[] = useMemo(() => {
const isWhisperResolution = (action?.originalMessage as OriginalMessageActionableMentionWhisper['originalMessage'])?.resolution !== null;
diff --git a/src/pages/home/report/ReportAttachments.tsx b/src/pages/home/report/ReportAttachments.tsx
index e6dbd760e5af..3ff472baee40 100644
--- a/src/pages/home/report/ReportAttachments.tsx
+++ b/src/pages/home/report/ReportAttachments.tsx
@@ -6,14 +6,15 @@ import ComposerFocusManager from '@libs/ComposerFocusManager';
import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
import * as ReportUtils from '@libs/ReportUtils';
-import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
type ReportAttachmentsProps = StackScreenProps;
function ReportAttachments({route}: ReportAttachmentsProps) {
- const reportID = route.params.id;
+ const reportID = route.params.reportID;
+ const type = route.params.type;
+ const accountID = route.params.accountID;
const report = ReportUtils.getReport(reportID);
// In native the imported images sources are of type number. Ref: https://reactnative.dev/docs/image#imagesource
@@ -21,14 +22,16 @@ function ReportAttachments({route}: ReportAttachmentsProps) {
const onCarouselAttachmentChange = useCallback(
(attachment: Attachment) => {
- const routeToNavigate = ROUTES.ATTACHMENTS.getRoute(reportID, CONST.ATTACHMENT_TYPE.REPORT, String(attachment.source));
+ const routeToNavigate = ROUTES.ATTACHMENTS.getRoute(reportID, type, String(attachment.source), Number(accountID));
Navigation.navigate(routeToNavigate);
},
- [reportID],
+ [reportID, accountID, type],
);
return (
Date: Thu, 25 Apr 2024 12:36:21 +0700
Subject: [PATCH 009/207] fix remove unused change
---
src/libs/Middleware/SaveResponseInOnyx.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/libs/Middleware/SaveResponseInOnyx.ts b/src/libs/Middleware/SaveResponseInOnyx.ts
index 4f06f206eb37..ffe4f8a9bea9 100644
--- a/src/libs/Middleware/SaveResponseInOnyx.ts
+++ b/src/libs/Middleware/SaveResponseInOnyx.ts
@@ -33,7 +33,6 @@ const SaveResponseInOnyx: Middleware = (requestResponse, request) =>
OnyxUpdates.saveUpdateInformation(responseToApply);
// Ensure the queue is paused while the client resolves the gap in onyx updates so that updates are guaranteed to happen in a specific order.
-
return Promise.resolve({
...response,
shouldPauseQueue: true,
From 07cb16f10664cdb345647401804793d455b2ef9a Mon Sep 17 00:00:00 2001
From: nkdengineer
Date: Thu, 25 Apr 2024 12:38:18 +0700
Subject: [PATCH 010/207] fix remove unused change
---
src/libs/Navigation/NavigationRoot.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx
index f143d6b2bcc1..506eae2bdfd2 100644
--- a/src/libs/Navigation/NavigationRoot.tsx
+++ b/src/libs/Navigation/NavigationRoot.tsx
@@ -118,7 +118,6 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N
if (!state) {
return;
}
-
const activeWorkspaceID = getPolicyIDFromState(state as NavigationState);
// Performance optimization to avoid context consumers to delay first render
setTimeout(() => {
From 8d8867d24826a754f7abf6d1078dfb8a78c5f600 Mon Sep 17 00:00:00 2001
From: nkdengineer
Date: Thu, 25 Apr 2024 14:32:11 +0700
Subject: [PATCH 011/207] fix remove unused change
---
src/libs/Navigation/linkTo.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libs/Navigation/linkTo.ts b/src/libs/Navigation/linkTo.ts
index e08237c04601..863cb102add4 100644
--- a/src/libs/Navigation/linkTo.ts
+++ b/src/libs/Navigation/linkTo.ts
@@ -154,6 +154,7 @@ export default function linkTo(navigation: NavigationContainerRef
Date: Thu, 25 Apr 2024 14:42:53 +0700
Subject: [PATCH 012/207] fix typecheck
---
src/ROUTES.ts | 2 +-
.../HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx | 7 +++----
.../Navigation/linkingConfig/getAdaptedStateFromPath.ts | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 249ba1c2571a..a1c609db6217 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -223,7 +223,7 @@ const ROUTES = {
ATTACHMENTS: {
route: 'attachment',
getRoute: (reportID: string, type: ValueOf, url: string, accountID?: number) =>
- `attachment?source=${encodeURIComponent(url)}&type=${type}${reportID ? `&reportID=${reportID}` : ''}${accountID ? `&accountID=${accountID}` : ''}`,
+ `attachment?source=${encodeURIComponent(url)}&type=${type}${reportID ? `&reportID=${reportID}` : ''}${accountID ? `&accountID=${accountID}` : ''}` as const,
},
REPORT_PARTICIPANTS: {
route: 'r/:reportID/participants',
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
index 36238d635d83..221731bbeef6 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx
@@ -87,12 +87,11 @@ function ImageRenderer({tnode}: ImageRendererProps) {
if (!source || !type) {
return;
}
- let route = '';
+
if (reportID) {
- route = ROUTES.ATTACHMENTS?.getRoute(reportID, type, source, accountID);
+ const route = ROUTES.ATTACHMENTS?.getRoute(reportID, type, source, accountID);
+ Navigation.navigate(route);
}
-
- Navigation.navigate(route);
}}
onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
shouldUseHapticsOnLongPress
diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
index 4faa12696726..9a951bc4f9f2 100644
--- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
+++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
@@ -306,7 +306,7 @@ function getAdaptedState(state: PartialState
const matchingBottomTabRoute = getMatchingBottomTabRouteForState(state);
routes.push(createBottomTabNavigator(matchingBottomTabRoute, policyID));
if (!isNarrowLayout) {
- routes.push(createCentralPaneNavigator({name: SCREENS.REPORT, params: {reportID: reportAttachments.params?.id ?? ''}}));
+ routes.push(createCentralPaneNavigator({name: SCREENS.REPORT, params: {reportID: reportAttachments.params?.reportID ?? ''}}));
}
routes.push(reportAttachments);
From c48b0aa66fccfbdf9e84733e8bdeb08a1b4a57f0 Mon Sep 17 00:00:00 2001
From: nkdengineer
Date: Thu, 25 Apr 2024 14:49:50 +0700
Subject: [PATCH 013/207] fix lint
---
src/components/Attachments/AttachmentCarousel/index.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/Attachments/AttachmentCarousel/index.tsx b/src/components/Attachments/AttachmentCarousel/index.tsx
index 64d694683b9b..6e8843472377 100644
--- a/src/components/Attachments/AttachmentCarousel/index.tsx
+++ b/src/components/Attachments/AttachmentCarousel/index.tsx
@@ -79,7 +79,7 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
onNavigate(targetAttachments[initialPage]);
}
}
- }, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, report.reportID]);
+ }, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, report.reportID, type]);
/** Updates the page state when the user navigates between attachments */
const updatePage = useCallback(
From aef525237d188ca52a7256b45bc2ece9f680f3d4 Mon Sep 17 00:00:00 2001
From: nkdengineer
Date: Thu, 25 Apr 2024 15:39:59 +0700
Subject: [PATCH 014/207] fix native issue
---
.../AttachmentCarousel/index.native.tsx | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/components/Attachments/AttachmentCarousel/index.native.tsx b/src/components/Attachments/AttachmentCarousel/index.native.tsx
index f6d63fc9307d..c97b16ca2988 100644
--- a/src/components/Attachments/AttachmentCarousel/index.native.tsx
+++ b/src/components/Attachments/AttachmentCarousel/index.native.tsx
@@ -9,15 +9,17 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import variables from '@styles/variables';
+import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import CarouselButtons from './CarouselButtons';
+import extractAttachmentsFromNote from './extractAttachmentsFromNote';
import extractAttachmentsFromReport from './extractAttachmentsFromReport';
import type {AttachmentCarouselPagerHandle} from './Pager';
import AttachmentCarouselPager from './Pager';
import type {AttachmentCaraouselOnyxProps, AttachmentCarouselProps} from './types';
import useCarouselArrows from './useCarouselArrows';
-function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility, onClose}: AttachmentCarouselProps) {
+function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility, onClose, type, accountID}: AttachmentCarouselProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const pagerRef = useRef(null);
@@ -31,15 +33,19 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
useEffect(() => {
const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined;
const attachmentsFromReport = extractAttachmentsFromReport(parentReportAction, reportActions);
-
- const initialPage = attachmentsFromReport.findIndex(compareImage);
+ let attachmentsFromNote: Attachment[] = [];
+ if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) {
+ attachmentsFromNote = extractAttachmentsFromNote(report.reportID, accountID);
+ }
+ const targetAttachments = type === CONST.ATTACHMENT_TYPE.REPORT ? attachmentsFromReport : attachmentsFromNote;
+ const initialPage = targetAttachments.findIndex(compareImage);
// Dismiss the modal when deleting an attachment during its display in preview.
if (initialPage === -1 && attachments.find(compareImage)) {
Navigation.dismissModal();
} else {
setPage(initialPage);
- setAttachments(attachmentsFromReport);
+ setAttachments(targetAttachments);
// Update the download button visibility in the parent modal
if (setDownloadButtonVisibility) {
@@ -47,8 +53,8 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
}
// Update the parent modal's state with the source and name from the mapped attachments
- if (attachmentsFromReport[initialPage] !== undefined && onNavigate) {
- onNavigate(attachmentsFromReport[initialPage]);
+ if (targetAttachments[initialPage] !== undefined && onNavigate) {
+ onNavigate(targetAttachments[initialPage]);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
From 851f959154367ef5b46d71dcad94061e59078e8f Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Mon, 29 Apr 2024 16:57:03 +0530
Subject: [PATCH 015/207] Navigate to console page
---
src/CONST.ts | 1 -
src/ROUTES.ts | 5 +-
.../BaseClientSideLoggingToolMenu.tsx | 22 +-
.../ConsoleComponents.tsx | 193 ------------------
.../ConsoleModal.tsx | 44 ----
.../index.android.tsx | 2 +-
.../ClientSideLoggingToolMenu/index.ios.tsx | 2 +-
.../ClientSideLoggingToolMenu/index.tsx | 2 +-
.../ClientSideLoggingToolMenu/types.ts | 2 -
src/components/Modal/index.tsx | 2 +-
src/components/TestToolsModal.tsx | 5 +-
src/libs/Navigation/linkingConfig/config.ts | 2 +-
src/libs/Navigation/types.ts | 4 +-
src/pages/settings/AboutPage/ConsolePage.tsx | 179 +++++++++++++++-
.../ShareLogList/BaseShareLogList.tsx | 8 +-
.../AboutPage/ShareLogList/index.native.tsx | 4 +-
.../settings/AboutPage/ShareLogList/index.tsx | 7 +-
src/pages/settings/AboutPage/ShareLogPage.tsx | 7 +-
.../Troubleshoot/TroubleshootPage.tsx | 2 +-
.../utils/generators/ModalStyleUtils.ts | 23 ---
20 files changed, 214 insertions(+), 302 deletions(-)
delete mode 100644 src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
delete mode 100644 src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
diff --git a/src/CONST.ts b/src/CONST.ts
index 893dc008786b..2cd614b74816 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -860,7 +860,6 @@ const CONST = {
POPOVER: 'popover',
RIGHT_DOCKED: 'right_docked',
ONBOARDING: 'onboarding',
- CENTERED_SMALL_AND_UNSWIPEABLE: 'centered_small_and_unswipeable'
},
ANCHOR_ORIGIN_VERTICAL: {
TOP: 'top',
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 71e673aea994..db9ae77fd0e8 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -172,7 +172,10 @@ const ROUTES = {
SETTINGS_STATUS_CLEAR_AFTER_DATE: 'settings/profile/status/clear-after/date',
SETTINGS_STATUS_CLEAR_AFTER_TIME: 'settings/profile/status/clear-after/time',
SETTINGS_TROUBLESHOOT: 'settings/troubleshoot',
- SETTINGS_CONSOLE: 'settings/troubleshoot/console',
+ SETTINGS_CONSOLE: {
+ route: 'settings/troubleshoot/console',
+ getRoute: (isViaTestToolsModal = false) => `settings/troubleshoot/console?isViaTestToolsModal=${isViaTestToolsModal}` as const,
+ },
SETTINGS_SHARE_LOG: {
route: 'settings/troubleshoot/console/share-log',
getRoute: (source: string, isViaTestToolsModal = false) => `settings/troubleshoot/console/share-log?source=${encodeURI(source)}&isViaTestToolsModal=${isViaTestToolsModal}` as const,
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index 9b5faac55bc4..7d27caa997f7 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -1,4 +1,4 @@
-import React, {useState} from 'react';
+import React from 'react';
import {Alert} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
@@ -12,7 +12,8 @@ import * as Console from '@libs/actions/Console';
import {parseStringifiedMessages} from '@libs/Console';
import ONYXKEYS from '@src/ONYXKEYS';
import type {CapturedLogs, Log} from '@src/types/onyx';
-import ConsoleModal from "./ConsoleModal";
+import Navigation from "@navigation/Navigation";
+import ROUTES from "@src/ROUTES";
type BaseClientSideLoggingToolMenuOnyxProps = {
/** Logs captured on the current device */
@@ -64,7 +65,6 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
Console.disableLoggingAndFlushLogs();
};
const styles = useThemeStyles();
- const [isConsoleModalVisible, setIsConsoleModalVisible] = useState(false);
return (
<>
@@ -75,15 +75,18 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
onToggle={onToggle}
/>
- {!!shouldStoreLogs && isViaTestToolsModal &&
+ {!!shouldStoreLogs && isViaTestToolsModal && (
setIsConsoleModalVisible(true)}
+ onPress={() => {
+ closeTestToolsModal()
+ Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(isViaTestToolsModal))
+ }}
/>
- }
+ )}
{!!file && (
<>
{`path: ${file.path}`}
@@ -96,13 +99,6 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
>
)}
- {
- setIsConsoleModalVisible(false)
- }}
- closeTestToolsModal={closeTestToolsModal}
- />
>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx b/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
deleted file mode 100644
index d7e53223c3a5..000000000000
--- a/src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx
+++ /dev/null
@@ -1,193 +0,0 @@
-import React, {useCallback, useEffect, useMemo, useState} from 'react';
-import type {ListRenderItem, ListRenderItemInfo} from 'react-native';
-import {View} from 'react-native';
-import CONST from "@src/CONST";
-import useThemeStyles from "@hooks/useThemeStyles";
-import useLocalize from "@hooks/useLocalize";
-import InvertedFlatList from "@components/InvertedFlatList";
-import Text from "@components/Text";
-import type {CapturedLogs, Log} from "@src/types/onyx";
-import {format} from "date-fns";
-import {withOnyx} from "react-native-onyx";
-import type {OnyxEntry} from "react-native-onyx";
-import ONYXKEYS from "@src/ONYXKEYS";
-import {createLog, parseStringifiedMessages, sanitizeConsoleInput} from "@libs/Console";
-import {addLog} from "@userActions/Console";
-import useKeyboardShortcut from "@hooks/useKeyboardShortcut";
-import localFileDownload from "@libs/localFileDownload";
-import localFileCreate from "@libs/localFileCreate";
-import Navigation from "@navigation/Navigation";
-import ROUTES from "@src/ROUTES";
-import Button from "@components/Button";
-import * as Expensicons from "@components/Icon/Expensicons";
-import TextInput from "@components/TextInput";
-import ConfirmModal from "@components/ConfirmModal";
-
-type ConsoleComponentsOnyxProps = {
- /** Logs captured on the current device */
- capturedLogs: OnyxEntry;
-
- /** Whether or not logs should be stored */
- shouldStoreLogs: OnyxEntry;
-};
-
-type ConsoleComponentsProps = {
- /** Action to run when pressing Share button */
- onClose?: () => void;
- /** Boolean to know if console logs have been opened via test tools modal */
- isViaTestToolsModal: boolean
-} & ConsoleComponentsOnyxProps;
-
-
-function ConsoleComponents({capturedLogs, shouldStoreLogs, onClose, isViaTestToolsModal}: ConsoleComponentsProps) {
- const styles = useThemeStyles();
- const {translate} = useLocalize();
-
- const [input, setInput] = useState('');
- const [logs, setLogs] = useState(capturedLogs);
- const [isGeneratingLogsFile, setIsGeneratingLogsFile] = useState(false);
- const [isLimitModalVisible, setIsLimitModalVisible] = useState(false);
-
- const logsList = useMemo(
- () =>
- Object.entries(logs ?? {})
- .map(([key, value]) => ({key, ...value}))
- .reverse(),
- [logs],
- );
-
- useEffect(() => {
- if (!shouldStoreLogs) {
- return;
- }
-
- setLogs((prevLogs) => ({...prevLogs, ...capturedLogs}));
- }, [capturedLogs, shouldStoreLogs]);
-
- const renderItem: ListRenderItem = useCallback(
- ({item}: ListRenderItemInfo) => {
- if (!item) {
- return null;
- }
-
- return (
-
- {`${format(new Date(item.time), CONST.DATE.FNS_DB_FORMAT_STRING)} ${item.message}`}
-
- );
- },
- [styles.mb2],
- );
-
- const executeArbitraryCode = () => {
- const sanitizedInput = sanitizeConsoleInput(input);
-
- const output = createLog(sanitizedInput);
- output.forEach((log) => addLog(log));
- setInput('');
- };
-
- useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, executeArbitraryCode);
-
- const saveLogs = () => {
- const logsWithParsedMessages = parseStringifiedMessages(logsList);
-
- localFileDownload('logs', JSON.stringify(logsWithParsedMessages, null, 2));
- };
-
- const shareLogs = () => {
- setIsGeneratingLogsFile(true);
- const logsWithParsedMessages = parseStringifiedMessages(logsList);
-
- // 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}) => {
- setIsGeneratingLogsFile(false);
-
- // if the file size is too large to send it as an attachment, show a modal and return
- if (size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) {
- setIsLimitModalVisible(true);
-
- return;
- }
-
- if (onClose) {
- onClose()
- }
- Navigation.navigate(ROUTES.SETTINGS_SHARE_LOG.getRoute(path, isViaTestToolsModal));
- });
- };
-
- const mhModal = isViaTestToolsModal ? styles.mh2 : undefined;
-
- return (
- <>
-
-
- {translate('initialSettingsPage.debugConsole.noLogsAvailable')}}
- />
-
-
-
-
-
-
-
-
-
-
- setIsLimitModalVisible(false)}
- prompt={translate('initialSettingsPage.debugConsole.logSizeTooLarge', {
- size: CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE / 1024 / 1024,
- })}
- shouldShowCancelButton={false}
- confirmText={translate('common.ok')}
- />
- >
- );
-}
-
-ConsoleComponents.displayName = 'ConsoleModal';
-
-
-export default withOnyx({
- capturedLogs: {
- key: ONYXKEYS.LOGS,
- },
- shouldStoreLogs: {
- key: ONYXKEYS.SHOULD_STORE_LOGS,
- },
-})(ConsoleComponents);
diff --git a/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx b/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
deleted file mode 100644
index 4d405db69226..000000000000
--- a/src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import React from 'react';
-import {View} from 'react-native';
-import CONST from "@src/CONST";
-import Modal from "@components/Modal";
-import useWindowDimensions from "@hooks/useWindowDimensions";
-import useStyleUtils from "@hooks/useStyleUtils";
-import ConsoleComponents from "./ConsoleComponents";
-
-type ConsoleModalProps = {
- /** Locally created file */
- isVisible: boolean
- /** Action to run when pressing Share button */
- onClose: () => void;
- /** Action to close the test tools modal */
- closeTestToolsModal?: () => void;
-};
-
-
-function ConsoleModal({isVisible, onClose, closeTestToolsModal}: ConsoleModalProps) {
- const {windowWidth, windowHeight} = useWindowDimensions();
- const StyleUtils = useStyleUtils();
-
- return (
-
-
-
- {
- onClose()
- if (closeTestToolsModal) {
- closeTestToolsModal()
- }
- }} isViaTestToolsModal/>
-
-
- );
-}
-
-ConsoleModal.displayName = 'ConsoleModal';
-
-export default ConsoleModal;
diff --git a/src/components/ClientSideLoggingToolMenu/index.android.tsx b/src/components/ClientSideLoggingToolMenu/index.android.tsx
index 272c563f8e91..b31a9244005d 100644
--- a/src/components/ClientSideLoggingToolMenu/index.android.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.android.tsx
@@ -4,7 +4,7 @@ import Share from 'react-native-share';
import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-import type ClientSideLoggingToolMenuProps from "./types";
+import type ClientSideLoggingToolMenuProps from './types';
function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
diff --git a/src/components/ClientSideLoggingToolMenu/index.ios.tsx b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
index f5de90b00140..e1ad9778830b 100644
--- a/src/components/ClientSideLoggingToolMenu/index.ios.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
@@ -3,7 +3,7 @@ import Share from 'react-native-share';
import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-import type ClientSideLoggingToolMenuProps from "./types";
+import type ClientSideLoggingToolMenuProps from './types';
function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
diff --git a/src/components/ClientSideLoggingToolMenu/index.tsx b/src/components/ClientSideLoggingToolMenu/index.tsx
index 9cb86b46b797..83f28c581b40 100644
--- a/src/components/ClientSideLoggingToolMenu/index.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.tsx
@@ -1,8 +1,8 @@
import React from 'react';
import type {Log} from '@libs/Console';
import localFileDownload from '@libs/localFileDownload';
-import type ClientSideLoggingToolMenuProps from "./types";
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
+import type ClientSideLoggingToolMenuProps from './types';
function ClientSideLoggingToolMenu({isViaTestToolsModal, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
const downloadFile = (logs: Log[]) => {
diff --git a/src/components/ClientSideLoggingToolMenu/types.ts b/src/components/ClientSideLoggingToolMenu/types.ts
index 86ad66dfd33c..4c29a48a9003 100644
--- a/src/components/ClientSideLoggingToolMenu/types.ts
+++ b/src/components/ClientSideLoggingToolMenu/types.ts
@@ -1,8 +1,6 @@
type ClientSideLoggingToolMenuProps = {
/** Boolean to know if this was opened via test tools modal */
isViaTestToolsModal: boolean;
- /** Action to close the test tools modal */
- closeTestToolsModal?: () => void;
};
export default ClientSideLoggingToolMenuProps;
diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx
index 5c31ac60d39d..76f4b251ec83 100644
--- a/src/components/Modal/index.tsx
+++ b/src/components/Modal/index.tsx
@@ -34,7 +34,7 @@ function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = (
const showModal = () => {
const statusBarColor = StatusBar.getBackgroundColor() ?? theme.appBG;
- const isFullScreenModal = type === CONST.MODAL.MODAL_TYPE.CENTERED || type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED || type === CONST.MODAL.MODAL_TYPE.CENTERED_SMALL_AND_UNSWIPEABLE;
+ const isFullScreenModal = type === CONST.MODAL.MODAL_TYPE.CENTERED || type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED;
if (statusBarColor) {
setPreviousStatusBarColor(statusBarColor);
diff --git a/src/components/TestToolsModal.tsx b/src/components/TestToolsModal.tsx
index 2d2ec9eb599d..f9107a5a269a 100644
--- a/src/components/TestToolsModal.tsx
+++ b/src/components/TestToolsModal.tsx
@@ -45,7 +45,10 @@ function TestToolsModal({isTestToolsModalOpen = false}: TestToolsModalProps) {
{translate('initialSettingsPage.troubleshoot.releaseOptions')}
-
+
);
diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts
index b0c4da6fbdbc..0ee8a1153407 100644
--- a/src/libs/Navigation/linkingConfig/config.ts
+++ b/src/libs/Navigation/linkingConfig/config.ts
@@ -209,7 +209,7 @@ const config: LinkingOptions['config'] = {
exact: true,
},
[SCREENS.SETTINGS.CONSOLE]: {
- path: ROUTES.SETTINGS_CONSOLE,
+ path: ROUTES.SETTINGS_CONSOLE.route,
exact: true,
},
[SCREENS.SETTINGS.SHARE_LOG]: ROUTES.SETTINGS_SHARE_LOG.route,
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index 492df5354613..8b0146a7f918 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -111,7 +111,9 @@ type SettingsNavigatorParamList = {
[SCREENS.SETTINGS.TROUBLESHOOT]: undefined;
[SCREENS.SETTINGS.APP_DOWNLOAD_LINKS]: undefined;
[SCREENS.SETTINGS.TROUBLESHOOT]: undefined;
- [SCREENS.SETTINGS.CONSOLE]: undefined;
+ [SCREENS.SETTINGS.CONSOLE]: {
+ isViaTestToolsModal: boolean;
+ };
[SCREENS.SETTINGS.SHARE_LOG]: {
/** URL of the generated file to share logs in a report */
source: string;
diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx
index 48847757dac4..2bd9ad53a544 100644
--- a/src/pages/settings/AboutPage/ConsolePage.tsx
+++ b/src/pages/settings/AboutPage/ConsolePage.tsx
@@ -1,25 +1,192 @@
-import React from 'react';
+import {format} from 'date-fns';
+import React, {useCallback, useEffect, useMemo, useState} from 'react';
+import {View} from 'react-native';
+import type {ListRenderItem, ListRenderItemInfo} from 'react-native';
+import {withOnyx} from 'react-native-onyx';
+import type {OnyxEntry} from 'react-native-onyx';
+import Button from '@components/Button';
+import ConfirmModal from '@components/ConfirmModal';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import * as Expensicons from '@components/Icon/Expensicons';
+import InvertedFlatList from '@components/InvertedFlatList';
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 useThemeStyles from '@hooks/useThemeStyles';
+import {addLog} from '@libs/actions/Console';
+import {createLog, parseStringifiedMessages, sanitizeConsoleInput} from '@libs/Console';
+import type {Log} from '@libs/Console';
+import localFileCreate from '@libs/localFileCreate';
+import localFileDownload from '@libs/localFileDownload';
import Navigation from '@libs/Navigation/Navigation';
+import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
-import ConsoleComponents from "@components/ClientSideLoggingToolMenu/ConsoleComponents";
+import type {CapturedLogs} from '@src/types/onyx';
+import {RouteProp, useRoute} from "@react-navigation/native";
+import {SettingsNavigatorParamList} from "@navigation/types";
+import SCREENS from "@src/SCREENS";
-function ConsolePage() {
+type ConsolePageOnyxProps = {
+ /** Logs captured on the current device */
+ capturedLogs: OnyxEntry;
+
+ /** Whether or not logs should be stored */
+ shouldStoreLogs: OnyxEntry;
+};
+
+type ConsolePageProps = ConsolePageOnyxProps;
+
+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 {translate} = useLocalize();
+ const styles = useThemeStyles();
+
+ const route = useRoute>();
+ const isViaTestToolsModal = route.params?.isViaTestToolsModal ?? false;
+
+ const logsList = useMemo(
+ () =>
+ Object.entries(logs ?? {})
+ .map(([key, value]) => ({key, ...value}))
+ .reverse(),
+ [logs],
+ );
+
+ useEffect(() => {
+ if (!shouldStoreLogs) {
+ return;
+ }
+
+ setLogs((prevLogs) => ({...prevLogs, ...capturedLogs}));
+ }, [capturedLogs, shouldStoreLogs]);
+
+ const executeArbitraryCode = () => {
+ const sanitizedInput = sanitizeConsoleInput(input);
+
+ const output = createLog(sanitizedInput);
+ output.forEach((log) => addLog(log));
+ setInput('');
+ };
+
+ useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, executeArbitraryCode);
+
+ const saveLogs = () => {
+ const logsWithParsedMessages = parseStringifiedMessages(logsList);
+
+ localFileDownload('logs', JSON.stringify(logsWithParsedMessages, null, 2));
+ };
+
+ const shareLogs = () => {
+ setIsGeneratingLogsFile(true);
+ const logsWithParsedMessages = parseStringifiedMessages(logsList);
+
+ // 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}) => {
+ setIsGeneratingLogsFile(false);
+
+ // if the file size is too large to send it as an attachment, show a modal and return
+ if (size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) {
+ setIsLimitModalVisible(true);
+
+ return;
+ }
+
+ Navigation.navigate(ROUTES.SETTINGS_SHARE_LOG.getRoute(path, isViaTestToolsModal));
+ });
+ };
+
+ const renderItem: ListRenderItem = useCallback(
+ ({item}: ListRenderItemInfo) => {
+ if (!item) {
+ return null;
+ }
+
+ return (
+
+ {`${format(new Date(item.time), CONST.DATE.FNS_DB_FORMAT_STRING)} ${item.message}`}
+
+ );
+ },
+ [styles.mb2],
+ );
return (
Navigation.goBack(ROUTES.SETTINGS_TROUBLESHOOT)}
+ onBackButtonPress={() => {
+ Navigation.goBack(isViaTestToolsModal ? undefined : ROUTES.SETTINGS_TROUBLESHOOT)
+ }}
+ />
+
+ {translate('initialSettingsPage.debugConsole.noLogsAvailable')}}
+ />
+
+
+
+
+
+
+
+
+
+ setIsLimitModalVisible(false)}
+ prompt={translate('initialSettingsPage.debugConsole.logSizeTooLarge', {
+ size: CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE / 1024 / 1024,
+ })}
+ shouldShowCancelButton={false}
+ confirmText={translate('common.ok')}
/>
-
);
}
ConsolePage.displayName = 'ConsolePage';
-export default ConsolePage;
+export default withOnyx({
+ capturedLogs: {
+ key: ONYXKEYS.LOGS,
+ },
+ shouldStoreLogs: {
+ key: ONYXKEYS.SHOULD_STORE_LOGS,
+ },
+})(ConsolePage);
diff --git a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
index 58ddac79321b..3e8a9daadd3d 100644
--- a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
@@ -91,13 +91,7 @@ function BaseShareLogList({onAttachLogToReport, isViaTestToolsModal = false}: Ba
<>
{
- if (isViaTestToolsModal) {
- Navigation.goBack();
- return;
- }
- Navigation.goBack(ROUTES.SETTINGS_CONSOLE)
- }}
+ onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_CONSOLE.getRoute(isViaTestToolsModal))}
/>
{
if (!reportID || !logSource) {
return;
@@ -17,7 +17,7 @@ function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
Navigation.navigate(routeToNavigate);
};
- return ;
+ return ;
}
export default ShareLogList;
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.tsx b/src/pages/settings/AboutPage/ShareLogList/index.tsx
index e7bf191306d7..03cd7c42f73c 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.tsx
@@ -20,7 +20,12 @@ function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
() => {},
);
};
- return ;
+ return (
+
+ );
}
export default ShareLogList;
diff --git a/src/pages/settings/AboutPage/ShareLogPage.tsx b/src/pages/settings/AboutPage/ShareLogPage.tsx
index 7123746059ea..7688ade3ccd1 100644
--- a/src/pages/settings/AboutPage/ShareLogPage.tsx
+++ b/src/pages/settings/AboutPage/ShareLogPage.tsx
@@ -7,7 +7,12 @@ import ShareLogList from './ShareLogList';
type ShareLogPageProps = StackScreenProps;
function ShareLogPage({route}: ShareLogPageProps) {
- return ;
+ return (
+
+ );
}
export default ShareLogPage;
diff --git a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
index e14d4ac13bb3..b463ba02f4d3 100644
--- a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
+++ b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
@@ -55,7 +55,7 @@ function TroubleshootPage({shouldStoreLogs}: TroubleshootPageProps) {
const debugConsoleItem: BaseMenuItem = {
translationKey: 'initialSettingsPage.troubleshoot.viewConsole',
icon: Expensicons.Gear,
- action: waitForNavigate(() => Navigation.navigate(ROUTES.SETTINGS_CONSOLE)),
+ action: waitForNavigate(() => Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(false))),
};
const baseMenuItems: BaseMenuItem[] = [
diff --git a/src/styles/utils/generators/ModalStyleUtils.ts b/src/styles/utils/generators/ModalStyleUtils.ts
index 94b39a400367..335ef8382941 100644
--- a/src/styles/utils/generators/ModalStyleUtils.ts
+++ b/src/styles/utils/generators/ModalStyleUtils.ts
@@ -164,29 +164,6 @@ const createModalStyleUtils: StyleUtilGenerator = ({the
shouldAddTopSafeAreaPadding = false;
shouldAddBottomSafeAreaPadding = false;
break;
- case CONST.MODAL.MODAL_TYPE.CENTERED_SMALL_AND_UNSWIPEABLE:
- // A centered modal that takes up the minimum possible screen space on all devices and is unswipeable
- modalStyle = {
- ...modalStyle,
- ...{
- alignItems: 'center',
- },
- };
- modalContainerStyle = {
- boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)',
- borderRadius: 12,
- borderWidth: 0,
- };
-
- // Allow this modal to be dismissed with a swipe down or swipe right
- swipeDirection = undefined;
- animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn';
- animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut';
- shouldAddTopSafeAreaMargin = false;
- shouldAddBottomSafeAreaMargin = false;
- shouldAddTopSafeAreaPadding = false;
- shouldAddBottomSafeAreaPadding = false;
- break;
case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED:
modalStyle = {
...modalStyle,
From 2cc184680d314aae2fda7efba72ff179b02db35c Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Mon, 29 Apr 2024 19:27:04 +0530
Subject: [PATCH 016/207] Update
---
.../BaseClientSideLoggingToolMenu.tsx | 4 +++-
src/components/ClientSideLoggingToolMenu/types.ts | 2 ++
src/pages/settings/AboutPage/ConsolePage.tsx | 7 ++++---
src/pages/settings/AboutPage/ShareLogList/index.native.tsx | 7 +++++--
4 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index 7d27caa997f7..92d723dd36c6 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -81,7 +81,9 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
small
text={translate('initialSettingsPage.debugConsole.viewConsole')}
onPress={() => {
- closeTestToolsModal()
+ if (closeTestToolsModal) {
+ closeTestToolsModal()
+ }
Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(isViaTestToolsModal))
}}
/>
diff --git a/src/components/ClientSideLoggingToolMenu/types.ts b/src/components/ClientSideLoggingToolMenu/types.ts
index 4c29a48a9003..86ad66dfd33c 100644
--- a/src/components/ClientSideLoggingToolMenu/types.ts
+++ b/src/components/ClientSideLoggingToolMenu/types.ts
@@ -1,6 +1,8 @@
type ClientSideLoggingToolMenuProps = {
/** Boolean to know if this was opened via test tools modal */
isViaTestToolsModal: boolean;
+ /** Action to close the test tools modal */
+ closeTestToolsModal?: () => void;
};
export default ClientSideLoggingToolMenuProps;
diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx
index 2bd9ad53a544..c4443cbfbfdf 100644
--- a/src/pages/settings/AboutPage/ConsolePage.tsx
+++ b/src/pages/settings/AboutPage/ConsolePage.tsx
@@ -25,9 +25,10 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {CapturedLogs} from '@src/types/onyx';
-import {RouteProp, useRoute} from "@react-navigation/native";
-import {SettingsNavigatorParamList} from "@navigation/types";
-import SCREENS from "@src/SCREENS";
+import type {RouteProp} from "@react-navigation/native";
+import { useRoute} from "@react-navigation/native";
+import type {SettingsNavigatorParamList} from "@navigation/types";
+import type SCREENS from "@src/SCREENS";
type ConsolePageOnyxProps = {
/** Logs captured on the current device */
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.native.tsx b/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
index 9150f4655f95..d9eec220618f 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
@@ -5,7 +5,7 @@ import ROUTES from '@src/ROUTES';
import BaseShareLogList from './BaseShareLogList';
import type {ShareLogListProps} from './types';
-function ShareLogList({logSource}: ShareLogListProps) {
+function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
const onAttachLogToReport = (reportID: string, filename: string) => {
if (!reportID || !logSource) {
return;
@@ -17,7 +17,10 @@ function ShareLogList({logSource}: ShareLogListProps) {
Navigation.navigate(routeToNavigate);
};
- return ;
+ return ;
}
export default ShareLogList;
From d3bfce58c5a68893596053f64c4f0d676bbbaa59 Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Mon, 29 Apr 2024 19:53:42 +0530
Subject: [PATCH 017/207] Lint fixes
---
.../BaseClientSideLoggingToolMenu.tsx | 19 ++++++++++++++-----
.../ClientSideLoggingToolMenu/index.tsx | 12 +++++++-----
src/pages/settings/AboutPage/ConsolePage.tsx | 10 +++++-----
.../AboutPage/ShareLogList/index.native.tsx | 10 ++++++----
4 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index 92d723dd36c6..417da5cbf337 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -10,10 +10,10 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Console from '@libs/actions/Console';
import {parseStringifiedMessages} from '@libs/Console';
+import Navigation from '@navigation/Navigation';
import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
import type {CapturedLogs, Log} from '@src/types/onyx';
-import Navigation from "@navigation/Navigation";
-import ROUTES from "@src/ROUTES";
type BaseClientSideLoggingToolMenuOnyxProps = {
/** Logs captured on the current device */
@@ -38,7 +38,16 @@ type BaseClientSideLoggingToolProps = {
closeTestToolsModal?: () => void;
} & BaseClientSideLoggingToolMenuOnyxProps;
-function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onShareLogs, onDisableLogging, onEnableLogging, isViaTestToolsModal, closeTestToolsModal}: BaseClientSideLoggingToolProps) {
+function BaseClientSideLoggingToolMenu({
+ shouldStoreLogs,
+ capturedLogs,
+ file,
+ onShareLogs,
+ onDisableLogging,
+ onEnableLogging,
+ isViaTestToolsModal,
+ closeTestToolsModal,
+}: BaseClientSideLoggingToolProps) {
const {translate} = useLocalize();
const onToggle = () => {
@@ -82,9 +91,9 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS
text={translate('initialSettingsPage.debugConsole.viewConsole')}
onPress={() => {
if (closeTestToolsModal) {
- closeTestToolsModal()
+ closeTestToolsModal();
}
- Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(isViaTestToolsModal))
+ Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(isViaTestToolsModal));
}}
/>
diff --git a/src/components/ClientSideLoggingToolMenu/index.tsx b/src/components/ClientSideLoggingToolMenu/index.tsx
index 83f28c581b40..a4f820283248 100644
--- a/src/components/ClientSideLoggingToolMenu/index.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.tsx
@@ -9,11 +9,13 @@ function ClientSideLoggingToolMenu({isViaTestToolsModal, closeTestToolsModal}: C
localFileDownload('logs', JSON.stringify(logs, null, 2));
};
- return ;
+ return (
+
+ );
}
ClientSideLoggingToolMenu.displayName = 'ClientSideLoggingToolMenu';
diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx
index c4443cbfbfdf..12574568382c 100644
--- a/src/pages/settings/AboutPage/ConsolePage.tsx
+++ b/src/pages/settings/AboutPage/ConsolePage.tsx
@@ -1,3 +1,5 @@
+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 {View} from 'react-native';
@@ -21,14 +23,12 @@ import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import localFileDownload from '@libs/localFileDownload';
import Navigation from '@libs/Navigation/Navigation';
+import type {SettingsNavigatorParamList} from '@navigation/types';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
+import type SCREENS from '@src/SCREENS';
import type {CapturedLogs} from '@src/types/onyx';
-import type {RouteProp} from "@react-navigation/native";
-import { useRoute} from "@react-navigation/native";
-import type {SettingsNavigatorParamList} from "@navigation/types";
-import type SCREENS from "@src/SCREENS";
type ConsolePageOnyxProps = {
/** Logs captured on the current device */
@@ -122,7 +122,7 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) {
{
- Navigation.goBack(isViaTestToolsModal ? undefined : ROUTES.SETTINGS_TROUBLESHOOT)
+ Navigation.goBack(isViaTestToolsModal ? undefined : ROUTES.SETTINGS_TROUBLESHOOT);
}}
/>
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.native.tsx b/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
index d9eec220618f..b1fd80586b70 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
@@ -17,10 +17,12 @@ function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
Navigation.navigate(routeToNavigate);
};
- return ;
+ return (
+
+ );
}
export default ShareLogList;
From e59e1aba0139721239a59213e74af94c4355fdc4 Mon Sep 17 00:00:00 2001
From: nkdengineer
Date: Tue, 30 Apr 2024 17:37:07 +0700
Subject: [PATCH 018/207] fix lint
---
src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
index 394c4e96bbea..939c64d53c84 100644
--- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
+++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
@@ -166,7 +166,6 @@ function getAdaptedState(state: PartialState
const welcomeVideoModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.WELCOME_VIDEO_MODAL_NAVIGATOR);
const attachmentsScreen = state.routes.find((route) => route.name === SCREENS.ATTACHMENTS);
const featureTrainingModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.FEATURE_TRANING_MODAL_NAVIGATOR);
- const reportAttachmentsScreen = state.routes.find((route) => route.name === SCREENS.REPORT_ATTACHMENTS);
if (isNarrowLayout) {
metainfo.isFullScreenNavigatorMandatory = false;
From a73a5071c6bd5035fb4835a3642f77c744d77934 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 3 May 2024 13:18:27 +0530
Subject: [PATCH 019/207] add routes
---
src/ROUTES.ts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index df87daf52b57..5ddaab6a7420 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -790,6 +790,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/accounting/xero/advanced',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/advanced` as const,
},
+ POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR: {
+ route: 'settings/workspaces/:policyID/accounting/xero/advanced/purchase-bill-status-selector',
+ getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/advanced/purchase-bill-status-selector` as const,
+ },
POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_IMPORT: {
route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import` as const,
From e266c3eaa3081b66f7810003bd065ccad4f47ea7 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 3 May 2024 13:18:39 +0530
Subject: [PATCH 020/207] add screen map
---
src/SCREENS.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index 1129a86a4e92..988ba28d18fa 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -240,6 +240,7 @@ const SCREENS = {
XERO_CUSTOMER: 'Policy_Acounting_Xero_Import_Customer',
XERO_TAXES: 'Policy_Accounting_Xero_Taxes',
XERO_ADVANCED: 'Policy_Accounting_Xero_Advanced',
+ XERO_BILL_STATUS_SELECTOR: 'Policy_Accounting_Xero_Advanced_Bill_Status',
},
INITIAL: 'Workspace_Initial',
PROFILE: 'Workspace_Profile',
From 102d949c2f9cc4ed88e425deafb0257505d3bca2 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 3 May 2024 13:18:50 +0530
Subject: [PATCH 021/207] add navigation map
---
.../Navigation/AppNavigator/ModalStackNavigators/index.tsx | 2 ++
.../Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts | 1 +
src/libs/Navigation/linkingConfig/config.ts | 1 +
src/libs/Navigation/types.ts | 3 +++
4 files changed, 7 insertions(+)
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
index fad3ce072b06..5d6f85b6e705 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
@@ -300,6 +300,8 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: () => require('../../../../pages/workspace/accounting/xero/XeroTaxesConfigurationPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED]: () => require('../../../../pages/workspace/accounting/xero/advanced/XeroAdvancedPage').default as React.ComponentType,
+ [SCREENS.WORKSPACE.ACCOUNTING.XERO_BILL_STATUS_SELECTOR]: () =>
+ require('../../../../pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage').default as React.ComponentType,
[SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY]: () => require('../../../../pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage').default as React.ComponentType,
[SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET]: () =>
require('../../../../pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage').default as React.ComponentType,
diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts
index f5a45b2ece19..bca304044505 100755
--- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts
+++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts
@@ -45,6 +45,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = {
SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER,
SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES,
SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED,
+ SCREENS.WORKSPACE.ACCOUNTING.XERO_BILL_STATUS_SELECTOR,
],
[SCREENS.WORKSPACE.TAXES]: [
SCREENS.WORKSPACE.TAXES_SETTINGS,
diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts
index 1fdd575364f3..2313c1782902 100644
--- a/src/libs/Navigation/linkingConfig/config.ts
+++ b/src/libs/Navigation/linkingConfig/config.ts
@@ -332,6 +332,7 @@ const config: LinkingOptions['config'] = {
[SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: {path: ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TAXES.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED]: {path: ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.route},
+ [SCREENS.WORKSPACE.ACCOUNTING.XERO_BILL_STATUS_SELECTOR]: {path: ROUTES.POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR.route},
[SCREENS.WORKSPACE.DESCRIPTION]: {
path: ROUTES.WORKSPACE_PROFILE_DESCRIPTION.route,
},
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index 40427bf8cbbd..3d9f86ea384f 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -327,6 +327,9 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED]: {
policyID: string;
};
+ [SCREENS.WORKSPACE.ACCOUNTING.XERO_BILL_STATUS_SELECTOR]: {
+ policyID: string;
+ };
[SCREENS.GET_ASSISTANCE]: {
backTo: Routes;
};
From 37df48a3bde44b89629157a9a244a58836ec6a0d Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 3 May 2024 13:19:13 +0530
Subject: [PATCH 022/207] link to bill status page and add default page
---
.../xero/advanced/XeroAdvancedPage.tsx | 4 +-
.../XeroPurchaseBillStatusSelectorPage.tsx | 83 +++++++++++++++++++
2 files changed, 86 insertions(+), 1 deletion(-)
create mode 100644 src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
index f781769adabf..4038678f214b 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
@@ -6,11 +6,13 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections';
import * as ErrorUtils from '@libs/ErrorUtils';
+import Navigation from '@libs/Navigation/Navigation';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow';
import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
+import ROUTES from '@src/ROUTES';
function XeroAdvancedPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
@@ -52,7 +54,7 @@ function XeroAdvancedPage({policy}: WithPolicyConnectionsProps) {
description={translate('workspace.xero.advancedConfig.purchaseBillStatusTitle')}
key={translate('workspace.xero.advancedConfig.purchaseBillStatusTitle')}
wrapperStyle={[styles.sectionMenuItemTopDescription]}
- onPress={() => {}}
+ onPress={() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR.getRoute(policyID))}
/>
[...(bankAccounts ?? []), ...(creditCards ?? [])], [bankAccounts, creditCards]);
+
+ const qboOnlineSelectorOptions = useMemo(
+ () =>
+ accountOptions?.map(({id, name}) => ({
+ value: id,
+ text: name,
+ keyForList: id,
+ isSelected: reimbursementAccountID === id,
+ })),
+ [reimbursementAccountID, accountOptions],
+ );
+ const listHeaderComponent = useMemo(
+ () => (
+
+ {translate('workspace.qbo.advancedConfig.invoiceAccountSelectDescription')}
+
+ ),
+ [translate, styles.pb2, styles.ph5, styles.pb5, styles.textNormal],
+ );
+
+ const initiallyFocusedOptionKey = useMemo(() => qboOnlineSelectorOptions?.find((mode) => mode.isSelected)?.keyForList, [qboOnlineSelectorOptions]);
+
+ const saveSelection = useCallback(
+ ({value}: SelectorType) => {
+ Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.QBO, CONST.QUICK_BOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID, value);
+ Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID));
+ },
+ [policyID],
+ );
+
+ return (
+
+
+
+ );
+}
+
+XeroPurchaseBillStatusSelectorPage.displayName = 'XeroPurchaseBillStatusSelectorPage';
+
+export default withPolicyConnections(XeroPurchaseBillStatusSelectorPage);
From 7562b7ffe70e6ae55f63432b80cb10e4a6ac5478 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 3 May 2024 13:28:10 +0530
Subject: [PATCH 023/207] add selection screen
---
src/components/SelectionScreen.tsx | 81 ++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
create mode 100644 src/components/SelectionScreen.tsx
diff --git a/src/components/SelectionScreen.tsx b/src/components/SelectionScreen.tsx
new file mode 100644
index 000000000000..df650dffd40e
--- /dev/null
+++ b/src/components/SelectionScreen.tsx
@@ -0,0 +1,81 @@
+import React from 'react';
+import useLocalize from '@hooks/useLocalize';
+import type {PolicyAccessVariant} from '@pages/workspace/AccessOrNotFoundWrapper';
+import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
+import type {TranslationPaths} from '@src/languages/types';
+import type {PolicyFeatureName} from '@src/types/onyx/Policy';
+import HeaderWithBackButton from './HeaderWithBackButton';
+import ScreenWrapper from './ScreenWrapper';
+import SelectionList from './SelectionList';
+import type RadioListItem from './SelectionList/RadioListItem';
+import type TableListItem from './SelectionList/TableListItem';
+import type {ListItem, SectionListDataType} from './SelectionList/types';
+import type UserListItem from './SelectionList/UserListItem';
+
+type SelectorType = ListItem & {
+ value: string;
+};
+
+type SelectionScreenProps = {
+ displayName: string;
+ title: TranslationPaths;
+ headerContent?: React.ReactNode;
+ sections: Array>;
+ listItem: typeof RadioListItem | typeof UserListItem | typeof TableListItem;
+ initiallyFocusedOptionKey?: string | null | undefined;
+ onSelectRow: (selection: SelectorType) => void;
+ onBackButtonPress: () => void;
+ /** The current policyID */
+ policyID: string;
+ /** Defines which types of access should be verified */
+ accessVariants?: PolicyAccessVariant[];
+ /** The current feature name that the user tries to get access to */
+ featureName?: PolicyFeatureName;
+};
+
+function SelectionScreen({
+ displayName,
+ title,
+ headerContent,
+ sections,
+ listItem,
+ initiallyFocusedOptionKey,
+ onSelectRow,
+ onBackButtonPress,
+ policyID,
+ accessVariants,
+ featureName,
+}: SelectionScreenProps) {
+ const {translate} = useLocalize();
+ return (
+
+
+
+
+
+
+ );
+}
+
+export type {SelectorType};
+
+SelectionScreen.displayName = 'SelectionScreen';
+export default SelectionScreen;
From 189c4f4df13f15db503fb45f8bf2b54c489dd8d0 Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Fri, 3 May 2024 14:19:58 +0530
Subject: [PATCH 024/207] Add sync functionality in Xero connection
---
.../actions/connections/QuickBooksOnline.ts | 39 +++----------------
src/libs/actions/connections/index.ts | 35 ++++++++++++++++-
.../accounting/PolicyAccountingPage.tsx | 4 +-
3 files changed, 41 insertions(+), 37 deletions(-)
diff --git a/src/libs/actions/connections/QuickBooksOnline.ts b/src/libs/actions/connections/QuickBooksOnline.ts
index f507758e8d38..3bf4bb4b6a36 100644
--- a/src/libs/actions/connections/QuickBooksOnline.ts
+++ b/src/libs/actions/connections/QuickBooksOnline.ts
@@ -1,41 +1,14 @@
-import type {OnyxUpdate} from 'react-native-onyx';
-import Onyx from 'react-native-onyx';
-import * as API from '@libs/API';
-import type {ConnectPolicyToAccountingIntegrationParams, SyncPolicyToQuickbooksOnlineParams} from '@libs/API/parameters';
+import type {ConnectPolicyToAccountingIntegrationParams} from '@libs/API/parameters';
import {READ_COMMANDS} from '@libs/API/types';
import {getCommandURL} from '@libs/ApiUtils';
-import CONST from '@src/CONST';
-import ONYXKEYS from '@src/ONYXKEYS';
function getQuickBooksOnlineSetupLink(policyID: string) {
const params: ConnectPolicyToAccountingIntegrationParams = {policyID};
- const commandURL = getCommandURL({command: READ_COMMANDS.CONNECT_POLICY_TO_QUICKBOOKS_ONLINE, shouldSkipWebProxy: true});
+ const commandURL = getCommandURL({
+ command: READ_COMMANDS.CONNECT_POLICY_TO_QUICKBOOKS_ONLINE,
+ shouldSkipWebProxy: true,
+ });
return commandURL + new URLSearchParams(params).toString();
}
-function syncConnection(policyID: string) {
- const optimisticData: OnyxUpdate[] = [
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`,
- value: {
- stageInProgress: CONST.POLICY.CONNECTIONS.SYNC_STAGE_NAME.STARTING_IMPORT,
- connectionName: CONST.POLICY.CONNECTIONS.NAME.QBO,
- },
- },
- ];
- const failureData: OnyxUpdate[] = [
- {
- onyxMethod: Onyx.METHOD.SET,
- key: `${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`,
- value: null,
- },
- ];
- const parameters: SyncPolicyToQuickbooksOnlineParams = {
- policyID,
- idempotencyKey: policyID,
- };
- API.read(READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_ONLINE, parameters, {optimisticData, failureData});
-}
-
-export {getQuickBooksOnlineSetupLink, syncConnection};
+export {getQuickBooksOnlineSetupLink};
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 5ce806c7d4be..ca09f1069b72 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -2,7 +2,8 @@ import Onyx from 'react-native-onyx';
import type {OnyxUpdate} from 'react-native-onyx';
import * as API from '@libs/API';
import type {RemovePolicyConnectionParams, UpdatePolicyConnectionConfigParams} from '@libs/API/parameters';
-import {WRITE_COMMANDS} from '@libs/API/types';
+import {SyncPolicyToQuickbooksOnlineParams} from '@libs/API/parameters';
+import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
@@ -124,4 +125,34 @@ function updatePolicyConnectionConfig syncConnection(policyID),
+ onSelected: () => syncConnection(policyID, connectedIntegration),
disabled: isOffline,
},
{
From fe9b69b9c49c24c052ccd2309ef539dd97e38327 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 3 May 2024 15:29:58 +0530
Subject: [PATCH 025/207] add selection screen
---
.../XeroPurchaseBillStatusSelectorPage.tsx | 52 ++++++++++---------
1 file changed, 27 insertions(+), 25 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx
index b369a8008e52..bffe9eecb73b 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx
@@ -6,6 +6,7 @@ import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
+import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -26,55 +27,56 @@ function XeroPurchaseBillStatusSelectorPage({policy}: WithPolicyConnectionsProps
const {translate} = useLocalize();
const policyID = policy?.id ?? '';
- const {bankAccounts, creditCards} = policy?.connections?.quickbooksOnline?.data ?? {};
- const {reimbursementAccountID} = policy?.connections?.quickbooksOnline?.config ?? {};
- const accountOptions = useMemo(() => [...(bankAccounts ?? []), ...(creditCards ?? [])], [bankAccounts, creditCards]);
+ const {bankAccounts} = policy?.connections?.xero?.data ?? {};
- const qboOnlineSelectorOptions = useMemo(
+ const {invoiceCollectionsAccountID} = policy?.connections?.xero?.config.sync ?? {};
+
+ const xeroSelectorOptions = useMemo(
() =>
- accountOptions?.map(({id, name}) => ({
+ (bankAccounts ?? []).map(({id, name}) => ({
value: id,
text: name,
keyForList: id,
- isSelected: reimbursementAccountID === id,
+ isSelected: invoiceCollectionsAccountID === id,
})),
- [reimbursementAccountID, accountOptions],
+ [invoiceCollectionsAccountID, bankAccounts],
);
+
const listHeaderComponent = useMemo(
() => (
- {translate('workspace.qbo.advancedConfig.invoiceAccountSelectDescription')}
+ {translate('workspace.xero.advancedConfig.invoiceAccountSelectDescription')}
),
[translate, styles.pb2, styles.ph5, styles.pb5, styles.textNormal],
);
- const initiallyFocusedOptionKey = useMemo(() => qboOnlineSelectorOptions?.find((mode) => mode.isSelected)?.keyForList, [qboOnlineSelectorOptions]);
+ const initiallyFocusedOptionKey = useMemo(() => xeroSelectorOptions?.find((mode) => mode.isSelected)?.keyForList, [xeroSelectorOptions]);
- const saveSelection = useCallback(
+ const updateMode = useCallback(
({value}: SelectorType) => {
- Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.QBO, CONST.QUICK_BOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID, value);
- Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID));
+ Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.SYNC, {
+ invoiceCollectionsAccountID: value,
+ });
+ Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.getRoute(policyID));
},
[policyID],
);
return (
-
-
-
+ displayName={XeroPurchaseBillStatusSelectorPage.displayName}
+ sections={[{data: xeroSelectorOptions}]}
+ listItem={RadioListItem}
+ onSelectRow={updateMode}
+ initiallyFocusedOptionKey={initiallyFocusedOptionKey}
+ headerContent={listHeaderComponent}
+ onBackButtonPress={() => Navigation.goBack()}
+ title="workspace.xero.advancedConfig.xeroInvoiceCollectionAccount"
+ />
);
}
From a362c38c92af0a5af95be66f5c22ab0df149037c Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Fri, 3 May 2024 17:36:18 +0530
Subject: [PATCH 026/207] Update
---
.../ConnectToQuickbooksOnlineButton/index.native.tsx | 2 +-
src/components/ConnectToQuickbooksOnlineButton/index.tsx | 2 +-
src/libs/actions/connections/QuickBooksOnline.ts | 2 +-
src/libs/actions/connections/index.ts | 7 +++----
4 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/src/components/ConnectToQuickbooksOnlineButton/index.native.tsx b/src/components/ConnectToQuickbooksOnlineButton/index.native.tsx
index 3a5e545cce88..50f71ea5a1ae 100644
--- a/src/components/ConnectToQuickbooksOnlineButton/index.native.tsx
+++ b/src/components/ConnectToQuickbooksOnlineButton/index.native.tsx
@@ -10,7 +10,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import useLocalize from '@hooks/useLocalize';
import {removePolicyConnection} from '@libs/actions/connections';
-import {getQuickBooksOnlineSetupLink} from '@libs/actions/connections/QuickBooksOnline';
+import getQuickBooksOnlineSetupLink from '@libs/actions/connections/QuickBooksOnline';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Session} from '@src/types/onyx';
diff --git a/src/components/ConnectToQuickbooksOnlineButton/index.tsx b/src/components/ConnectToQuickbooksOnlineButton/index.tsx
index 7de2ba55fb84..b17ff374d3a6 100644
--- a/src/components/ConnectToQuickbooksOnlineButton/index.tsx
+++ b/src/components/ConnectToQuickbooksOnlineButton/index.tsx
@@ -5,7 +5,7 @@ import useEnvironment from '@hooks/useEnvironment';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import {removePolicyConnection} from '@libs/actions/connections';
-import {getQuickBooksOnlineSetupLink} from '@libs/actions/connections/QuickBooksOnline';
+import getQuickBooksOnlineSetupLink from '@libs/actions/connections/QuickBooksOnline';
import * as Link from '@userActions/Link';
import CONST from '@src/CONST';
import type {ConnectToQuickbooksOnlineButtonProps} from './types';
diff --git a/src/libs/actions/connections/QuickBooksOnline.ts b/src/libs/actions/connections/QuickBooksOnline.ts
index 3bf4bb4b6a36..2642ad4056a9 100644
--- a/src/libs/actions/connections/QuickBooksOnline.ts
+++ b/src/libs/actions/connections/QuickBooksOnline.ts
@@ -11,4 +11,4 @@ function getQuickBooksOnlineSetupLink(policyID: string) {
return commandURL + new URLSearchParams(params).toString();
}
-export {getQuickBooksOnlineSetupLink};
+export default getQuickBooksOnlineSetupLink;
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index ca09f1069b72..2296ae28df60 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -1,8 +1,7 @@
import Onyx from 'react-native-onyx';
import type {OnyxUpdate} from 'react-native-onyx';
import * as API from '@libs/API';
-import type {RemovePolicyConnectionParams, UpdatePolicyConnectionConfigParams} from '@libs/API/parameters';
-import {SyncPolicyToQuickbooksOnlineParams} from '@libs/API/parameters';
+import type {RemovePolicyConnectionParams, UpdatePolicyConnectionConfigParams, SyncPolicyToQuickbooksOnlineParams} from '@libs/API/parameters';
import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
@@ -125,14 +124,14 @@ function updatePolicyConnectionConfig
Date: Fri, 3 May 2024 17:54:54 +0530
Subject: [PATCH 027/207] Update PolicyAccountingPage.tsx
---
src/pages/workspace/accounting/PolicyAccountingPage.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index 50deefdf94b8..51d9bb493728 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -23,8 +23,7 @@ import usePermissions from '@hooks/usePermissions';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
-import {removePolicyConnection} from '@libs/actions/connections';
-import {syncConnection} from '@libs/actions/connections';
+import {removePolicyConnection, syncConnection} from '@libs/actions/connections';
import {findCurrentXeroOrganization, getXeroTenants} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
From ff31b5350e3b2f06368fe96e26189a1432dac295 Mon Sep 17 00:00:00 2001
From: Shridhar Goel <35566748+ShridharGoel@users.noreply.github.com>
Date: Fri, 3 May 2024 17:55:24 +0530
Subject: [PATCH 028/207] Update PolicyAccountingPage.tsx
---
src/pages/workspace/accounting/PolicyAccountingPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index 51d9bb493728..9541021c79cb 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -136,7 +136,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
onSelected: () => setIsDisconnectModalOpen(true),
},
],
- [translate, policyID, isOffline],
+ [translate, policyID, isOffline, connectedIntegration],
);
const connectionsMenuItems: MenuItemProps[] = useMemo(() => {
From 0f1a50d39f86b9cf948f47c1cad1950734491e0c Mon Sep 17 00:00:00 2001
From: tienifr
Date: Tue, 7 May 2024 18:31:57 +0700
Subject: [PATCH 029/207] access control on iou request
---
src/CONST.ts | 3 +
src/components/ConnectionLayout.tsx | 4 +-
src/components/SelectionScreen.tsx | 4 +-
src/pages/iou/request/IOURequestStartPage.tsx | 41 ++++++--------
.../workspace/AccessOrNotFoundWrapper.tsx | 55 ++++++++++++++-----
5 files changed, 66 insertions(+), 41 deletions(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index 19720c05a93c..1ffeaa754717 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -1567,6 +1567,9 @@ const CONST = {
ACCOUNTANT: 'accountant',
},
},
+ ACCESS_VARIANTS: {
+ CREATE: 'create',
+ },
},
GROWL: {
diff --git a/src/components/ConnectionLayout.tsx b/src/components/ConnectionLayout.tsx
index a91dea9bfc92..e6e37a3f1273 100644
--- a/src/components/ConnectionLayout.tsx
+++ b/src/components/ConnectionLayout.tsx
@@ -4,7 +4,7 @@ import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
-import type {PolicyAccessVariant} from '@pages/workspace/AccessOrNotFoundWrapper';
+import type {AccessVariant} from '@pages/workspace/AccessOrNotFoundWrapper';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import type {TranslationPaths} from '@src/languages/types';
import type {PolicyFeatureName} from '@src/types/onyx/Policy';
@@ -33,7 +33,7 @@ type ConnectionLayoutProps = {
policyID: string;
/** Defines which types of access should be verified */
- accessVariants?: PolicyAccessVariant[];
+ accessVariants?: AccessVariant[];
/** The current feature name that the user tries to get access to */
featureName?: PolicyFeatureName;
diff --git a/src/components/SelectionScreen.tsx b/src/components/SelectionScreen.tsx
index a2ab477accef..0ff267160e07 100644
--- a/src/components/SelectionScreen.tsx
+++ b/src/components/SelectionScreen.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import useLocalize from '@hooks/useLocalize';
-import type {PolicyAccessVariant} from '@pages/workspace/AccessOrNotFoundWrapper';
+import type {AccessVariant} from '@pages/workspace/AccessOrNotFoundWrapper';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import type {TranslationPaths} from '@src/languages/types';
import type {PolicyFeatureName} from '@src/types/onyx/Policy';
@@ -45,7 +45,7 @@ type SelectionScreenProps = {
policyID: string;
/** Defines which types of access should be verified */
- accessVariants?: PolicyAccessVariant[];
+ accessVariants?: AccessVariant[];
/** The current feature name that the user tries to get access to */
featureName?: PolicyFeatureName;
diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx
index 1bbf0d02a941..3e057c4d8300 100644
--- a/src/pages/iou/request/IOURequestStartPage.tsx
+++ b/src/pages/iou/request/IOURequestStartPage.tsx
@@ -3,7 +3,6 @@ import React, {useCallback, useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
-import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import DragAndDropProvider from '@components/DragAndDrop/Provider';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
@@ -13,13 +12,12 @@ import useLocalize from '@hooks/useLocalize';
import usePermissions from '@hooks/usePermissions';
import useThemeStyles from '@hooks/useThemeStyles';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
-import * as IOUUtils from '@libs/IOUUtils';
import * as KeyDownPressListener from '@libs/KeyboardShortcut/KeyDownPressListener';
import Navigation from '@libs/Navigation/Navigation';
import OnyxTabNavigator, {TopTab} from '@libs/Navigation/OnyxTabNavigator';
-import * as PolicyUtils from '@libs/PolicyUtils';
import * as ReportUtils from '@libs/ReportUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
+import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import * as IOU from '@userActions/IOU';
import type {IOURequestType} from '@userActions/IOU';
import CONST from '@src/CONST';
@@ -44,9 +42,6 @@ type IOURequestStartPageOnyxProps = {
/** The transaction being modified */
transaction: OnyxEntry;
-
- /** The list of all policies */
- allPolicies: OnyxCollection;
};
type IOURequestStartPageProps = IOURequestStartPageOnyxProps & WithWritableReportOrNotFoundProps;
@@ -60,7 +55,6 @@ function IOURequestStartPage({
},
selectedTab,
transaction,
- allPolicies,
}: IOURequestStartPageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
@@ -105,9 +99,6 @@ function IOURequestStartPage({
const isExpenseReport = ReportUtils.isExpenseReport(report);
const shouldDisplayDistanceRequest = (!!canUseP2PDistanceRequests || isExpenseChat || isExpenseReport || isFromGlobalCreate) && iouType !== CONST.IOU.TYPE.SPLIT;
- // Allow the user to submit the expense if we are submitting the expense in global menu or the report can create the exoense
- const isAllowedToCreateRequest = isEmptyObject(report?.reportID) || ReportUtils.canCreateRequest(report, policy, iouType) || PolicyUtils.canSendInvoice(allPolicies);
-
const navigateBack = () => {
Navigation.closeRHPFlow();
};
@@ -126,15 +117,20 @@ function IOURequestStartPage({
}
return (
-
- {({safeAreaPaddingBottomStyle}) => (
-
+
+ {({safeAreaPaddingBottomStyle}) => (
-
- )}
-
+ )}
+
+
);
}
@@ -180,7 +176,4 @@ export default withOnyx(
transaction: {
key: ({route}) => `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${route?.params.transactionID ?? 0}`,
},
- allPolicies: {
- key: ONYXKEYS.COLLECTION.POLICY,
- },
})(IOURequestStartPage);
diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
index b90a9cb38151..85d63c7f423a 100644
--- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx
+++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
@@ -1,14 +1,17 @@
/* eslint-disable rulesdir/no-negated-variables */
import React, {useEffect} from 'react';
-import type {OnyxEntry} from 'react-native-onyx';
+import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import type {FullPageNotFoundViewProps} from '@components/BlockingViews/FullPageNotFoundView';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
+import * as IOUUtils from '@libs/IOUUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
+import * as ReportUtils from '@libs/ReportUtils';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
import * as Policy from '@userActions/Policy';
+import type {IOUType} from '@src/CONST';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
@@ -17,29 +20,42 @@ import type {PolicyFeatureName} from '@src/types/onyx/Policy';
import callOrReturn from '@src/types/utils/callOrReturn';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
-const POLICY_ACCESS_VARIANTS = {
+const ACCESS_VARIANTS = {
[CONST.POLICY.ACCESS_VARIANTS.PAID]: (policy: OnyxEntry) => PolicyUtils.isPaidGroupPolicy(policy) && !!policy?.isPolicyExpenseChatEnabled,
[CONST.POLICY.ACCESS_VARIANTS.ADMIN]: (policy: OnyxEntry) => PolicyUtils.isPolicyAdmin(policy),
-} as const satisfies Record boolean>;
+ [CONST.IOU.ACCESS_VARIANTS.CREATE]: (policy: OnyxEntry, report: OnyxEntry, allPolicies: OnyxCollection, iouType?: IOUType) =>
+ // Allow the user to submit the expense if we are submitting the expense in global menu or the report can create the expense
+ (isEmptyObject(report?.reportID) || ReportUtils.canCreateRequest(report, policy, iouType)) &&
+ (iouType !== CONST.IOU.TYPE.INVOICE || PolicyUtils.canSendInvoice(allPolicies)),
+} as const satisfies Record, iouType?: IOUType) => boolean>;
-type PolicyAccessVariant = keyof typeof POLICY_ACCESS_VARIANTS;
+type AccessVariant = keyof typeof ACCESS_VARIANTS;
type AccessOrNotFoundWrapperOnyxProps = {
+ /** The report that holds the transaction */
+ report: OnyxEntry;
+
/** The report currently being looked at */
policy: OnyxEntry;
/** Indicated whether the report data is loading */
isLoadingReportData: OnyxEntry;
+
+ /** The list of all policies */
+ allPolicies: OnyxCollection;
};
type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & {
/** The children to render */
children: ((props: AccessOrNotFoundWrapperOnyxProps) => React.ReactNode) | React.ReactNode;
+ /** The id of the report that holds the transaction */
+ reportID?: string;
+
/** The report currently being looked at */
- policyID: string;
+ policyID?: string;
/** Defines which types of access should be verified */
- accessVariants?: PolicyAccessVariant[];
+ accessVariants?: AccessVariant[];
/** The current feature name that the user tries to get access to */
featureName?: PolicyFeatureName;
@@ -49,6 +65,9 @@ type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & {
/** Whether or not to block user from accessing the page */
shouldBeBlocked?: boolean;
+
+ /** The type of the transaction */
+ iouType?: IOUType;
} & Pick;
type PageNotFoundFallbackProps = Pick & {shouldShowFullScreenFallback: boolean};
@@ -64,7 +83,7 @@ function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageN
/>
) : (
Navigation.goBack(ROUTES.WORKSPACE_PROFILE.getRoute(policyID))}
+ onBackButtonPress={() => !!policyID && Navigation.goBack(ROUTES.WORKSPACE_PROFILE.getRoute(policyID))}
// eslint-disable-next-line react/jsx-props-no-spreading
{...fullPageNotFoundViewProps}
/>
@@ -72,7 +91,7 @@ function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageN
}
function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps, shouldBeBlocked, ...props}: AccessOrNotFoundWrapperProps) {
- const {policy, policyID, featureName, isLoadingReportData} = props;
+ const {policy, policyID, report, iouType, allPolicies, featureName, isLoadingReportData} = props;
const isPolicyIDInRoute = !!policyID?.length;
@@ -91,12 +110,16 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps
const isFeatureEnabled = featureName ? PolicyUtils.isPolicyFeatureEnabled(policy, featureName) : true;
const isPageAccessible = accessVariants.reduce((acc, variant) => {
- const accessFunction = POLICY_ACCESS_VARIANTS[variant];
- return acc && accessFunction(policy);
+ const accessFunction = ACCESS_VARIANTS[variant];
+ return acc && accessFunction(policy, report, allPolicies, iouType);
}, true);
+ const isIOU = !!iouType && IOUUtils.isValidMoneyRequestType(iouType);
+ const isFromGlobalCreate = isEmptyObject(report?.reportID);
+
+ const isPolicyNotAccessible = isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id;
const shouldShowNotFoundPage =
- isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id || !isPageAccessible || !isFeatureEnabled || shouldBeBlocked;
+ isPolicyNotAccessible || !isPageAccessible || !isFeatureEnabled || shouldBeBlocked;
if (shouldShowFullScreenLoadingIndicator) {
return ;
@@ -115,13 +138,19 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps
return callOrReturn(props.children, props);
}
-export type {PolicyAccessVariant};
+export type {AccessVariant};
export default withOnyx({
+ report: {
+ key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+ },
policy: {
- key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID ?? ''}`,
+ key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
},
isLoadingReportData: {
key: ONYXKEYS.IS_LOADING_REPORT_DATA,
},
+ allPolicies: {
+ key: ONYXKEYS.COLLECTION.POLICY,
+ },
})(AccessOrNotFoundWrapper);
From a9176d659b9ffcf6dfa469ce2014e6c324c98c3c Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Tue, 7 May 2024 19:12:34 +0530
Subject: [PATCH 030/207] Update
---
src/ROUTES.ts | 4 ++--
.../BaseClientSideLoggingToolMenu.tsx | 12 ++++--------
.../ClientSideLoggingToolMenu/index.android.tsx | 3 +--
.../ClientSideLoggingToolMenu/index.ios.tsx | 3 +--
src/components/ClientSideLoggingToolMenu/index.tsx | 3 +--
src/components/TestToolsModal.tsx | 1 -
src/libs/Navigation/types.ts | 4 ++--
src/pages/settings/AboutPage/ConsolePage.tsx | 5 ++---
.../AboutPage/ShareLogList/BaseShareLogList.tsx | 10 ++++++++--
.../settings/AboutPage/ShareLogList/index.native.tsx | 7 ++-----
src/pages/settings/AboutPage/ShareLogList/index.tsx | 7 ++-----
src/pages/settings/AboutPage/ShareLogList/types.ts | 4 ----
src/pages/settings/AboutPage/ShareLogPage.tsx | 7 +------
src/pages/settings/Troubleshoot/TroubleshootPage.tsx | 2 +-
14 files changed, 27 insertions(+), 45 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 6a51f1fbae20..12dd16edb9ca 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -181,11 +181,11 @@ const ROUTES = {
SETTINGS_TROUBLESHOOT: 'settings/troubleshoot',
SETTINGS_CONSOLE: {
route: 'settings/troubleshoot/console',
- getRoute: (isViaTestToolsModal = false) => `settings/troubleshoot/console?isViaTestToolsModal=${isViaTestToolsModal}` as const,
+ getRoute: (backTo?: string) => getUrlWithBackToParam(`settings/troubleshoot/console`, backTo) as const,
},
SETTINGS_SHARE_LOG: {
route: 'settings/troubleshoot/console/share-log',
- getRoute: (source: string, isViaTestToolsModal = false) => `settings/troubleshoot/console/share-log?source=${encodeURI(source)}&isViaTestToolsModal=${isViaTestToolsModal}` as const,
+ getRoute: (source: string, backTo?: string) => getUrlWithBackToParam(`settings/troubleshoot/console/share-log?source=${encodeURI(source)}`, backTo) as const,
},
SETTINGS_EXIT_SURVEY_REASON: 'settings/exit-survey/reason',
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index 24ceb3e760d0..99afa5185e7f 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -14,6 +14,7 @@ import Navigation from '@navigation/Navigation';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {CapturedLogs, Log} from '@src/types/onyx';
+import toggleTestToolsModal from "@userActions/TestTool";
type BaseClientSideLoggingToolMenuOnyxProps = {
/** Logs captured on the current device */
@@ -36,8 +37,6 @@ type BaseClientSideLoggingToolProps = {
displayPath?: string;
/** Boolean to know if this was opened via test tools modal */
isViaTestToolsModal: boolean;
- /** Action to close the test tools modal */
- closeTestToolsModal?: () => void;
} & BaseClientSideLoggingToolMenuOnyxProps;
function BaseClientSideLoggingToolMenu({
@@ -48,8 +47,7 @@ function BaseClientSideLoggingToolMenu({
onDisableLogging,
onEnableLogging,
displayPath,
- isViaTestToolsModal,
- closeTestToolsModal,
+ isViaTestToolsModal
}: BaseClientSideLoggingToolProps) {
const {translate} = useLocalize();
@@ -93,10 +91,8 @@ function BaseClientSideLoggingToolMenu({
small
text={translate('initialSettingsPage.debugConsole.viewConsole')}
onPress={() => {
- if (closeTestToolsModal) {
- closeTestToolsModal();
- }
- Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(isViaTestToolsModal));
+ toggleTestToolsModal()
+ Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute());
}}
/>
diff --git a/src/components/ClientSideLoggingToolMenu/index.android.tsx b/src/components/ClientSideLoggingToolMenu/index.android.tsx
index 02ec8b9231ed..d9335a5c5921 100644
--- a/src/components/ClientSideLoggingToolMenu/index.android.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.android.tsx
@@ -7,7 +7,7 @@ import CONST from '@src/CONST';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
import type ClientSideLoggingToolMenuProps from './types';
-function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
+function ClientSideLoggingToolMenu({isViaTestToolsModal = false}: ClientSideLoggingToolMenuProps) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
const createAndSaveFile = (logs: Log[]) => {
@@ -42,7 +42,6 @@ function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsM
onShareLogs={shareLogs}
displayPath={`${CONST.DOWNLOADS_PATH}/${file?.newFileName ?? ''}`}
isViaTestToolsModal={isViaTestToolsModal}
- closeTestToolsModal={closeTestToolsModal}
/>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/index.ios.tsx b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
index 12f04c81c419..bfdc6fbcde9b 100644
--- a/src/components/ClientSideLoggingToolMenu/index.ios.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
@@ -8,7 +8,7 @@ import CONST from '@src/CONST';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
import type ClientSideLoggingToolMenuProps from './types';
-function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
+function ClientSideLoggingToolMenu({isViaTestToolsModal = false}: ClientSideLoggingToolMenuProps) {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
const {environment} = useEnvironment();
@@ -35,7 +35,6 @@ function ClientSideLoggingToolMenu({isViaTestToolsModal = false, closeTestToolsM
onShareLogs={shareLogs}
displayPath={`${CONST.NEW_EXPENSIFY_PATH}${getDownloadFolderPathSuffixForIOS(environment)}/${file?.newFileName ?? ''}`}
isViaTestToolsModal={isViaTestToolsModal}
- closeTestToolsModal={closeTestToolsModal}
/>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/index.tsx b/src/components/ClientSideLoggingToolMenu/index.tsx
index a4f820283248..50dfb629b565 100644
--- a/src/components/ClientSideLoggingToolMenu/index.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.tsx
@@ -4,7 +4,7 @@ import localFileDownload from '@libs/localFileDownload';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
import type ClientSideLoggingToolMenuProps from './types';
-function ClientSideLoggingToolMenu({isViaTestToolsModal, closeTestToolsModal}: ClientSideLoggingToolMenuProps) {
+function ClientSideLoggingToolMenu({isViaTestToolsModal}: ClientSideLoggingToolMenuProps) {
const downloadFile = (logs: Log[]) => {
localFileDownload('logs', JSON.stringify(logs, null, 2));
};
@@ -13,7 +13,6 @@ function ClientSideLoggingToolMenu({isViaTestToolsModal, closeTestToolsModal}: C
);
}
diff --git a/src/components/TestToolsModal.tsx b/src/components/TestToolsModal.tsx
index f9107a5a269a..e60600909b26 100644
--- a/src/components/TestToolsModal.tsx
+++ b/src/components/TestToolsModal.tsx
@@ -47,7 +47,6 @@ function TestToolsModal({isTestToolsModalOpen = false}: TestToolsModalProps) {
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index 2e006e7d7643..150cef975760 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -112,12 +112,12 @@ type SettingsNavigatorParamList = {
[SCREENS.SETTINGS.APP_DOWNLOAD_LINKS]: undefined;
[SCREENS.SETTINGS.TROUBLESHOOT]: undefined;
[SCREENS.SETTINGS.CONSOLE]: {
- isViaTestToolsModal: boolean;
+ backTo: Routes;
};
[SCREENS.SETTINGS.SHARE_LOG]: {
/** URL of the generated file to share logs in a report */
source: string;
- isViaTestToolsModal: boolean;
+ backTo: Routes;
};
[SCREENS.SETTINGS.WALLET.ROOT]: undefined;
[SCREENS.SETTINGS.WALLET.CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS]: undefined;
diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx
index 12574568382c..b3dab1999e64 100644
--- a/src/pages/settings/AboutPage/ConsolePage.tsx
+++ b/src/pages/settings/AboutPage/ConsolePage.tsx
@@ -49,7 +49,6 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) {
const styles = useThemeStyles();
const route = useRoute>();
- const isViaTestToolsModal = route.params?.isViaTestToolsModal ?? false;
const logsList = useMemo(
() =>
@@ -98,7 +97,7 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) {
return;
}
- Navigation.navigate(ROUTES.SETTINGS_SHARE_LOG.getRoute(path, isViaTestToolsModal));
+ Navigation.navigate(ROUTES.SETTINGS_SHARE_LOG.getRoute(path, ROUTES.SETTINGS_CONSOLE.getRoute(route.params?.backTo)));
});
};
@@ -122,7 +121,7 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) {
{
- Navigation.goBack(isViaTestToolsModal ? undefined : ROUTES.SETTINGS_TROUBLESHOOT);
+ Navigation.goBack(route.params?.backTo);
}}
/>
diff --git a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
index 0c656a47ad1f..37c1b4a2ba22 100644
--- a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
@@ -18,8 +18,12 @@ import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Report} from '@src/types/onyx';
import type {BaseShareLogListProps} from './types';
+import {StackScreenProps} from "@react-navigation/stack";
+import {SettingsNavigatorParamList} from "@navigation/types";
+import SCREENS from "@src/SCREENS";
+import {RouteProp, useRoute} from "@react-navigation/native";
-function BaseShareLogList({onAttachLogToReport, isViaTestToolsModal = false}: BaseShareLogListProps) {
+function BaseShareLogList({onAttachLogToReport}: BaseShareLogListProps) {
const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState('');
const {isOffline} = useNetwork();
const {translate} = useLocalize();
@@ -27,6 +31,8 @@ function BaseShareLogList({onAttachLogToReport, isViaTestToolsModal = false}: Ba
const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false});
const {options, areOptionsInitialized} = useOptionsList();
+ const route = useRoute>();
+
const searchOptions = useMemo(() => {
if (!areOptionsInitialized) {
return {
@@ -99,7 +105,7 @@ function BaseShareLogList({onAttachLogToReport, isViaTestToolsModal = false}: Ba
<>
Navigation.goBack(ROUTES.SETTINGS_CONSOLE.getRoute(isViaTestToolsModal))}
+ onBackButtonPress={() => Navigation.goBack(route.params?.backTo)}
/>
{
if (!reportID || !logSource) {
return;
@@ -18,10 +18,7 @@ function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
};
return (
-
+
);
}
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.tsx b/src/pages/settings/AboutPage/ShareLogList/index.tsx
index 03cd7c42f73c..9c6f82bbb593 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.tsx
@@ -6,7 +6,7 @@ import ROUTES from '@src/ROUTES';
import BaseShareLogList from './BaseShareLogList';
import type {ShareLogListProps} from './types';
-function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
+function ShareLogList({logSource, backTo}: ShareLogListProps) {
const onAttachLogToReport = (reportID: string, filename: string) => {
FileUtils.readFileAsync(
logSource,
@@ -21,10 +21,7 @@ function ShareLogList({logSource, isViaTestToolsModal}: ShareLogListProps) {
);
};
return (
-
+
);
}
diff --git a/src/pages/settings/AboutPage/ShareLogList/types.ts b/src/pages/settings/AboutPage/ShareLogList/types.ts
index bab48c39cc27..500641a3da42 100644
--- a/src/pages/settings/AboutPage/ShareLogList/types.ts
+++ b/src/pages/settings/AboutPage/ShareLogList/types.ts
@@ -1,14 +1,10 @@
type ShareLogListProps = {
/** The source of the log file to share */
logSource: string;
- /** Boolean to know if this was opened via test tools modal */
- isViaTestToolsModal: boolean;
};
type BaseShareLogListProps = {
onAttachLogToReport: (reportID: string, filename: string) => void;
- /** Boolean to know if this was opened via test tools modal */
- isViaTestToolsModal: boolean;
};
export type {BaseShareLogListProps, ShareLogListProps};
diff --git a/src/pages/settings/AboutPage/ShareLogPage.tsx b/src/pages/settings/AboutPage/ShareLogPage.tsx
index 7688ade3ccd1..8f0623f99d32 100644
--- a/src/pages/settings/AboutPage/ShareLogPage.tsx
+++ b/src/pages/settings/AboutPage/ShareLogPage.tsx
@@ -7,12 +7,7 @@ import ShareLogList from './ShareLogList';
type ShareLogPageProps = StackScreenProps;
function ShareLogPage({route}: ShareLogPageProps) {
- return (
-
- );
+ return ;
}
export default ShareLogPage;
diff --git a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
index b463ba02f4d3..8d48a336b260 100644
--- a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
+++ b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
@@ -55,7 +55,7 @@ function TroubleshootPage({shouldStoreLogs}: TroubleshootPageProps) {
const debugConsoleItem: BaseMenuItem = {
translationKey: 'initialSettingsPage.troubleshoot.viewConsole',
icon: Expensicons.Gear,
- action: waitForNavigate(() => Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(false))),
+ action: waitForNavigate(() => Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(ROUTES.SETTINGS_TROUBLESHOOT))),
};
const baseMenuItems: BaseMenuItem[] = [
From 1d0142048d6f2c191117990934f3ad677190566f Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Tue, 7 May 2024 21:00:28 +0530
Subject: [PATCH 031/207] Fixes
---
src/ROUTES.ts | 4 ++--
.../settings/AboutPage/ShareLogList/BaseShareLogList.tsx | 9 ++++-----
src/pages/settings/AboutPage/ShareLogList/index.tsx | 2 +-
3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 12dd16edb9ca..8d2c0fa174f3 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -181,11 +181,11 @@ const ROUTES = {
SETTINGS_TROUBLESHOOT: 'settings/troubleshoot',
SETTINGS_CONSOLE: {
route: 'settings/troubleshoot/console',
- getRoute: (backTo?: string) => getUrlWithBackToParam(`settings/troubleshoot/console`, backTo) as const,
+ getRoute: (backTo?: string) => getUrlWithBackToParam(`settings/troubleshoot/console`, backTo),
},
SETTINGS_SHARE_LOG: {
route: 'settings/troubleshoot/console/share-log',
- getRoute: (source: string, backTo?: string) => getUrlWithBackToParam(`settings/troubleshoot/console/share-log?source=${encodeURI(source)}`, backTo) as const,
+ getRoute: (source: string, backTo?: string) => getUrlWithBackToParam(`settings/troubleshoot/console/share-log?source=${encodeURI(source)}`, backTo),
},
SETTINGS_EXIT_SURVEY_REASON: 'settings/exit-survey/reason',
diff --git a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
index 37c1b4a2ba22..334e4be618d3 100644
--- a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
@@ -15,13 +15,12 @@ import Navigation from '@libs/Navigation/Navigation';
import * as OptionsListUtils from '@libs/OptionsListUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
-import ROUTES from '@src/ROUTES';
import type {Report} from '@src/types/onyx';
+import type {SettingsNavigatorParamList} from "@navigation/types";
+import type SCREENS from "@src/SCREENS";
+import type {RouteProp} from "@react-navigation/native";
+import {useRoute} from "@react-navigation/native";
import type {BaseShareLogListProps} from './types';
-import {StackScreenProps} from "@react-navigation/stack";
-import {SettingsNavigatorParamList} from "@navigation/types";
-import SCREENS from "@src/SCREENS";
-import {RouteProp, useRoute} from "@react-navigation/native";
function BaseShareLogList({onAttachLogToReport}: BaseShareLogListProps) {
const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState('');
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.tsx b/src/pages/settings/AboutPage/ShareLogList/index.tsx
index 9c6f82bbb593..5b410c332426 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.tsx
@@ -6,7 +6,7 @@ import ROUTES from '@src/ROUTES';
import BaseShareLogList from './BaseShareLogList';
import type {ShareLogListProps} from './types';
-function ShareLogList({logSource, backTo}: ShareLogListProps) {
+function ShareLogList({logSource}: ShareLogListProps) {
const onAttachLogToReport = (reportID: string, filename: string) => {
FileUtils.readFileAsync(
logSource,
From 8f1da7f92a177a3c0051c9cb4a2b91c08084d146 Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Wed, 8 May 2024 02:12:37 +0530
Subject: [PATCH 032/207] Update
---
.../BaseClientSideLoggingToolMenu.tsx | 15 ----------
.../index.android.tsx | 4 +--
.../ClientSideLoggingToolMenu/index.ios.tsx | 4 +--
.../ClientSideLoggingToolMenu/index.tsx | 4 +--
.../ClientSideLoggingToolMenu/types.ts | 8 ------
src/components/TestToolsModal.tsx | 28 ++++++++++++++++---
6 files changed, 27 insertions(+), 36 deletions(-)
delete mode 100644 src/components/ClientSideLoggingToolMenu/types.ts
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index 99afa5185e7f..157d824065ac 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -35,8 +35,6 @@ type BaseClientSideLoggingToolProps = {
onEnableLogging?: () => void;
/** Path used to display location of saved file */
displayPath?: string;
- /** Boolean to know if this was opened via test tools modal */
- isViaTestToolsModal: boolean;
} & BaseClientSideLoggingToolMenuOnyxProps;
function BaseClientSideLoggingToolMenu({
@@ -47,7 +45,6 @@ function BaseClientSideLoggingToolMenu({
onDisableLogging,
onEnableLogging,
displayPath,
- isViaTestToolsModal
}: BaseClientSideLoggingToolProps) {
const {translate} = useLocalize();
@@ -85,18 +82,6 @@ function BaseClientSideLoggingToolMenu({
onToggle={onToggle}
/>
- {!!shouldStoreLogs && isViaTestToolsModal && (
-
- {
- toggleTestToolsModal()
- Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute());
- }}
- />
-
- )}
{!!file && (
<>
{`path: ${displayPath}`}
diff --git a/src/components/ClientSideLoggingToolMenu/index.android.tsx b/src/components/ClientSideLoggingToolMenu/index.android.tsx
index d9335a5c5921..aa1bc215b719 100644
--- a/src/components/ClientSideLoggingToolMenu/index.android.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.android.tsx
@@ -5,9 +5,8 @@ import type {Log} from '@libs/Console';
import localFileCreate from '@libs/localFileCreate';
import CONST from '@src/CONST';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-import type ClientSideLoggingToolMenuProps from './types';
-function ClientSideLoggingToolMenu({isViaTestToolsModal = false}: ClientSideLoggingToolMenuProps) {
+function ClientSideLoggingToolMenu() {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
const createAndSaveFile = (logs: Log[]) => {
@@ -41,7 +40,6 @@ function ClientSideLoggingToolMenu({isViaTestToolsModal = false}: ClientSideLogg
onDisableLogging={createAndSaveFile}
onShareLogs={shareLogs}
displayPath={`${CONST.DOWNLOADS_PATH}/${file?.newFileName ?? ''}`}
- isViaTestToolsModal={isViaTestToolsModal}
/>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/index.ios.tsx b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
index bfdc6fbcde9b..78ffccf612a2 100644
--- a/src/components/ClientSideLoggingToolMenu/index.ios.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.ios.tsx
@@ -6,9 +6,8 @@ import getDownloadFolderPathSuffixForIOS from '@libs/getDownloadFolderPathSuffix
import localFileCreate from '@libs/localFileCreate';
import CONST from '@src/CONST';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-import type ClientSideLoggingToolMenuProps from './types';
-function ClientSideLoggingToolMenu({isViaTestToolsModal = false}: ClientSideLoggingToolMenuProps) {
+function ClientSideLoggingToolMenu() {
const [file, setFile] = useState<{path: string; newFileName: string; size: number}>();
const {environment} = useEnvironment();
@@ -34,7 +33,6 @@ function ClientSideLoggingToolMenu({isViaTestToolsModal = false}: ClientSideLogg
onDisableLogging={createFile}
onShareLogs={shareLogs}
displayPath={`${CONST.NEW_EXPENSIFY_PATH}${getDownloadFolderPathSuffixForIOS(environment)}/${file?.newFileName ?? ''}`}
- isViaTestToolsModal={isViaTestToolsModal}
/>
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/index.tsx b/src/components/ClientSideLoggingToolMenu/index.tsx
index 50dfb629b565..7208297ade53 100644
--- a/src/components/ClientSideLoggingToolMenu/index.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.tsx
@@ -2,9 +2,8 @@ import React from 'react';
import type {Log} from '@libs/Console';
import localFileDownload from '@libs/localFileDownload';
import BaseClientSideLoggingToolMenu from './BaseClientSideLoggingToolMenu';
-import type ClientSideLoggingToolMenuProps from './types';
-function ClientSideLoggingToolMenu({isViaTestToolsModal}: ClientSideLoggingToolMenuProps) {
+function ClientSideLoggingToolMenu() {
const downloadFile = (logs: Log[]) => {
localFileDownload('logs', JSON.stringify(logs, null, 2));
};
@@ -12,7 +11,6 @@ function ClientSideLoggingToolMenu({isViaTestToolsModal}: ClientSideLoggingToolM
return (
);
}
diff --git a/src/components/ClientSideLoggingToolMenu/types.ts b/src/components/ClientSideLoggingToolMenu/types.ts
deleted file mode 100644
index 86ad66dfd33c..000000000000
--- a/src/components/ClientSideLoggingToolMenu/types.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-type ClientSideLoggingToolMenuProps = {
- /** Boolean to know if this was opened via test tools modal */
- isViaTestToolsModal: boolean;
- /** Action to close the test tools modal */
- closeTestToolsModal?: () => void;
-};
-
-export default ClientSideLoggingToolMenuProps;
diff --git a/src/components/TestToolsModal.tsx b/src/components/TestToolsModal.tsx
index e60600909b26..3d9f400d99aa 100644
--- a/src/components/TestToolsModal.tsx
+++ b/src/components/TestToolsModal.tsx
@@ -10,6 +10,10 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
import toggleTestToolsModal from '@userActions/TestTool';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
+import Navigation from "@navigation/Navigation";
+import ROUTES from "@src/ROUTES";
+import Button from "./Button";
+import TestToolRow from "./TestToolRow";
import ClientSideLoggingToolMenu from './ClientSideLoggingToolMenu';
import Modal from './Modal';
import ProfilingToolMenu from './ProfilingToolMenu';
@@ -19,11 +23,14 @@ import Text from './Text';
type TestToolsModalOnyxProps = {
/** Whether the test tools modal is open */
isTestToolsModalOpen: OnyxEntry;
+
+ /** Whether or not logs should be stored */
+ shouldStoreLogs: OnyxEntry;
};
type TestToolsModalProps = TestToolsModalOnyxProps;
-function TestToolsModal({isTestToolsModalOpen = false}: TestToolsModalProps) {
+function TestToolsModal({isTestToolsModalOpen = false, shouldStoreLogs = false}: TestToolsModalProps) {
const {isDevelopment} = useEnvironment();
const {windowWidth} = useWindowDimensions();
const StyleUtils = useStyleUtils();
@@ -45,9 +52,19 @@ function TestToolsModal({isTestToolsModalOpen = false}: TestToolsModalProps) {
{translate('initialSettingsPage.troubleshoot.releaseOptions')}
-
+
+ {!!shouldStoreLogs && (
+
+ {
+ toggleTestToolsModal();
+ Navigation.navigate(ROUTES.SETTINGS_CONSOLE.getRoute(Navigation.getActiveRoute()));
+ }}
+ />
+
+ )}
);
@@ -59,4 +76,7 @@ export default withOnyx({
isTestToolsModalOpen: {
key: ONYXKEYS.IS_TEST_TOOLS_MODAL_OPEN,
},
+ shouldStoreLogs: {
+ key: ONYXKEYS.SHOULD_STORE_LOGS,
+ },
})(TestToolsModal);
From 064cd4deb6ee5ab039abd1f179a68ce36c41ee5e Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Wed, 8 May 2024 02:15:35 +0530
Subject: [PATCH 033/207] Update
---
src/pages/settings/AboutPage/ShareLogList/index.native.tsx | 4 +---
src/pages/settings/AboutPage/ShareLogList/index.tsx | 4 +---
src/pages/settings/Troubleshoot/TroubleshootPage.tsx | 2 +-
3 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.native.tsx b/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
index 4753d60379dd..9150f4655f95 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.native.tsx
@@ -17,9 +17,7 @@ function ShareLogList({logSource}: ShareLogListProps) {
Navigation.navigate(routeToNavigate);
};
- return (
-
- );
+ return ;
}
export default ShareLogList;
diff --git a/src/pages/settings/AboutPage/ShareLogList/index.tsx b/src/pages/settings/AboutPage/ShareLogList/index.tsx
index 5b410c332426..555e44e53747 100644
--- a/src/pages/settings/AboutPage/ShareLogList/index.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/index.tsx
@@ -20,9 +20,7 @@ function ShareLogList({logSource}: ShareLogListProps) {
() => {},
);
};
- return (
-
- );
+ return ;
}
export default ShareLogList;
diff --git a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
index 8d48a336b260..817edb5cc9f7 100644
--- a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
+++ b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx
@@ -119,7 +119,7 @@ function TroubleshootPage({shouldStoreLogs}: TroubleshootPageProps) {
>
-
+
Date: Wed, 8 May 2024 13:48:58 +0700
Subject: [PATCH 034/207] do not require policy for money request
---
src/pages/iou/request/IOURequestStartPage.tsx | 2 +-
src/pages/workspace/AccessOrNotFoundWrapper.tsx | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx
index 3e057c4d8300..661da2c1a97a 100644
--- a/src/pages/iou/request/IOURequestStartPage.tsx
+++ b/src/pages/iou/request/IOURequestStartPage.tsx
@@ -1,7 +1,7 @@
import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
-import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
+import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import DragAndDropProvider from '@components/DragAndDrop/Provider';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
index 85d63c7f423a..c67b4a521fe7 100644
--- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx
+++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
@@ -24,6 +24,8 @@ const ACCESS_VARIANTS = {
[CONST.POLICY.ACCESS_VARIANTS.PAID]: (policy: OnyxEntry) => PolicyUtils.isPaidGroupPolicy(policy) && !!policy?.isPolicyExpenseChatEnabled,
[CONST.POLICY.ACCESS_VARIANTS.ADMIN]: (policy: OnyxEntry) => PolicyUtils.isPolicyAdmin(policy),
[CONST.IOU.ACCESS_VARIANTS.CREATE]: (policy: OnyxEntry, report: OnyxEntry, allPolicies: OnyxCollection, iouType?: IOUType) =>
+ !!iouType &&
+ IOUUtils.isValidMoneyRequestType(iouType) &&
// Allow the user to submit the expense if we are submitting the expense in global menu or the report can create the expense
(isEmptyObject(report?.reportID) || ReportUtils.canCreateRequest(report, policy, iouType)) &&
(iouType !== CONST.IOU.TYPE.INVOICE || PolicyUtils.canSendInvoice(allPolicies)),
@@ -94,6 +96,8 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps
const {policy, policyID, report, iouType, allPolicies, featureName, isLoadingReportData} = props;
const isPolicyIDInRoute = !!policyID?.length;
+ const isMoneyRequest = !!iouType && IOUUtils.isValidMoneyRequestType(iouType);
+ const isFromGlobalCreate = isEmptyObject(report?.reportID);
useEffect(() => {
if (!isPolicyIDInRoute || !isEmptyObject(policy)) {
@@ -105,7 +109,7 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isPolicyIDInRoute, policyID]);
- const shouldShowFullScreenLoadingIndicator = isLoadingReportData !== false && (!Object.entries(policy ?? {}).length || !policy?.id);
+ const shouldShowFullScreenLoadingIndicator = !isMoneyRequest && isLoadingReportData !== false && (!Object.entries(policy ?? {}).length || !policy?.id);
const isFeatureEnabled = featureName ? PolicyUtils.isPolicyFeatureEnabled(policy, featureName) : true;
@@ -114,12 +118,8 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps
return acc && accessFunction(policy, report, allPolicies, iouType);
}, true);
- const isIOU = !!iouType && IOUUtils.isValidMoneyRequestType(iouType);
- const isFromGlobalCreate = isEmptyObject(report?.reportID);
-
const isPolicyNotAccessible = isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id;
- const shouldShowNotFoundPage =
- isPolicyNotAccessible || !isPageAccessible || !isFeatureEnabled || shouldBeBlocked;
+ const shouldShowNotFoundPage = (!isMoneyRequest && !isFromGlobalCreate && isPolicyNotAccessible) || !isPageAccessible || !isFeatureEnabled || shouldBeBlocked;
if (shouldShowFullScreenLoadingIndicator) {
return ;
From 5c971d72dc086be81caa62186ba8557fe2ec60c6 Mon Sep 17 00:00:00 2001
From: tienifr
Date: Wed, 8 May 2024 15:34:26 +0700
Subject: [PATCH 035/207] handle go back
---
src/pages/workspace/AccessOrNotFoundWrapper.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
index c67b4a521fe7..c289905a1bf6 100644
--- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx
+++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
@@ -85,7 +85,7 @@ function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageN
/>
) : (
!!policyID && Navigation.goBack(ROUTES.WORKSPACE_PROFILE.getRoute(policyID))}
+ onBackButtonPress={() => Navigation.goBack(policyID ? ROUTES.WORKSPACE_PROFILE.getRoute(policyID) : undefined)}
// eslint-disable-next-line react/jsx-props-no-spreading
{...fullPageNotFoundViewProps}
/>
From c0ce51c4422c6a0a4ab60278d8057919220a3685 Mon Sep 17 00:00:00 2001
From: tienifr
Date: Wed, 8 May 2024 15:38:19 +0700
Subject: [PATCH 036/207] handle go back home
---
src/pages/workspace/AccessOrNotFoundWrapper.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
index c289905a1bf6..4740fb7f5988 100644
--- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx
+++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
@@ -85,7 +85,7 @@ function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageN
/>
) : (
Navigation.goBack(policyID ? ROUTES.WORKSPACE_PROFILE.getRoute(policyID) : undefined)}
+ onBackButtonPress={() => Navigation.goBack(policyID ? ROUTES.WORKSPACE_PROFILE.getRoute(policyID) : ROUTES.HOME)}
// eslint-disable-next-line react/jsx-props-no-spreading
{...fullPageNotFoundViewProps}
/>
From 42193ec979ab4d06c9d233a6618ed95a786a1cd2 Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Wed, 8 May 2024 17:55:45 +0530
Subject: [PATCH 037/207] Update
---
src/ROUTES.ts | 2 +-
.../BaseClientSideLoggingToolMenu.tsx | 14 +-------------
src/components/ClientSideLoggingToolMenu/index.tsx | 6 +-----
src/pages/settings/AboutPage/ConsolePage.tsx | 6 ++----
.../AboutPage/ShareLogList/BaseShareLogList.tsx | 9 ++-------
5 files changed, 7 insertions(+), 30 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 8d2c0fa174f3..af4dc013fbca 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -185,7 +185,7 @@ const ROUTES = {
},
SETTINGS_SHARE_LOG: {
route: 'settings/troubleshoot/console/share-log',
- getRoute: (source: string, backTo?: string) => getUrlWithBackToParam(`settings/troubleshoot/console/share-log?source=${encodeURI(source)}`, backTo),
+ getRoute: (source: string) => `settings/troubleshoot/console/share-log?source=${encodeURI(source)}` as const,
},
SETTINGS_EXIT_SURVEY_REASON: 'settings/exit-survey/reason',
diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
index 157d824065ac..7c4c669e2154 100644
--- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
+++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx
@@ -10,11 +10,8 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Console from '@libs/actions/Console';
import {parseStringifiedMessages} from '@libs/Console';
-import Navigation from '@navigation/Navigation';
import ONYXKEYS from '@src/ONYXKEYS';
-import ROUTES from '@src/ROUTES';
import type {CapturedLogs, Log} from '@src/types/onyx';
-import toggleTestToolsModal from "@userActions/TestTool";
type BaseClientSideLoggingToolMenuOnyxProps = {
/** Logs captured on the current device */
@@ -37,15 +34,7 @@ type BaseClientSideLoggingToolProps = {
displayPath?: string;
} & BaseClientSideLoggingToolMenuOnyxProps;
-function BaseClientSideLoggingToolMenu({
- shouldStoreLogs,
- capturedLogs,
- file,
- onShareLogs,
- onDisableLogging,
- onEnableLogging,
- displayPath,
-}: BaseClientSideLoggingToolProps) {
+function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onShareLogs, onDisableLogging, onEnableLogging, displayPath}: BaseClientSideLoggingToolProps) {
const {translate} = useLocalize();
const onToggle = () => {
@@ -72,7 +61,6 @@ function BaseClientSideLoggingToolMenu({
Console.disableLoggingAndFlushLogs();
};
const styles = useThemeStyles();
-
return (
<>
diff --git a/src/components/ClientSideLoggingToolMenu/index.tsx b/src/components/ClientSideLoggingToolMenu/index.tsx
index 7208297ade53..182c3bf99b74 100644
--- a/src/components/ClientSideLoggingToolMenu/index.tsx
+++ b/src/components/ClientSideLoggingToolMenu/index.tsx
@@ -8,11 +8,7 @@ function ClientSideLoggingToolMenu() {
localFileDownload('logs', JSON.stringify(logs, null, 2));
};
- return (
-
- );
+ return ;
}
ClientSideLoggingToolMenu.displayName = 'ClientSideLoggingToolMenu';
diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx
index b3dab1999e64..63f23df057dc 100644
--- a/src/pages/settings/AboutPage/ConsolePage.tsx
+++ b/src/pages/settings/AboutPage/ConsolePage.tsx
@@ -97,7 +97,7 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) {
return;
}
- Navigation.navigate(ROUTES.SETTINGS_SHARE_LOG.getRoute(path, ROUTES.SETTINGS_CONSOLE.getRoute(route.params?.backTo)));
+ Navigation.navigate(ROUTES.SETTINGS_SHARE_LOG.getRoute(path));
});
};
@@ -120,9 +120,7 @@ function ConsolePage({capturedLogs, shouldStoreLogs}: ConsolePageProps) {
{
- Navigation.goBack(route.params?.backTo);
- }}
+ onBackButtonPress={() => Navigation.goBack(route.params?.backTo)}
/>
>();
-
const searchOptions = useMemo(() => {
if (!areOptionsInitialized) {
return {
@@ -104,7 +99,7 @@ function BaseShareLogList({onAttachLogToReport}: BaseShareLogListProps) {
<>
Navigation.goBack(route.params?.backTo)}
+ onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_CONSOLE)}
/>
Date: Wed, 8 May 2024 18:12:53 +0530
Subject: [PATCH 038/207] Fixes
---
src/components/TestToolsModal.tsx | 8 ++++----
.../settings/AboutPage/ShareLogList/BaseShareLogList.tsx | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/components/TestToolsModal.tsx b/src/components/TestToolsModal.tsx
index 3d9f400d99aa..ad1c65e76a4b 100644
--- a/src/components/TestToolsModal.tsx
+++ b/src/components/TestToolsModal.tsx
@@ -7,17 +7,17 @@ import useLocalize from '@hooks/useLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
+import Navigation from '@navigation/Navigation';
import toggleTestToolsModal from '@userActions/TestTool';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
-import Navigation from "@navigation/Navigation";
-import ROUTES from "@src/ROUTES";
-import Button from "./Button";
-import TestToolRow from "./TestToolRow";
+import ROUTES from '@src/ROUTES';
+import Button from './Button';
import ClientSideLoggingToolMenu from './ClientSideLoggingToolMenu';
import Modal from './Modal';
import ProfilingToolMenu from './ProfilingToolMenu';
import TestToolMenu from './TestToolMenu';
+import TestToolRow from './TestToolRow';
import Text from './Text';
type TestToolsModalOnyxProps = {
diff --git a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
index 58c3be7df6b1..943bff5459ce 100644
--- a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
+++ b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
@@ -99,7 +99,7 @@ function BaseShareLogList({onAttachLogToReport}: BaseShareLogListProps) {
<>
Navigation.goBack(ROUTES.SETTINGS_CONSOLE)}
+ onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_CONSOLE.getRoute())}
/>
Date: Wed, 8 May 2024 18:37:05 +0530
Subject: [PATCH 039/207] Add new command and JSdoc
---
.../SyncPolicyToIntegratedConnectionParams.ts | 6 +++++
.../SyncPolicyToQuickbooksOnlineParams.ts | 6 -----
src/libs/API/parameters/index.ts | 2 +-
src/libs/API/types.ts | 4 ++-
src/libs/actions/connections/index.ts | 26 +++++++++++++------
5 files changed, 28 insertions(+), 16 deletions(-)
create mode 100644 src/libs/API/parameters/SyncPolicyToIntegratedConnectionParams.ts
delete mode 100644 src/libs/API/parameters/SyncPolicyToQuickbooksOnlineParams.ts
diff --git a/src/libs/API/parameters/SyncPolicyToIntegratedConnectionParams.ts b/src/libs/API/parameters/SyncPolicyToIntegratedConnectionParams.ts
new file mode 100644
index 000000000000..ad3a926c6b3e
--- /dev/null
+++ b/src/libs/API/parameters/SyncPolicyToIntegratedConnectionParams.ts
@@ -0,0 +1,6 @@
+type SyncPolicyToIntegratedConnectionParams = {
+ policyID: string;
+ idempotencyKey: string;
+};
+
+export default SyncPolicyToIntegratedConnectionParams;
diff --git a/src/libs/API/parameters/SyncPolicyToQuickbooksOnlineParams.ts b/src/libs/API/parameters/SyncPolicyToQuickbooksOnlineParams.ts
deleted file mode 100644
index b5782c150b9f..000000000000
--- a/src/libs/API/parameters/SyncPolicyToQuickbooksOnlineParams.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-type SyncPolicyToQuickbooksOnlineParams = {
- policyID: string;
- idempotencyKey: string;
-};
-
-export default SyncPolicyToQuickbooksOnlineParams;
diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts
index 30261051c0e5..6fa8cf510eb0 100644
--- a/src/libs/API/parameters/index.ts
+++ b/src/libs/API/parameters/index.ts
@@ -12,7 +12,7 @@ export type {default as BeginSignInParams} from './BeginSignInParams';
export type {default as CloseAccountParams} from './CloseAccountParams';
export type {default as ConnectBankAccountParams} from './ConnectBankAccountParams';
export type {default as ConnectPolicyToAccountingIntegrationParams} from './ConnectPolicyToAccountingIntegrationParams';
-export type {default as SyncPolicyToQuickbooksOnlineParams} from './SyncPolicyToQuickbooksOnlineParams';
+export type {default as SyncPolicyToIntegratedConnectionParams} from './SyncPolicyToIntegratedConnectionParams';
export type {default as DeleteContactMethodParams} from './DeleteContactMethodParams';
export type {default as DeletePaymentBankAccountParams} from './DeletePaymentBankAccountParams';
export type {default as DeletePaymentCardParams} from './DeletePaymentCardParams';
diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts
index cd85cdfbe401..ee2639284883 100644
--- a/src/libs/API/types.ts
+++ b/src/libs/API/types.ts
@@ -434,6 +434,7 @@ const READ_COMMANDS = {
CONNECT_POLICY_TO_QUICKBOOKS_ONLINE: 'ConnectPolicyToQuickbooksOnline',
CONNECT_POLICY_TO_XERO: 'ConnectPolicyToXero',
SYNC_POLICY_TO_QUICKBOOKS_ONLINE: 'SyncPolicyToQuickbooksOnline',
+ SYNC_POLICY_TO_XERO: 'SyncPolicyToXero',
OPEN_REIMBURSEMENT_ACCOUNT_PAGE: 'OpenReimbursementAccountPage',
OPEN_WORKSPACE_VIEW: 'OpenWorkspaceView',
GET_MAPBOX_ACCESS_TOKEN: 'GetMapboxAccessToken',
@@ -479,7 +480,8 @@ type ReadCommand = ValueOf;
type ReadCommandParameters = {
[READ_COMMANDS.CONNECT_POLICY_TO_QUICKBOOKS_ONLINE]: Parameters.ConnectPolicyToAccountingIntegrationParams;
[READ_COMMANDS.CONNECT_POLICY_TO_XERO]: Parameters.ConnectPolicyToAccountingIntegrationParams;
- [READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_ONLINE]: Parameters.SyncPolicyToQuickbooksOnlineParams;
+ [READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_ONLINE]: Parameters.SyncPolicyToIntegratedConnectionParams;
+ [READ_COMMANDS.SYNC_POLICY_TO_XERO]: Parameters.SyncPolicyToIntegratedConnectionParams;
[READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE]: Parameters.OpenReimbursementAccountPageParams;
[READ_COMMANDS.OPEN_WORKSPACE_VIEW]: Parameters.OpenWorkspaceViewParams;
[READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN]: EmptyObject;
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 2296ae28df60..10d07599c374 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -1,7 +1,11 @@
-import Onyx from 'react-native-onyx';
import type {OnyxUpdate} from 'react-native-onyx';
+import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
-import type {RemovePolicyConnectionParams, UpdatePolicyConnectionConfigParams, SyncPolicyToQuickbooksOnlineParams} from '@libs/API/parameters';
+import type {
+ RemovePolicyConnectionParams,
+ SyncPolicyToIntegratedConnectionParams,
+ UpdatePolicyConnectionConfigParams
+} from '@libs/API/parameters';
import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
@@ -42,6 +46,7 @@ function removePolicyConnection(policyID: string, connectionName: PolicyConnecti
};
API.write(WRITE_COMMANDS.REMOVE_POLICY_CONNECTION, parameters, {optimisticData, failureData});
}
+
function updatePolicyConnectionConfig(
policyID: string,
connectionName: TConnectionName,
@@ -124,6 +129,12 @@ function updatePolicyConnectionConfig
Date: Fri, 10 May 2024 01:52:47 +0530
Subject: [PATCH 040/207] Update
---
src/libs/actions/connections/index.ts | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 7b77f785bb6a..95495b19d7c7 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -1,11 +1,7 @@
import type {OnyxUpdate} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
-import type {
- RemovePolicyConnectionParams,
- SyncPolicyToIntegratedConnectionParams,
- UpdatePolicyConnectionConfigParams
-} from '@libs/API/parameters';
+import type {RemovePolicyConnectionParams, SyncPolicyToIntegratedConnectionParams, UpdatePolicyConnectionConfigParams} from '@libs/API/parameters';
import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
@@ -150,7 +146,7 @@ function syncConnection(policyID: string, connectionName: PolicyConnectionName |
API.read(connectionName === CONST.POLICY.CONNECTIONS.NAME.QBO ? READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_ONLINE : READ_COMMANDS.SYNC_POLICY_TO_XERO, parameters, {
optimisticData,
- failureData
+ failureData,
});
}
From 66142428d257665e1aa57c0e37e8f6574237ce61 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 05:47:49 +0530
Subject: [PATCH 041/207] unlink from advanced
---
.../workspace/accounting/xero/advanced/XeroAdvancedPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
index 8c48840352c1..154f5f8a97f9 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
@@ -62,7 +62,7 @@ function XeroAdvancedPage({policy}: WithPolicyConnectionsProps) {
description={translate('workspace.xero.advancedConfig.purchaseBillStatusTitle')}
key={translate('workspace.xero.advancedConfig.purchaseBillStatusTitle')}
wrapperStyle={[styles.sectionMenuItemTopDescription]}
- onPress={() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR.getRoute(policyID))}
+ onPress={() => {}}
/>
Date: Fri, 10 May 2024 05:52:41 +0530
Subject: [PATCH 042/207] link export page
---
.../accounting/xero/export/XeroExportConfigurationPage.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/pages/workspace/accounting/xero/export/XeroExportConfigurationPage.tsx b/src/pages/workspace/accounting/xero/export/XeroExportConfigurationPage.tsx
index 934c41dab614..e951afff922f 100644
--- a/src/pages/workspace/accounting/xero/export/XeroExportConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroExportConfigurationPage.tsx
@@ -6,9 +6,11 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback';
import type {OfflineWithFeedbackProps} from '@components/OfflineWithFeedback';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
+import Navigation from '@libs/Navigation/Navigation';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import CONST from '@src/CONST';
+import ROUTES from '@src/ROUTES';
type MenuItem = MenuItemProps & {pendingAction?: OfflineWithFeedbackProps['pendingAction']};
@@ -44,7 +46,7 @@ function XeroExportConfigurationPage({policy}: WithPolicyConnectionsProps) {
},
{
description: translate('workspace.xero.advancedConfig.purchaseBillStatusTitle'),
- onPress: () => {},
+ onPress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR.getRoute(policyID)),
title: exportConfiguration?.billStatus?.purchase,
pendingAction: pendingFields?.export,
error: errorFields?.purchase ? translate('common.genericErrorMessage') : undefined,
From 6ad88e37c701ed59d7d67abdab5234ecae8dfe8b Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 06:02:31 +0530
Subject: [PATCH 043/207] update route to export
---
src/ROUTES.ts | 4 +-
src/SCREENS.ts | 2 +-
.../XeroPurchaseBillStatusSelectorPage.tsx | 85 -------------------
.../XeroPurchaseBillStatusSelectorPage.tsx | 73 ++++++++++++++++
4 files changed, 76 insertions(+), 88 deletions(-)
delete mode 100644 src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx
create mode 100644 src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 60d8cce94e35..445a7497b65f 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -817,8 +817,8 @@ const ROUTES = {
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/advanced` as const,
},
POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR: {
- route: 'settings/workspaces/:policyID/accounting/xero/advanced/purchase-bill-status-selector',
- getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/advanced/purchase-bill-status-selector` as const,
+ route: 'settings/workspaces/:policyID/accounting/xero/export/purchase-bill-status-selector',
+ getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/export/purchase-bill-status-selector` as const,
},
POLICY_ACCOUNTING_XERO_INVOICE_SELECTOR: {
route: 'settings/workspaces/:policyID/accounting/xero/advanced/invoice-account-selector',
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index 1f04484e0f64..5c1589626cc4 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -250,7 +250,7 @@ const SCREENS = {
XERO_EXPORT: 'Policy_Accounting_Xero_Export',
XERO_EXPORT_PURCHASE_BILL_DATE_SELECT: 'Policy_Accounting_Xero_Export_Purchase_Bill_Date_Select',
XERO_ADVANCED: 'Policy_Accounting_Xero_Advanced',
- XERO_BILL_STATUS_SELECTOR: 'Policy_Accounting_Xero_Advanced_Bill_Status',
+ XERO_BILL_STATUS_SELECTOR: 'Policy_Accounting_Xero_Export_Bill_Status',
XERO_INVOICE_ACCOUNT_SELECTOR: 'Policy_Accounting_Xero_Invoice_Account_Selector',
XERO_EXPORT_PREFERRED_EXPORTER_SELECT: 'Workspace_Accounting_Xero_Export_Preferred_Exporter_Select',
XERO_BILL_PAYMENT_ACCOUNT_SELECTOR: 'Policy_Accounting_Xero_Bill_Payment_Account_Selector',
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx
deleted file mode 100644
index bffe9eecb73b..000000000000
--- a/src/pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import React, {useCallback, useMemo} from 'react';
-import {View} from 'react-native';
-import ConnectionLayout from '@components/ConnectionLayout';
-import HeaderWithBackButton from '@components/HeaderWithBackButton';
-import ScreenWrapper from '@components/ScreenWrapper';
-import SelectionList from '@components/SelectionList';
-import RadioListItem from '@components/SelectionList/RadioListItem';
-import type {ListItem} from '@components/SelectionList/types';
-import SelectionScreen from '@components/SelectionScreen';
-import Text from '@components/Text';
-import useLocalize from '@hooks/useLocalize';
-import useThemeStyles from '@hooks/useThemeStyles';
-import * as Connections from '@libs/actions/connections';
-import Navigation from '@libs/Navigation/Navigation';
-import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
-import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
-import withPolicyConnections from '@pages/workspace/withPolicyConnections';
-import CONST from '@src/CONST';
-import ROUTES from '@src/ROUTES';
-
-type SelectorType = ListItem & {
- value: string;
-};
-
-function XeroPurchaseBillStatusSelectorPage({policy}: WithPolicyConnectionsProps) {
- const styles = useThemeStyles();
- const {translate} = useLocalize();
-
- const policyID = policy?.id ?? '';
- const {bankAccounts} = policy?.connections?.xero?.data ?? {};
-
- const {invoiceCollectionsAccountID} = policy?.connections?.xero?.config.sync ?? {};
-
- const xeroSelectorOptions = useMemo(
- () =>
- (bankAccounts ?? []).map(({id, name}) => ({
- value: id,
- text: name,
- keyForList: id,
- isSelected: invoiceCollectionsAccountID === id,
- })),
- [invoiceCollectionsAccountID, bankAccounts],
- );
-
- const listHeaderComponent = useMemo(
- () => (
-
- {translate('workspace.xero.advancedConfig.invoiceAccountSelectDescription')}
-
- ),
- [translate, styles.pb2, styles.ph5, styles.pb5, styles.textNormal],
- );
-
- const initiallyFocusedOptionKey = useMemo(() => xeroSelectorOptions?.find((mode) => mode.isSelected)?.keyForList, [xeroSelectorOptions]);
-
- const updateMode = useCallback(
- ({value}: SelectorType) => {
- Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.SYNC, {
- invoiceCollectionsAccountID: value,
- });
- Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.getRoute(policyID));
- },
- [policyID],
- );
-
- return (
- Navigation.goBack()}
- title="workspace.xero.advancedConfig.xeroInvoiceCollectionAccount"
- />
- );
-}
-
-XeroPurchaseBillStatusSelectorPage.displayName = 'XeroPurchaseBillStatusSelectorPage';
-
-export default withPolicyConnections(XeroPurchaseBillStatusSelectorPage);
diff --git a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
new file mode 100644
index 000000000000..8c652325312b
--- /dev/null
+++ b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
@@ -0,0 +1,73 @@
+import React, {useCallback, useMemo} from 'react';
+import {View} from 'react-native';
+import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/RadioListItem';
+import type {ListItem} from '@components/SelectionList/types';
+import SelectionScreen from '@components/SelectionScreen';
+import type {SelectorType} from '@components/SelectionScreen';
+import Text from '@components/Text';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@hooks/useThemeStyles';
+import * as Connections from '@libs/actions/connections';
+import Navigation from '@navigation/Navigation';
+import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
+import withPolicyConnections from '@pages/workspace/withPolicyConnections';
+import CONST from '@src/CONST';
+import ROUTES from '@src/ROUTES';
+
+type MenuListItem = ListItem & {
+ value: ValueOf;
+};
+
+function XeroPurchaseBillStatusSelectorPage({policy}: WithPolicyConnectionsProps) {
+ const {translate} = useLocalize();
+ const policyID = policy?.id ?? '';
+ const styles = useThemeStyles();
+ const {billDate} = policy?.connections?.xero?.config?.export ?? {};
+ const data: MenuListItem[] = Object.values(CONST.XERO_EXPORT_DATE).map((dateType) => ({
+ value: dateType,
+ text: translate(`workspace.xero.exportDate.values.${dateType}.label`),
+ alternateText: translate(`workspace.xero.exportDate.values.${dateType}.description`),
+ keyForList: dateType,
+ isSelected: billDate === dateType,
+ }));
+
+ const headerContent = useMemo(
+ () => (
+
+ {translate('workspace.xero.exportDate.description')}
+
+ ),
+ [translate, styles.pb5, styles.ph5],
+ );
+
+ const selectExportDate = useCallback(
+ (row: MenuListItem) => {
+ if (row.value !== billDate) {
+ Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.EXPORT, {billDate: row.value});
+ }
+ Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_EXPORT_PURCHASE_BILL_DATE_SELECT.getRoute(policyID));
+ },
+ [billDate, policyID],
+ );
+
+ return (
+ selectExportDate(selection as MenuListItem)}
+ initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
+ policyID={policyID}
+ accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]}
+ featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
+ onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_EXPORT.getRoute(policyID))}
+ />
+ );
+}
+
+XeroPurchaseBillStatusSelectorPage.displayName = 'XeroPurchaseBillDateSelectPage';
+
+export default withPolicyConnections(XeroPurchaseBillStatusSelectorPage);
From db7f63ec9b5879f3b90055e5e46d691ca43c0615 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 14:05:12 +0530
Subject: [PATCH 044/207] add lang
---
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 d51d142696cc..d2dab5746e11 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2082,6 +2082,8 @@ export default {
},
},
invoiceStatus: {
+ label: 'Purchase bill status',
+ description: 'When exported to Xero what state should purchase bills have.',
values: {
[CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Authorised',
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Draft',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index a19342d04ea3..a83e2f55931d 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2117,6 +2117,8 @@ export default {
},
},
invoiceStatus: {
+ label: 'Estado de la factura de compra',
+ description: 'When exported to Xero what state should purchase bills have.',
values: {
[CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Autorizado',
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Borrador',
From c4fcf6d11703fdfcb3feb5ded79ee36682a1e724 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 14:05:29 +0530
Subject: [PATCH 045/207] fix nav
---
src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
index 1a179ec9a733..330de469d0a7 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
@@ -314,7 +314,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/accounting/xero/advanced/XeroAdvancedPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_BILL_STATUS_SELECTOR]: () =>
- require('../../../../pages/workspace/accounting/xero/advanced/XeroPurchaseBillStatusSelectorPage').default as React.ComponentType,
+ require('../../../../pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_INVOICE_ACCOUNT_SELECTOR]: () =>
require('../../../../pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT_PREFERRED_EXPORTER_SELECT]: () =>
From d75c75674ca4e144ab62c5b4d76d774cba92c4f5 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 14:05:46 +0530
Subject: [PATCH 046/207] use updated routes and lang
---
.../XeroPurchaseBillStatusSelectorPage.tsx | 35 ++++++++++---------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
index 8c652325312b..dc2119c49d93 100644
--- a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
@@ -16,49 +16,50 @@ import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
type MenuListItem = ListItem & {
- value: ValueOf;
+ value: ValueOf;
};
function XeroPurchaseBillStatusSelectorPage({policy}: WithPolicyConnectionsProps) {
const {translate} = useLocalize();
const policyID = policy?.id ?? '';
const styles = useThemeStyles();
- const {billDate} = policy?.connections?.xero?.config?.export ?? {};
- const data: MenuListItem[] = Object.values(CONST.XERO_EXPORT_DATE).map((dateType) => ({
- value: dateType,
- text: translate(`workspace.xero.exportDate.values.${dateType}.label`),
- alternateText: translate(`workspace.xero.exportDate.values.${dateType}.description`),
- keyForList: dateType,
- isSelected: billDate === dateType,
+ const {billStatus} = policy?.connections?.xero?.config?.export ?? {};
+ const invoiceStatus = billStatus?.purchase;
+
+ const data: MenuListItem[] = Object.values(CONST.XERO_CONFIG.INVOICE_STATUS).map((status) => ({
+ value: status,
+ text: translate(`workspace.xero.invoiceStatus.values.${status}`),
+ keyForList: status,
+ isSelected: invoiceStatus === status,
}));
const headerContent = useMemo(
() => (
- {translate('workspace.xero.exportDate.description')}
+ {translate('workspace.xero.invoiceStatus.description')}
),
[translate, styles.pb5, styles.ph5],
);
- const selectExportDate = useCallback(
+ const selectPurchaseBillStatus = useCallback(
(row: MenuListItem) => {
- if (row.value !== billDate) {
- Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.EXPORT, {billDate: row.value});
+ if (row.value !== invoiceStatus) {
+ Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.EXPORT, {billStatus: {sales: row.value, purchase: row.value}});
}
- Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_EXPORT_PURCHASE_BILL_DATE_SELECT.getRoute(policyID));
+ Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR.getRoute(policyID));
},
- [billDate, policyID],
+ [invoiceStatus, policyID],
);
return (
selectExportDate(selection as MenuListItem)}
+ onSelectRow={(selection: SelectorType) => selectPurchaseBillStatus(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]}
From 6de73ea9e4a761f1b217e37fc0fc18f7fb1bd5c3 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 14:09:16 +0530
Subject: [PATCH 047/207] update status name
---
src/languages/en.ts | 4 ++--
src/languages/es.ts | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/languages/en.ts b/src/languages/en.ts
index d2dab5746e11..4d9903af11ee 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2085,9 +2085,9 @@ export default {
label: 'Purchase bill status',
description: 'When exported to Xero what state should purchase bills have.',
values: {
- [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Authorised',
+ [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Awaiting payment',
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Draft',
- [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Submitted',
+ [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Awaiting approval',
},
},
exportPreferredExporterNote: 'This can be any workspace admin, but must be a domain admin if you set different export accounts for individual company cards in domain settings.',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index a83e2f55931d..851ba1528203 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2120,9 +2120,9 @@ export default {
label: 'Estado de la factura de compra',
description: 'When exported to Xero what state should purchase bills have.',
values: {
- [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Autorizado',
+ [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Awaiting payment',
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Borrador',
- [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Enviado',
+ [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Awaiting approval',
},
},
exportPreferredExporterNote:
From 19b1c8c934d025237db5c075593b2824ff7ea226 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 14:10:00 +0530
Subject: [PATCH 048/207] change order
---
src/languages/en.ts | 2 +-
src/languages/es.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 4d9903af11ee..eb5c0a031740 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2085,9 +2085,9 @@ export default {
label: 'Purchase bill status',
description: 'When exported to Xero what state should purchase bills have.',
values: {
- [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Awaiting payment',
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Draft',
[CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Awaiting approval',
+ [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Awaiting payment',
},
},
exportPreferredExporterNote: 'This can be any workspace admin, but must be a domain admin if you set different export accounts for individual company cards in domain settings.',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 851ba1528203..9f3bf41dc255 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2120,9 +2120,9 @@ export default {
label: 'Estado de la factura de compra',
description: 'When exported to Xero what state should purchase bills have.',
values: {
- [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Awaiting payment',
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Borrador',
[CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Awaiting approval',
+ [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Awaiting payment',
},
},
exportPreferredExporterNote:
From c7eb413e1883ebdafb4594edb166e46b146f220d Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 14:10:46 +0530
Subject: [PATCH 049/207] change order
---
src/CONST.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index bd1c61c907d7..6f18b3b7b5c9 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -1303,9 +1303,9 @@ const CONST = {
IMPORT_CUSTOMERS: 'importCustomers',
IMPORT_TAX_RATES: 'importTaxRates',
INVOICE_STATUS: {
- AWAITING_PAYMENT: 'AWT_PAYMENT',
DRAFT: 'DRAFT',
AWAITING_APPROVAL: 'AWT_APPROVAL',
+ AWAITING_PAYMENT: 'AWT_PAYMENT',
},
IMPORT_TRACKING_CATEGORIES: 'importTrackingCategories',
MAPPINGS: 'mappings',
From 2380eb77fbb47f010bd8d404da58a55cf9fde12d Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 14:16:52 +0530
Subject: [PATCH 050/207] handle undefined
---
.../xero/export/XeroPurchaseBillStatusSelectorPage.tsx | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
index dc2119c49d93..52634712220f 100644
--- a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
@@ -1,3 +1,4 @@
+import _ from 'lodash';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
@@ -44,12 +45,15 @@ function XeroPurchaseBillStatusSelectorPage({policy}: WithPolicyConnectionsProps
const selectPurchaseBillStatus = useCallback(
(row: MenuListItem) => {
+ if (_.isEmpty(billStatus)) {
+ return;
+ }
if (row.value !== invoiceStatus) {
- Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.EXPORT, {billStatus: {sales: row.value, purchase: row.value}});
+ Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.EXPORT, {billStatus: {...billStatus, purchase: row.value}});
}
Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR.getRoute(policyID));
},
- [invoiceStatus, policyID],
+ [billStatus, invoiceStatus, policyID],
);
return (
From 4d1a0e0e77406920d7d422ce5447d3413c7eb393 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 16:18:26 +0530
Subject: [PATCH 051/207] Update
src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
Co-authored-by: Manan
---
.../xero/export/XeroPurchaseBillStatusSelectorPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
index 52634712220f..b2406d0a3bc2 100644
--- a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
@@ -73,6 +73,6 @@ function XeroPurchaseBillStatusSelectorPage({policy}: WithPolicyConnectionsProps
);
}
-XeroPurchaseBillStatusSelectorPage.displayName = 'XeroPurchaseBillDateSelectPage';
+XeroPurchaseBillStatusSelectorPage.displayName = 'XeroPurchaseBillStatusSelectorPage';
export default withPolicyConnections(XeroPurchaseBillStatusSelectorPage);
From bf670dcdd0cb8519d5e861a3f7216e48cf8c9fdd Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 10 May 2024 16:19:07 +0530
Subject: [PATCH 052/207] Update src/SCREENS.ts
Co-authored-by: Manan
---
src/SCREENS.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index 5c1589626cc4..67362b29c506 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -250,7 +250,7 @@ const SCREENS = {
XERO_EXPORT: 'Policy_Accounting_Xero_Export',
XERO_EXPORT_PURCHASE_BILL_DATE_SELECT: 'Policy_Accounting_Xero_Export_Purchase_Bill_Date_Select',
XERO_ADVANCED: 'Policy_Accounting_Xero_Advanced',
- XERO_BILL_STATUS_SELECTOR: 'Policy_Accounting_Xero_Export_Bill_Status',
+ XERO_BILL_STATUS_SELECTOR: 'Policy_Accounting_Xero_Export_Bill_Status_Selector',
XERO_INVOICE_ACCOUNT_SELECTOR: 'Policy_Accounting_Xero_Invoice_Account_Selector',
XERO_EXPORT_PREFERRED_EXPORTER_SELECT: 'Workspace_Accounting_Xero_Export_Preferred_Exporter_Select',
XERO_BILL_PAYMENT_ACCOUNT_SELECTOR: 'Policy_Accounting_Xero_Bill_Payment_Account_Selector',
From 1fce4d03095b85069c24f736b29c730e5b32f18f Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Fri, 10 May 2024 16:36:54 +0200
Subject: [PATCH 053/207] add offline support for XeroOrganizationConfiguration
---
.../accounting/PolicyAccountingPage.tsx | 23 ++++++++++++++----
.../XeroOrganizationConfigurationPage.tsx | 24 +++++++++++++------
2 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index fbd5b669fa62..26638b92224e 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -11,7 +11,10 @@ import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
import type {LocaleContextProps} from '@components/LocaleContextProvider';
import type {MenuItemProps} from '@components/MenuItem';
+import MenuItem from '@components/MenuItem';
import MenuItemList from '@components/MenuItemList';
+import type {OfflineWithFeedbackProps} from '@components/OfflineWithFeedback';
+import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Section from '@components/Section';
@@ -39,6 +42,8 @@ import type {PolicyConnectionName} from '@src/types/onyx/Policy';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type IconAsset from '@src/types/utils/IconAsset';
+type MenuItemData = MenuItemProps & {pendingAction?: OfflineWithFeedbackProps['pendingAction']};
+
type PolicyAccountingPageOnyxProps = {
connectionSyncProgress: OnyxEntry;
};
@@ -140,7 +145,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
[translate, policyID, isOffline],
);
- const connectionsMenuItems: MenuItemProps[] = useMemo(() => {
+ const connectionsMenuItems: MenuItemData[] = useMemo(() => {
if (isEmptyObject(policy?.connections) && !isSyncInProgress) {
return accountingIntegrations.map((integration) => {
const integrationData = accountingIntegrationData(integration, policyID, translate);
@@ -211,6 +216,8 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
}
Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.getRoute(policyID, currentXeroOrganization?.id ?? ''));
},
+ pendingAction: policy?.connections?.xero?.config?.pendingFields?.tenantID,
+ brickRoadIndicator: policy?.connections?.xero?.config?.errorFields?.tenantID ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
},
]
: []),
@@ -334,10 +341,16 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
titleStyles={styles.accountSettingsSectionTitle}
childrenStyles={styles.pt5}
>
-
+ {connectionsMenuItems.map((menuItem) => (
+
+
+
+ ))}
{otherIntegrationsItems && (
+
- {translate('workspace.xero.organizationDescription')}
-
+
+ {translate('workspace.xero.organizationDescription')}
+
+
From 943c3fe0773dcf24d15ca7dc85fe2a7b72d60925 Mon Sep 17 00:00:00 2001
From: Mykhailo Kravchenko
Date: Mon, 13 May 2024 17:09:43 +0200
Subject: [PATCH 054/207] fix report name
---
src/libs/ReportUtils.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index fe265cebe321..ddf1386c8892 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -3181,6 +3181,9 @@ function getReportName(report: OnyxEntry, policy: OnyxEntry = nu
if (isMoneyRequestReport(report) || isInvoiceReport(report)) {
formattedName = getMoneyRequestReportName(report, policy);
}
+ if (isInvoiceRoom(report)) {
+ formattedName = getInvoicesChatName(report);
+ }
if (isArchivedRoom(report)) {
formattedName += ` (${Localize.translateLocal('common.archived')})`;
From 98e5cbeb242289550d1174eff11a6c191a3b8b1f Mon Sep 17 00:00:00 2001
From: Mykhailo Kravchenko
Date: Mon, 13 May 2024 17:10:05 +0200
Subject: [PATCH 055/207] fix leave room
---
src/libs/ReportUtils.ts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index ddf1386c8892..c9f70fc5c426 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -5594,6 +5594,10 @@ function temporary_getMoneyRequestOptions(
*/
function canLeaveRoom(report: OnyxEntry, isPolicyEmployee: boolean): boolean {
if (isInvoiceRoom(report)) {
+ if (isArchivedRoom(report)) {
+ return false;
+ }
+
const invoiceReport = getReport(report?.iouReportID ?? '');
if (invoiceReport?.ownerAccountID === currentUserAccountID) {
From ed2b114ac9aa4f80ff4e72399d3506cd6efa00ae Mon Sep 17 00:00:00 2001
From: Mykhailo Kravchenko
Date: Mon, 13 May 2024 17:10:17 +0200
Subject: [PATCH 056/207] fix report name
---
src/libs/ReportUtils.ts | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index c9f70fc5c426..169c90269139 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -3193,10 +3193,6 @@ function getReportName(report: OnyxEntry, policy: OnyxEntry = nu
formattedName = getDisplayNameForParticipant(currentUserAccountID, undefined, undefined, true);
}
- if (isInvoiceRoom(report)) {
- formattedName = getInvoicesChatName(report);
- }
-
if (formattedName) {
return formattedName;
}
From 160aa6c1be4f790f2bd83ebd8303295b1c254814 Mon Sep 17 00:00:00 2001
From: Mykhailo Kravchenko
Date: Mon, 13 May 2024 17:54:24 +0200
Subject: [PATCH 057/207] fix report subtitle
---
src/libs/ReportUtils.ts | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index 169c90269139..5fcc74f92b10 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -3270,7 +3270,15 @@ function getParentNavigationSubtitle(report: OnyxEntry): ParentNavigatio
}
if (isInvoiceReport(report) || isInvoiceRoom(parentReport)) {
- return {reportName: `${getPolicyName(parentReport)} & ${getInvoicePayerName(parentReport)}`};
+ let reportName = `${getPolicyName(parentReport)} & ${getInvoicePayerName(parentReport)}`;
+
+ if (isArchivedRoom(parentReport)) {
+ reportName += ` (${Localize.translateLocal('common.archived')})`;
+ }
+
+ return {
+ reportName,
+ };
}
return {
From 1cf8b940be10727d8ca6f43536a63a7d4ae8430f Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Mon, 13 May 2024 18:12:43 +0200
Subject: [PATCH 058/207] fix PR comments
---
src/CONST.ts | 1 +
.../xero/XeroOrganizationConfigurationPage.tsx | 13 +++++++------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index 8a380188d05e..6e5616eee662 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -1299,6 +1299,7 @@ const CONST = {
XERO_CONFIG: {
AUTO_SYNC: 'autoSync',
SYNC: 'sync',
+ TENANT_ID: 'tenantID',
IMPORT_CUSTOMERS: 'importCustomers',
IMPORT_TAX_RATES: 'importTaxRates',
IMPORT_TRACKING_CATEGORIES: 'importTrackingCategories',
diff --git a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
index e525f82994ff..20a1447ff9a6 100644
--- a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
@@ -18,6 +18,7 @@ import {findCurrentXeroOrganization, getXeroTenants} from '@libs/PolicyUtils';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import withPolicy from '@pages/workspace/withPolicy';
import type {WithPolicyProps} from '@pages/workspace/withPolicy';
+import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
@@ -32,7 +33,8 @@ function XeroOrganizationConfigurationPage({
const {translate} = useLocalize();
const styles = useThemeStyles();
const tenants = useMemo(() => getXeroTenants(policy ?? undefined), [policy]);
- const currentXeroOrganization = findCurrentXeroOrganization(tenants, policy?.connections?.xero?.config?.tenantID);
+ const xeroConfig = policy?.connections?.xero?.config;
+ const currentXeroOrganization = findCurrentXeroOrganization(tenants, xeroConfig?.tenantID);
const policyID = policy?.id ?? '';
@@ -48,7 +50,7 @@ function XeroOrganizationConfigurationPage({
return;
}
- updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, 'tenantID', keyForList);
+ updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.TENANT_ID, keyForList);
Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING.getRoute(policyID));
};
@@ -67,10 +69,9 @@ function XeroOrganizationConfigurationPage({
Policy.clearXeroErrorField(policyID, CONST.XERO_CONFIG.IMPORT_TAX_RATES)}
>
{translate('workspace.xero.organizationDescription')}
Date: Mon, 13 May 2024 18:38:29 +0200
Subject: [PATCH 059/207] fix XeroOrganization bug
---
.../accounting/xero/XeroOrganizationConfigurationPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
index 20a1447ff9a6..582aeac07416 100644
--- a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
@@ -71,7 +71,7 @@ function XeroOrganizationConfigurationPage({
Policy.clearXeroErrorField(policyID, CONST.XERO_CONFIG.IMPORT_TAX_RATES)}
+ onClose={() => Policy.clearXeroErrorField(policyID, CONST.XERO_CONFIG.TENANT_ID)}
>
{translate('workspace.xero.organizationDescription')}
Date: Mon, 13 May 2024 18:48:10 +0200
Subject: [PATCH 060/207] use ConnectionLayout in
XeroOrganizationConfigurationPage
---
.../XeroOrganizationConfigurationPage.tsx | 45 +++++++------------
1 file changed, 17 insertions(+), 28 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
index 582aeac07416..09281a7d477c 100644
--- a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
@@ -1,9 +1,7 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useMemo} from 'react';
-import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import ConnectionLayout from '@components/ConnectionLayout';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
-import ScreenWrapper from '@components/ScreenWrapper';
-import ScrollView from '@components/ScrollView';
import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
@@ -15,7 +13,6 @@ import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import {findCurrentXeroOrganization, getXeroTenants} from '@libs/PolicyUtils';
-import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import withPolicy from '@pages/workspace/withPolicy';
import type {WithPolicyProps} from '@pages/workspace/withPolicy';
import * as Policy from '@userActions/Policy';
@@ -55,35 +52,27 @@ function XeroOrganizationConfigurationPage({
};
return (
-
- Policy.clearXeroErrorField(policyID, CONST.XERO_CONFIG.TENANT_ID)}
>
-
-
-
- Policy.clearXeroErrorField(policyID, CONST.XERO_CONFIG.TENANT_ID)}
- >
- {translate('workspace.xero.organizationDescription')}
-
-
-
-
-
+ {translate('workspace.xero.organizationDescription')}
+
+
+
);
}
From 14589f8379fd04cca733338590e7328c1556ea4a Mon Sep 17 00:00:00 2001
From: nkdengineer
Date: Tue, 14 May 2024 04:59:16 +0700
Subject: [PATCH 061/207] fix create extractAttachments
---
...ntsFromReport.ts => extractAttachments.ts} | 21 ++++-
.../extractAttachmentsFromNote.ts | 80 -------------------
.../AttachmentCarousel/index.native.tsx | 12 +--
.../Attachments/AttachmentCarousel/index.tsx | 12 +--
4 files changed, 30 insertions(+), 95 deletions(-)
rename src/components/Attachments/AttachmentCarousel/{extractAttachmentsFromReport.ts => extractAttachments.ts} (85%)
delete mode 100644 src/components/Attachments/AttachmentCarousel/extractAttachmentsFromNote.ts
diff --git a/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.ts b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts
similarity index 85%
rename from src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.ts
rename to src/components/Attachments/AttachmentCarousel/extractAttachments.ts
index d1185f88ccd5..fcec07a327a0 100644
--- a/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.ts
+++ b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts
@@ -1,8 +1,10 @@
import {Parser as HtmlParser} from 'htmlparser2';
import type {OnyxEntry} from 'react-native-onyx';
+import type {ValueOf} from 'type-fest';
import type {Attachment} from '@components/Attachments/types';
import * as FileUtils from '@libs/fileDownload/FileUtils';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
+import {getReport} from '@libs/ReportUtils';
import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot';
import CONST from '@src/CONST';
import type {ReportAction, ReportActions} from '@src/types/onyx';
@@ -10,8 +12,13 @@ import type {ReportAction, ReportActions} from '@src/types/onyx';
/**
* Constructs the initial component state from report actions
*/
-function extractAttachmentsFromReport(parentReportAction?: OnyxEntry, reportActions?: OnyxEntry) {
- const actions = [...(parentReportAction ? [parentReportAction] : []), ...ReportActionsUtils.getSortedReportActions(Object.values(reportActions ?? {}))];
+function extractAttachments(
+ type: ValueOf,
+ {reportID, accountID, parentReportAction, reportActions}: {reportID?: string; accountID?: number; parentReportAction?: OnyxEntry; reportActions?: OnyxEntry},
+) {
+ const report = getReport(reportID);
+ const privateNotes = report?.privateNotes;
+ const targetNote = privateNotes?.[Number(accountID)]?.note ?? '';
const attachments: Attachment[] = [];
// We handle duplicate image sources by considering the first instance as original. Selecting any duplicate
@@ -71,6 +78,14 @@ function extractAttachmentsFromReport(parentReportAction?: OnyxEntry {
if (!ReportActionsUtils.shouldReportActionBeVisible(action, key) || ReportActionsUtils.isMoneyRequestAction(action)) {
return;
@@ -86,4 +101,4 @@ function extractAttachmentsFromReport(parentReportAction?: OnyxEntry {
- if (name === 'video') {
- const source = tryResolveUrlFromApiRoot(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]);
- if (uniqueSources.has(source)) {
- return;
- }
-
- uniqueSources.add(source);
- const splittedUrl = attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE].split('/');
- attachments.unshift({
- source: tryResolveUrlFromApiRoot(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]),
- isAuthTokenRequired: Boolean(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]),
- file: {name: splittedUrl[splittedUrl.length - 1]},
- duration: Number(attribs[CONST.ATTACHMENT_DURATION_ATTRIBUTE]),
- isReceipt: false,
- hasBeenFlagged: false,
- });
- return;
- }
-
- if (name === 'img' && attribs.src) {
- const expensifySource = attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE];
- const source = tryResolveUrlFromApiRoot(expensifySource || attribs.src);
- if (uniqueSources.has(source)) {
- return;
- }
-
- uniqueSources.add(source);
- let fileName = attribs[CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE] || FileUtils.getFileName(`${source}`);
-
- // Public image URLs might lack a file extension in the source URL, without an extension our
- // AttachmentView fails to recognize them as images and renders fallback content instead.
- // We apply this small hack to add an image extension and ensure AttachmentView renders the image.
- const fileInfo = FileUtils.splitExtensionFromFileName(fileName);
- if (!fileInfo.fileExtension) {
- fileName = `${fileInfo.fileName || 'image'}.jpg`;
- }
-
- // By iterating actions in chronological order and prepending each attachment
- // we ensure correct order of attachments even across actions with multiple attachments.
- attachments.unshift({
- reportActionID: attribs['data-id'],
- source,
- isAuthTokenRequired: Boolean(expensifySource),
- file: {name: fileName},
- isReceipt: false,
- hasBeenFlagged: attribs['data-flagged'] === 'true',
- });
- }
- },
- });
-
- htmlParser.write(targetNote);
- htmlParser.end();
-
- return attachments.reverse();
-}
-
-export default extractAttachmentsFromNote;
diff --git a/src/components/Attachments/AttachmentCarousel/index.native.tsx b/src/components/Attachments/AttachmentCarousel/index.native.tsx
index c97b16ca2988..aad307073c0f 100644
--- a/src/components/Attachments/AttachmentCarousel/index.native.tsx
+++ b/src/components/Attachments/AttachmentCarousel/index.native.tsx
@@ -12,8 +12,7 @@ import variables from '@styles/variables';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import CarouselButtons from './CarouselButtons';
-import extractAttachmentsFromNote from './extractAttachmentsFromNote';
-import extractAttachmentsFromReport from './extractAttachmentsFromReport';
+import extractAttachments from './extractAttachments';
import type {AttachmentCarouselPagerHandle} from './Pager';
import AttachmentCarouselPager from './Pager';
import type {AttachmentCaraouselOnyxProps, AttachmentCarouselProps} from './types';
@@ -32,12 +31,13 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
useEffect(() => {
const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined;
- const attachmentsFromReport = extractAttachmentsFromReport(parentReportAction, reportActions);
- let attachmentsFromNote: Attachment[] = [];
+ let targetAttachments: Attachment[] = [];
if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) {
- attachmentsFromNote = extractAttachmentsFromNote(report.reportID, accountID);
+ targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {reportID: report.reportID, accountID});
+ } else {
+ targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions});
}
- const targetAttachments = type === CONST.ATTACHMENT_TYPE.REPORT ? attachmentsFromReport : attachmentsFromNote;
+
const initialPage = targetAttachments.findIndex(compareImage);
// Dismiss the modal when deleting an attachment during its display in preview.
diff --git a/src/components/Attachments/AttachmentCarousel/index.tsx b/src/components/Attachments/AttachmentCarousel/index.tsx
index 6e8843472377..e4d8df7bc02d 100644
--- a/src/components/Attachments/AttachmentCarousel/index.tsx
+++ b/src/components/Attachments/AttachmentCarousel/index.tsx
@@ -19,8 +19,7 @@ import AttachmentCarouselCellRenderer from './AttachmentCarouselCellRenderer';
import CarouselActions from './CarouselActions';
import CarouselButtons from './CarouselButtons';
import CarouselItem from './CarouselItem';
-import extractAttachmentsFromNote from './extractAttachmentsFromNote';
-import extractAttachmentsFromReport from './extractAttachmentsFromReport';
+import extractAttachments from './extractAttachments';
import type {AttachmentCaraouselOnyxProps, AttachmentCarouselProps, UpdatePageProps} from './types';
import useCarouselArrows from './useCarouselArrows';
@@ -49,12 +48,13 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
useEffect(() => {
const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined;
- const attachmentsFromReport = extractAttachmentsFromReport(parentReportAction, reportActions ?? undefined);
- let attachmentsFromNote: Attachment[] = [];
+ let targetAttachments: Attachment[] = [];
if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) {
- attachmentsFromNote = extractAttachmentsFromNote(report.reportID, accountID);
+ targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {reportID: report.reportID, accountID});
+ } else {
+ targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions: reportActions ?? undefined});
}
- const targetAttachments = type === CONST.ATTACHMENT_TYPE.REPORT ? attachmentsFromReport : attachmentsFromNote;
+
if (isEqual(attachments, targetAttachments)) {
return;
From ac97fb635f5897154ece8de10df879cfa9d24958 Mon Sep 17 00:00:00 2001
From: nkdengineer
Date: Tue, 14 May 2024 05:11:42 +0700
Subject: [PATCH 062/207] fix lint
---
src/components/Attachments/AttachmentCarousel/index.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/components/Attachments/AttachmentCarousel/index.tsx b/src/components/Attachments/AttachmentCarousel/index.tsx
index e4d8df7bc02d..520c054e7c70 100644
--- a/src/components/Attachments/AttachmentCarousel/index.tsx
+++ b/src/components/Attachments/AttachmentCarousel/index.tsx
@@ -54,7 +54,6 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
} else {
targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions: reportActions ?? undefined});
}
-
if (isEqual(attachments, targetAttachments)) {
return;
From 886cc375792da7f9880594bbd5f63c0b3fb0bcb5 Mon Sep 17 00:00:00 2001
From: Mykhailo Kravchenko
Date: Tue, 14 May 2024 11:25:38 +0200
Subject: [PATCH 063/207] add empty line
---
src/libs/ReportUtils.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index 6bbe6939c408..d74c9139b3fe 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -3196,6 +3196,7 @@ function getReportName(report: OnyxEntry, policy: OnyxEntry = nu
if (isMoneyRequestReport(report) || isInvoiceReport(report)) {
formattedName = getMoneyRequestReportName(report, policy);
}
+
if (isInvoiceRoom(report)) {
formattedName = getInvoicesChatName(report);
}
From 8e391e06200d4dfdbb712b6ad1fc9d036652de4e Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Tue, 14 May 2024 14:48:57 +0200
Subject: [PATCH 064/207] fix padding on XeroOrganizationList
---
.../accounting/xero/XeroOrganizationConfigurationPage.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
index 09281a7d477c..9e7a142327c2 100644
--- a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
@@ -66,6 +66,7 @@ function XeroOrganizationConfigurationPage({
>
{translate('workspace.xero.organizationDescription')}
Date: Tue, 14 May 2024 15:07:33 +0200
Subject: [PATCH 065/207] fix safe area insets
---
src/components/ConnectionLayout.tsx | 6 +++++-
.../accounting/xero/XeroOrganizationConfigurationPage.tsx | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/components/ConnectionLayout.tsx b/src/components/ConnectionLayout.tsx
index 8abe0e5759fc..6d17b84bfffa 100644
--- a/src/components/ConnectionLayout.tsx
+++ b/src/components/ConnectionLayout.tsx
@@ -44,6 +44,9 @@ type ConnectionLayoutProps = {
/** Style of the title text */
titleStyle?: StyleProp | undefined;
+ /** Whether to include safe area padding bottom or not */
+ shouldIncludeSafeAreaPaddingBottom?: boolean;
+
/** Whether to use ScrollView or not */
shouldUseScrollView?: boolean;
};
@@ -72,6 +75,7 @@ function ConnectionLayout({
featureName,
contentContainerStyle,
titleStyle,
+ shouldIncludeSafeAreaPaddingBottom,
shouldUseScrollView = true,
}: ConnectionLayoutProps) {
const {translate} = useLocalize();
@@ -95,7 +99,7 @@ function ConnectionLayout({
featureName={featureName}
>
diff --git a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
index 9e7a142327c2..0a331ad4938d 100644
--- a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
@@ -58,6 +58,7 @@ function XeroOrganizationConfigurationPage({
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
+ shouldIncludeSafeAreaPaddingBottom
>
Date: Tue, 14 May 2024 20:06:41 +0530
Subject: [PATCH 066/207] Updates
---
.../SyncPolicyToIntegratedConnectionParams.ts | 6 ------
.../SyncPolicyToQuickbooksOnlineParams.ts | 6 ++++++
src/libs/API/parameters/index.ts | 3 ++-
src/libs/API/types.ts | 4 ++--
src/libs/actions/connections/index.ts | 17 ++++++++++++-----
5 files changed, 22 insertions(+), 14 deletions(-)
delete mode 100644 src/libs/API/parameters/SyncPolicyToIntegratedConnectionParams.ts
create mode 100644 src/libs/API/parameters/SyncPolicyToQuickbooksOnlineParams.ts
diff --git a/src/libs/API/parameters/SyncPolicyToIntegratedConnectionParams.ts b/src/libs/API/parameters/SyncPolicyToIntegratedConnectionParams.ts
deleted file mode 100644
index ad3a926c6b3e..000000000000
--- a/src/libs/API/parameters/SyncPolicyToIntegratedConnectionParams.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-type SyncPolicyToIntegratedConnectionParams = {
- policyID: string;
- idempotencyKey: string;
-};
-
-export default SyncPolicyToIntegratedConnectionParams;
diff --git a/src/libs/API/parameters/SyncPolicyToQuickbooksOnlineParams.ts b/src/libs/API/parameters/SyncPolicyToQuickbooksOnlineParams.ts
new file mode 100644
index 000000000000..b5782c150b9f
--- /dev/null
+++ b/src/libs/API/parameters/SyncPolicyToQuickbooksOnlineParams.ts
@@ -0,0 +1,6 @@
+type SyncPolicyToQuickbooksOnlineParams = {
+ policyID: string;
+ idempotencyKey: string;
+};
+
+export default SyncPolicyToQuickbooksOnlineParams;
diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts
index 34609b6a40ec..55acc24f3ed3 100644
--- a/src/libs/API/parameters/index.ts
+++ b/src/libs/API/parameters/index.ts
@@ -12,7 +12,8 @@ export type {default as BeginSignInParams} from './BeginSignInParams';
export type {default as CloseAccountParams} from './CloseAccountParams';
export type {default as ConnectBankAccountParams} from './ConnectBankAccountParams';
export type {default as ConnectPolicyToAccountingIntegrationParams} from './ConnectPolicyToAccountingIntegrationParams';
-export type {default as SyncPolicyToIntegratedConnectionParams} from './SyncPolicyToIntegratedConnectionParams';
+export type {default as SyncPolicyToQuickbooksOnlineParams} from './SyncPolicyToQuickbooksOnlineParams';
+export type {default as SyncPolicyToXeroParams} from './SyncPolicyToXeroParams';
export type {default as DeleteContactMethodParams} from './DeleteContactMethodParams';
export type {default as DeletePaymentBankAccountParams} from './DeletePaymentBankAccountParams';
export type {default as DeletePaymentCardParams} from './DeletePaymentCardParams';
diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts
index 329ac4294b96..e6c3644f7278 100644
--- a/src/libs/API/types.ts
+++ b/src/libs/API/types.ts
@@ -486,8 +486,8 @@ type ReadCommand = ValueOf;
type ReadCommandParameters = {
[READ_COMMANDS.CONNECT_POLICY_TO_QUICKBOOKS_ONLINE]: Parameters.ConnectPolicyToAccountingIntegrationParams;
[READ_COMMANDS.CONNECT_POLICY_TO_XERO]: Parameters.ConnectPolicyToAccountingIntegrationParams;
- [READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_ONLINE]: Parameters.SyncPolicyToIntegratedConnectionParams;
- [READ_COMMANDS.SYNC_POLICY_TO_XERO]: Parameters.SyncPolicyToIntegratedConnectionParams;
+ [READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_ONLINE]: Parameters.SyncPolicyToQuickbooksOnlineParams;
+ [READ_COMMANDS.SYNC_POLICY_TO_XERO]: Parameters.SyncPolicyToXeroParams;
[READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE]: Parameters.OpenReimbursementAccountPageParams;
[READ_COMMANDS.OPEN_WORKSPACE_VIEW]: Parameters.OpenWorkspaceViewParams;
[READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN]: EmptyObject;
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 95495b19d7c7..8bbdd557bb4d 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -1,7 +1,7 @@
import type {OnyxUpdate} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
-import type {RemovePolicyConnectionParams, SyncPolicyToIntegratedConnectionParams, UpdatePolicyConnectionConfigParams} from '@libs/API/parameters';
+import type {RemovePolicyConnectionParams, SyncPolicyToQuickbooksOnlineParams, SyncPolicyToXeroParams, UpdatePolicyConnectionConfigParams} from '@libs/API/parameters';
import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
@@ -139,10 +139,17 @@ function syncConnection(policyID: string, connectionName: PolicyConnectionName |
value: null,
},
];
- const parameters: SyncPolicyToIntegratedConnectionParams = {
- policyID,
- idempotencyKey: policyID,
- };
+
+ const parameters: SyncPolicyToQuickbooksOnlineParams | SyncPolicyToXeroParams =
+ connectionName === CONST.POLICY.CONNECTIONS.NAME.QBO
+ ? ({
+ policyID,
+ idempotencyKey: policyID,
+ } as SyncPolicyToQuickbooksOnlineParams)
+ : ({
+ policyID,
+ idempotencyKey: policyID,
+ } as SyncPolicyToXeroParams);
API.read(connectionName === CONST.POLICY.CONNECTIONS.NAME.QBO ? READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_ONLINE : READ_COMMANDS.SYNC_POLICY_TO_XERO, parameters, {
optimisticData,
From b5e0200be63cea66fe657bde0b6deae9a69190aa Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Wed, 15 May 2024 11:14:06 +0200
Subject: [PATCH 067/207] fix typescript errors
---
src/pages/workspace/accounting/PolicyAccountingPage.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index d6b47a0dd662..948120d9d2da 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -2,7 +2,6 @@ import React, {useMemo, useRef, useState} from 'react';
import {ActivityIndicator, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
-import AccountingListSkeletonView from '@components/AccountingListSkeletonView';
import CollapsibleSection from '@components/CollapsibleSection';
import ConfirmModal from '@components/ConfirmModal';
import ConnectToQuickbooksOnlineButton from '@components/ConnectToQuickbooksOnlineButton';
@@ -106,7 +105,7 @@ function accountingIntegrationData(
}
}
-function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataFetchNeeded}: PolicyAccountingPageProps) {
+function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccountingPageProps) {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();
From 5dcf980403068b7d5c243116db2caaf05807585d Mon Sep 17 00:00:00 2001
From: tienifr
Date: Wed, 15 May 2024 16:40:08 +0700
Subject: [PATCH 068/207] pass allPolicies from IOUStartPage
---
src/pages/iou/request/IOURequestStartPage.tsx | 10 +++++++++-
src/pages/workspace/AccessOrNotFoundWrapper.tsx | 11 ++++-------
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx
index 661da2c1a97a..c1d55516b433 100644
--- a/src/pages/iou/request/IOURequestStartPage.tsx
+++ b/src/pages/iou/request/IOURequestStartPage.tsx
@@ -1,7 +1,7 @@
import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
-import type {OnyxEntry} from 'react-native-onyx';
+import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import DragAndDropProvider from '@components/DragAndDrop/Provider';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
@@ -42,6 +42,9 @@ type IOURequestStartPageOnyxProps = {
/** The transaction being modified */
transaction: OnyxEntry;
+
+ /** The list of all policies */
+ allPolicies: OnyxCollection;
};
type IOURequestStartPageProps = IOURequestStartPageOnyxProps & WithWritableReportOrNotFoundProps;
@@ -55,6 +58,7 @@ function IOURequestStartPage({
},
selectedTab,
transaction,
+ allPolicies,
}: IOURequestStartPageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
@@ -122,6 +126,7 @@ function IOURequestStartPage({
iouType={iouType}
policyID={policy?.id}
accessVariants={[CONST.IOU.ACCESS_VARIANTS.CREATE]}
+ allPolicies={allPolicies}
>
(
transaction: {
key: ({route}) => `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${route?.params.transactionID ?? 0}`,
},
+ allPolicies: {
+ key: ONYXKEYS.COLLECTION.POLICY,
+ },
})(IOURequestStartPage);
diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
index 4740fb7f5988..73f0264ee308 100644
--- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx
+++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
@@ -41,9 +41,6 @@ type AccessOrNotFoundWrapperOnyxProps = {
/** Indicated whether the report data is loading */
isLoadingReportData: OnyxEntry;
-
- /** The list of all policies */
- allPolicies: OnyxCollection;
};
type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & {
@@ -70,6 +67,9 @@ type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & {
/** The type of the transaction */
iouType?: IOUType;
+
+ /** The list of all policies */
+ allPolicies?: OnyxCollection;
} & Pick;
type PageNotFoundFallbackProps = Pick & {shouldShowFullScreenFallback: boolean};
@@ -115,7 +115,7 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps
const isPageAccessible = accessVariants.reduce((acc, variant) => {
const accessFunction = ACCESS_VARIANTS[variant];
- return acc && accessFunction(policy, report, allPolicies, iouType);
+ return acc && accessFunction(policy, report, allPolicies ?? null, iouType);
}, true);
const isPolicyNotAccessible = isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id;
@@ -150,7 +150,4 @@ export default withOnyx
Date: Wed, 15 May 2024 17:52:28 +0700
Subject: [PATCH 069/207] fix remove redundant attachment type
---
src/CONST.ts | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index 9748c1435b38..fba3a434be80 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -1185,9 +1185,7 @@ const CONST = {
},
ATTACHMENT_TYPE: {
REPORT: 'r',
- REPORT_ACTION: 'a',
NOTE: 'n',
- SINGLE: 's',
},
IMAGE_OBJECT_POSITION: {
From ef91552914dba19f23d1fd7597f5a4860be7d896 Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Wed, 15 May 2024 14:29:31 +0200
Subject: [PATCH 070/207] make taxes read only
---
.../workspace/taxes/WorkspaceEditTaxPage.tsx | 2 +-
.../workspace/taxes/WorkspaceTaxesPage.tsx | 29 ++++++++++---------
2 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/src/pages/workspace/taxes/WorkspaceEditTaxPage.tsx b/src/pages/workspace/taxes/WorkspaceEditTaxPage.tsx
index 8ccff7b4e126..c7f3c50489e7 100644
--- a/src/pages/workspace/taxes/WorkspaceEditTaxPage.tsx
+++ b/src/pages/workspace/taxes/WorkspaceEditTaxPage.tsx
@@ -86,7 +86,7 @@ function WorkspaceEditTaxPage({
{
const isMultiple = selectedTaxesIDs.length > 1;
- const options: Array> = [
- {
+ const options: Array> = [];
+ if (!PolicyUtils.hasAccountingConnections(policy)) {
+ options.push({
icon: Expensicons.Trashcan,
text: isMultiple ? translate('workspace.taxes.actions.deleteMultiple') : translate('workspace.taxes.actions.delete'),
value: CONST.POLICY.TAX_RATES_BULK_ACTION_TYPES.DELETE,
onSelected: () => setIsDeleteModalVisible(true),
- },
- ];
+ });
+ }
// `Disable rates` when at least one enabled rate is selected.
if (selectedTaxesIDs.some((taxID) => !policy?.taxRates?.taxes[taxID]?.isDisabled)) {
@@ -201,18 +202,20 @@ function WorkspaceTaxesPage({
});
}
return options;
- }, [policy?.taxRates?.taxes, selectedTaxesIDs, toggleTaxes, translate]);
+ }, [policy, selectedTaxesIDs, toggleTaxes, translate]);
const headerButtons = !selectedTaxesIDs.length ? (
- Navigation.navigate(ROUTES.WORKSPACE_TAX_CREATE.getRoute(policyID))}
- icon={Expensicons.Plus}
- text={translate('workspace.taxes.addRate')}
- style={[styles.mr3, isSmallScreenWidth && styles.w50]}
- />
+ {!PolicyUtils.hasAccountingConnections(policy) && (
+ Navigation.navigate(ROUTES.WORKSPACE_TAX_CREATE.getRoute(policyID))}
+ icon={Expensicons.Plus}
+ text={translate('workspace.taxes.addRate')}
+ style={[styles.mr3, isSmallScreenWidth && styles.w50]}
+ />
+ )}
Navigation.navigate(ROUTES.WORKSPACE_TAXES_SETTINGS.getRoute(policyID))}
From 191b805c3c71eed16c5f6f0f7c726742dbefe108 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Wed, 15 May 2024 20:34:35 +0530
Subject: [PATCH 071/207] 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 15fcd381e70b..aee9b59a7879 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2130,7 +2130,7 @@ export default {
},
invoiceStatus: {
label: 'Estado de la factura de compra',
- description: 'When exported to Xero what state should purchase bills have.',
+ description: 'Qué estado deben tener las facturas de compra cuando se exportan a Xero.',
values: {
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Borrador',
[CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Awaiting approval',
From 95b787fd7b63de467a432f48a19213482193ad4d Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Wed, 15 May 2024 20:34:44 +0530
Subject: [PATCH 072/207] 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 aee9b59a7879..f80fb79b2b2d 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2133,7 +2133,7 @@ export default {
description: 'Qué estado deben tener las facturas de compra cuando se exportan a Xero.',
values: {
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Borrador',
- [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Awaiting approval',
+ [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Pendiente de aprobación',
[CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Awaiting payment',
},
},
From 2c7c80f67b6e4fe29b0bca72c59840fd66981039 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Wed, 15 May 2024 20:34:57 +0530
Subject: [PATCH 073/207] 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 f80fb79b2b2d..39f8483ea725 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2134,7 +2134,7 @@ export default {
values: {
[CONST.XERO_CONFIG.INVOICE_STATUS.DRAFT]: 'Borrador',
[CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_APPROVAL]: 'Pendiente de aprobación',
- [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Awaiting payment',
+ [CONST.XERO_CONFIG.INVOICE_STATUS.AWAITING_PAYMENT]: 'Pendiente de pago',
},
},
exportPreferredExporterNote:
From d5dfbe69b28cebf7d38ba6aee24da9e9358672b7 Mon Sep 17 00:00:00 2001
From: Sheena Trepanier
Date: Wed, 15 May 2024 13:57:35 -0700
Subject: [PATCH 074/207] Create "Hidden" folder in helpsite repo to house
delisted articles
Per https://expensify.slack.com/archives/C02QSAC6BJ8/p1714064970851609?thread_ts=1713874136.782669&cid=C02QSAC6BJ8 I have been tasked with creating the Hidden folder in the helpsite.
We intend to use this folder to host articles that we do not want to indexed or searchable on the help site. Customers should not be able to access these.
---
docs/Hidden/Instructions | 1 +
1 file changed, 1 insertion(+)
create mode 100644 docs/Hidden/Instructions
diff --git a/docs/Hidden/Instructions b/docs/Hidden/Instructions
new file mode 100644
index 000000000000..940c7ab60d10
--- /dev/null
+++ b/docs/Hidden/Instructions
@@ -0,0 +1 @@
+This folder is used to house articles that should not be live articles on the helpsite.
From 7002203d2a048e93092b80a02cc5bfe220cdaaf6 Mon Sep 17 00:00:00 2001
From: Alex Beaman
Date: Thu, 16 May 2024 09:22:39 +0300
Subject: [PATCH 075/207] Fix values of EXPORTED_* actions
---
src/CONST.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index a983a18e3d6a..98d6116cc23f 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -667,9 +667,9 @@ const CONST = {
DELETED_ACCOUNT: 'DELETEDACCOUNT', // OldDot Action
DISMISSED_VIOLATION: 'DISMISSEDVIOLATION',
DONATION: 'DONATION', // OldDot Action
- EXPORTED_TO_CSV: 'EXPORTEDTOCSV', // OldDot Action
- EXPORTED_TO_INTEGRATION: 'EXPORTEDTOINTEGRATION', // OldDot Action
- EXPORTED_TO_QUICK_BOOKS: 'EXPORTEDTOQUICKBOOKS', // OldDot Action
+ EXPORTED_TO_CSV: 'EXPORTEDCSV', // OldDot Action
+ EXPORTED_TO_INTEGRATION: 'EXPORTINTEGRATION', // OldDot Action
+ EXPORTED_TO_QUICK_BOOKS: 'EXPORTED', // OldDot Action
FORWARDED: 'FORWARDED', // OldDot Action
HOLD: 'HOLD',
HOLD_COMMENT: 'HOLDCOMMENT',
From 68b7551190c1957d03bd6865b0e3c79e56d1c3f4 Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Thu, 16 May 2024 18:14:36 +0200
Subject: [PATCH 076/207] add error message in case of sync failure
---
src/components/MenuItem.tsx | 12 ++-
src/languages/en.ts | 11 +++
src/libs/actions/connections/index.ts | 9 ++-
.../accounting/PolicyAccountingPage.tsx | 80 ++++++++++---------
4 files changed, 72 insertions(+), 40 deletions(-)
diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx
index ad06f9fcb78c..f0bcf7b1f062 100644
--- a/src/components/MenuItem.tsx
+++ b/src/components/MenuItem.tsx
@@ -153,9 +153,15 @@ type MenuItemBaseProps = {
/** Error to display at the bottom of the component */
errorText?: MaybePhraseKey;
+ /** Any additional styles to pass to error text. */
+ errorTextStyle?: StyleProp;
+
/** Hint to display at the bottom of the component */
hintText?: MaybePhraseKey;
+ /** Should the description be shown above the title (instead of the other way around) */
+ shouldShowErrorTextRedDot?: boolean;
+
/** A boolean flag that gives the icon a green fill if true */
success?: boolean;
@@ -308,6 +314,8 @@ function MenuItem(
helperText,
helperTextStyle,
errorText,
+ errorTextStyle,
+ shouldShowErrorTextRedDot,
hintText,
success = false,
focused = false,
@@ -683,9 +691,9 @@ function MenuItem(
{!!errorText && (
)}
{!!hintText && (
diff --git a/src/languages/en.ts b/src/languages/en.ts
index f8d122f3b69a..05359df253d2 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2338,6 +2338,17 @@ export default {
}
}
},
+ syncError: (integration?: ConnectionName): string => {
+ switch (integration) {
+ case CONST.POLICY.CONNECTIONS.NAME.QBO:
+ return "Couldn't connect to QuickBooks Online due to incorrect credentials.";
+ case CONST.POLICY.CONNECTIONS.NAME.XERO:
+ return "Couldn't connect to Xero due to incorrect credentials.";
+ default: {
+ return "Couldn't connect to integration due to incorrect credentials.";
+ }
+ }
+ },
accounts: 'Chart of accounts',
taxes: 'Taxes',
imported: 'Imported',
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 4a501910548b..8d0eda8e5c88 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -1,5 +1,5 @@
import Onyx from 'react-native-onyx';
-import type {OnyxUpdate} from 'react-native-onyx';
+import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx';
import * as API from '@libs/API';
import type {RemovePolicyConnectionParams, UpdateManyPolicyConnectionConfigurationsParams, UpdatePolicyConnectionConfigParams} from '@libs/API/parameters';
import {WRITE_COMMANDS} from '@libs/API/types';
@@ -7,6 +7,7 @@ import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {ConnectionName, Connections, PolicyConnectionName} from '@src/types/onyx/Policy';
+import type Policy from '@src/types/onyx/Policy';
function removePolicyConnection(policyID: string, connectionName: PolicyConnectionName) {
const optimisticData: OnyxUpdate[] = [
@@ -183,4 +184,8 @@ function updateManyPolicyConnectionConfigs, connectionName: PolicyConnectionName): boolean {
+ return policy?.connections?.[connectionName].lastSync?.isSuccessful === false;
+}
+
+export {removePolicyConnection, updatePolicyConnectionConfig, updateManyPolicyConnectionConfigs, hasSynchronizationError};
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index d6ef27c7b00d..4bfa1299a69c 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -2,7 +2,6 @@ import React, {useMemo, useRef, useState} from 'react';
import {ActivityIndicator, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
-import AccountingListSkeletonView from '@components/AccountingListSkeletonView';
import CollapsibleSection from '@components/CollapsibleSection';
import ConfirmModal from '@components/ConfirmModal';
import ConnectToQuickbooksOnlineButton from '@components/ConnectToQuickbooksOnlineButton';
@@ -12,7 +11,10 @@ import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
import type {LocaleContextProps} from '@components/LocaleContextProvider';
import type {MenuItemProps} from '@components/MenuItem';
+import MenuItem from '@components/MenuItem';
import MenuItemList from '@components/MenuItemList';
+import type {OfflineWithFeedbackProps} from '@components/OfflineWithFeedback';
+import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Section from '@components/Section';
@@ -24,7 +26,7 @@ import usePermissions from '@hooks/usePermissions';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
-import {removePolicyConnection} from '@libs/actions/connections';
+import {hasSynchronizationError, removePolicyConnection} from '@libs/actions/connections';
import {syncConnection} from '@libs/actions/connections/QuickBooksOnline';
import {findCurrentXeroOrganization, getCurrentXeroOrganizationName, getXeroTenants} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
@@ -40,6 +42,8 @@ import type {PolicyConnectionName} from '@src/types/onyx/Policy';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type IconAsset from '@src/types/utils/IconAsset';
+type MenuItemData = MenuItemProps & {pendingAction?: OfflineWithFeedbackProps['pendingAction']; errors?: OfflineWithFeedbackProps['errors']};
+
type PolicyAccountingPageOnyxProps = {
connectionSyncProgress: OnyxEntry;
};
@@ -101,7 +105,7 @@ function accountingIntegrationData(
}
}
-function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataFetchNeeded}: PolicyAccountingPageProps) {
+function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccountingPageProps) {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();
@@ -141,7 +145,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
[translate, policyID, isOffline],
);
- const connectionsMenuItems: MenuItemProps[] = useMemo(() => {
+ const connectionsMenuItems: MenuItemData[] = useMemo(() => {
if (isEmptyObject(policy?.connections) && !isSyncInProgress) {
return accountingIntegrations.map((integration) => {
const integrationData = accountingIntegrationData(integration, policyID, translate);
@@ -169,7 +173,9 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
wrapperStyle: [styles.sectionMenuItemTopDescription],
shouldShowRightComponent: true,
title: integrationData?.title,
-
+ errorText: hasSynchronizationError(policy, connectedIntegration) ? translate('workspace.accounting.syncError', connectedIntegration) : undefined,
+ errorTextStyle: {marginTop: 8},
+ shouldShowErrorTextRedDot: true,
description: isSyncInProgress
? translate('workspace.accounting.connections.syncStageName', connectionSyncProgress.stageInProgress)
: translate('workspace.accounting.lastSync'),
@@ -212,6 +218,8 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
}
Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.getRoute(policyID, currentXeroOrganization?.id ?? ''));
},
+ pendingAction: policy?.connections?.xero?.config?.pendingFields?.tenantID,
+ brickRoadIndicator: policy?.connections?.xero?.config?.errorFields?.tenantID ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
},
]
: []),
@@ -245,21 +253,23 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
]),
];
}, [
- connectedIntegration,
- connectionSyncProgress?.stageInProgress,
- currentXeroOrganization,
- currentXeroOrganizationName,
- tenants,
+ policy,
isSyncInProgress,
- overflowMenu,
- policy?.connections,
- policyConnectedToXero,
+ connectedIntegration,
policyID,
- styles,
+ translate,
+ styles.sectionMenuItemTopDescription,
+ styles.popoverMenuIcon,
+ styles.fontWeightNormal,
+ connectionSyncProgress?.stageInProgress,
theme.spinner,
+ overflowMenu,
threeDotsMenuPosition,
- translate,
+ policyConnectedToXero,
+ currentXeroOrganizationName,
+ tenants.length,
accountingIntegrations,
+ currentXeroOrganization?.id,
]);
const otherIntegrationsItems = useMemo(() => {
@@ -336,30 +346,28 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
titleStyles={styles.accountSettingsSectionTitle}
childrenStyles={styles.pt5}
>
- {isConnectionDataFetchNeeded ? (
-
-
-
- ) : (
- <>
+ {connectionsMenuItems.map((menuItem) => (
+
+
+
+ ))}
+ {otherIntegrationsItems && (
+
- {otherIntegrationsItems && (
-
-
-
- )}
- >
+
)}
From 0d284d199197ae3308361b1ebf19bc2984181535 Mon Sep 17 00:00:00 2001
From: Alex Beaman
Date: Thu, 16 May 2024 19:16:36 +0300
Subject: [PATCH 077/207] Fix action name
Co-authored-by: Andrew Rosiclair
---
src/CONST.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index 98d6116cc23f..4e26d9214890 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -667,7 +667,7 @@ const CONST = {
DELETED_ACCOUNT: 'DELETEDACCOUNT', // OldDot Action
DISMISSED_VIOLATION: 'DISMISSEDVIOLATION',
DONATION: 'DONATION', // OldDot Action
- EXPORTED_TO_CSV: 'EXPORTEDCSV', // OldDot Action
+ EXPORTED_TO_CSV: 'EXPORTCSV', // OldDot Action
EXPORTED_TO_INTEGRATION: 'EXPORTINTEGRATION', // OldDot Action
EXPORTED_TO_QUICK_BOOKS: 'EXPORTED', // OldDot Action
FORWARDED: 'FORWARDED', // OldDot Action
From e2f0a629fc2bcbef80f0a95bd3817b4969a9b965 Mon Sep 17 00:00:00 2001
From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com>
Date: Fri, 17 May 2024 01:29:33 +0530
Subject: [PATCH 078/207] Fix lint
---
src/libs/actions/connections/index.ts | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 1093ecaeba7a..8fd406f13231 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -1,7 +1,13 @@
import type {OnyxUpdate} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
-import type {RemovePolicyConnectionParams, SyncPolicyToQuickbooksOnlineParams, SyncPolicyToXeroParams, UpdatePolicyConnectionConfigParams, UpdateManyPolicyConnectionConfigurationsParams} from '@libs/API/parameters';
+import type {
+ RemovePolicyConnectionParams,
+ SyncPolicyToQuickbooksOnlineParams,
+ SyncPolicyToXeroParams,
+ UpdateManyPolicyConnectionConfigurationsParams,
+ UpdatePolicyConnectionConfigParams,
+} from '@libs/API/parameters';
import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
From c010b125a1d45c45b201d9e009a3d91af8b64095 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Fri, 17 May 2024 02:50:41 +0530
Subject: [PATCH 079/207] fix: remove slash from url
---
src/ROUTES.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 2bc04c4a99ea..9f08e7f89dee 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -804,8 +804,8 @@ const ROUTES = {
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories/region` as const,
},
POLICY_ACCOUNTING_XERO_CUSTOMER: {
- route: '/settings/workspaces/:policyID/accounting/xero/import/customers',
- getRoute: (policyID: string) => `/settings/workspaces/${policyID}/accounting/xero/import/customers` as const,
+ route: 'settings/workspaces/:policyID/accounting/xero/import/customers',
+ getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/customers` as const,
},
POLICY_ACCOUNTING_XERO_TAXES: {
route: 'settings/workspaces/:policyID/accounting/xero/import/taxes',
From 1cc105672eaa13643cad56c59630cb5bd730e88e Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Fri, 17 May 2024 10:13:01 +0530
Subject: [PATCH 080/207] fix: route path
---
src/ROUTES.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 9f08e7f89dee..294219a61957 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -816,8 +816,8 @@ const ROUTES = {
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/export` as const,
},
POLICY_ACCOUNTING_XERO_PREFERRED_EXPORTER_SELECT: {
- route: '/settings/workspaces/:policyID/connections/xero/export/preferred-exporter/select',
- getRoute: (policyID: string) => `/settings/workspaces/${policyID}/connections/xero/export/preferred-exporter/select` as const,
+ route: 'settings/workspaces/:policyID/connections/xero/export/preferred-exporter/select',
+ getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/xero/export/preferred-exporter/select` as const,
},
POLICY_ACCOUNTING_XERO_EXPORT_PURCHASE_BILL_DATE_SELECT: {
route: 'settings/workspaces/:policyID/accounting/xero/export/purchase-bill-date-select',
From 6d71b0ebc4b6e06152b3e7d18abacabc67848de9 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Fri, 17 May 2024 22:04:58 +0530
Subject: [PATCH 081/207] fix: change selected text
---
src/pages/workspace/accounting/xero/XeroImportPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/accounting/xero/XeroImportPage.tsx b/src/pages/workspace/accounting/xero/XeroImportPage.tsx
index 0d9b96c46003..86fdcbf7ff92 100644
--- a/src/pages/workspace/accounting/xero/XeroImportPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroImportPage.tsx
@@ -37,7 +37,7 @@ function XeroImportPage({policy}: WithPolicyProps) {
description: translate('workspace.xero.trackingCategories'),
action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES.getRoute(policyID)),
hasError: !!errorFields?.importTrackingCategories,
- title: importTrackingCategories ? translate('workspace.accounting.importTypes.TAG') : translate('workspace.xero.notImported'),
+ title: importTrackingCategories ? translate('workspace.accounting.imported') : translate('workspace.xero.notImported'),
pendingAction: pendingFields?.importTrackingCategories,
},
{
From 4115f7e94a407d6fe6c1f614bc995effb535f2be Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Fri, 17 May 2024 22:05:13 +0530
Subject: [PATCH 082/207] fix: added padding
---
.../accounting/xero/XeroTrackingCategoryConfigurationPage.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
index 75323337cbed..2742060eaa2b 100644
--- a/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
@@ -63,6 +63,7 @@ function XeroTrackingCategoryConfigurationPage({policy}: WithPolicyProps) {
title={translate('workspace.accounting.import')}
switchAccessibilityLabel={translate('workspace.xero.trackingCategories')}
isActive={isSwitchOn}
+ wrapperStyle={styles.mv3}
onToggle={() =>
Connections.updatePolicyConnectionConfig(
policyID,
From 73524a9331f39353f4dabbe2dea8195a453848a7 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Fri, 17 May 2024 22:05:26 +0530
Subject: [PATCH 083/207] fix: default selection
---
.../accounting/xero/XeroMapCostCentersToConfigurationPage.tsx | 1 +
.../accounting/xero/XeroMapRegionsToConfigurationPage.tsx | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage.tsx
index b4f0fe04f6ce..1d1307a0d31c 100644
--- a/src/pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage.tsx
@@ -61,6 +61,7 @@ function XeroMapCostCentersToConfigurationPage({policy}: WithPolicyProps) {
sections={[{data: optionsList}]}
ListItem={RadioListItem}
onSelectRow={updateMapping}
+ initiallyFocusedOptionKey={optionsList.find((option) => option.isSelected)?.keyForList}
/>
);
diff --git a/src/pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage.tsx
index bb5870da8fc3..5c97de36d353 100644
--- a/src/pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage.tsx
@@ -60,6 +60,7 @@ function XeroMapRegionsToConfigurationPage({policy}: WithPolicyProps) {
sections={[{data: optionsList}]}
ListItem={RadioListItem}
onSelectRow={updateMapping}
+ initiallyFocusedOptionKey={optionsList.find((option) => option.isSelected)?.keyForList}
/>
);
From 636cbf1b62e80d584c241dc90079d0d31a1eaee8 Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Fri, 17 May 2024 22:06:57 +0530
Subject: [PATCH 084/207] hide policy guides as exporters
---
.../XeroPreferredExporterSelectPage.tsx | 32 ++++++++++++-------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx
index d56eb3476863..ce79ded13f9d 100644
--- a/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx
@@ -5,10 +5,11 @@ import RadioListItem from '@components/SelectionList/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
+import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections';
-import {getAdminEmployees} from '@libs/PolicyUtils';
+import {getAdminEmployees, isExpensifyTeam} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
@@ -25,6 +26,7 @@ function XeroPreferredExporterSelectPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
const policyOwner = policy?.owner ?? '';
const exporters = getAdminEmployees(policy);
+ const {login: currentUserLogin} = useCurrentUserPersonalDetails();
const policyID = policy?.id ?? '';
const data: CardListItem[] = useMemo(() => {
@@ -38,18 +40,26 @@ function XeroPreferredExporterSelectPage({policy}: WithPolicyConnectionsProps) {
},
];
}
- return exporters?.reduce((vendors, vendor) => {
- if (vendor.email) {
- vendors.push({
- value: vendor.email,
- text: vendor.email,
- keyForList: vendor.email,
- isSelected: exportConfiguration?.exporter === vendor.email,
- });
+
+ return exporters?.reduce((options, exporter) => {
+ if (!exporter.email) {
+ return options;
+ }
+
+ // Don't show guides if the current user is not a guide themselves or an Expensify employee
+ if (isExpensifyTeam(exporter.email) && !isExpensifyTeam(policyOwner) && !isExpensifyTeam(currentUserLogin)) {
+ return options;
}
- return vendors;
+
+ options.push({
+ value: exporter.email,
+ text: exporter.email,
+ keyForList: exporter.email,
+ isSelected: exportConfiguration?.exporter === exporter.email,
+ });
+ return options;
}, []);
- }, [exportConfiguration, exporters, policyOwner]);
+ }, [exportConfiguration, exporters, policyOwner, currentUserLogin]);
const selectExporter = useCallback(
(row: CardListItem) => {
From acbeb1b60b2fcdc9f16a5197044af7f03ff71a91 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Fri, 17 May 2024 23:10:28 +0530
Subject: [PATCH 085/207] fix: select first item in list
---
.../workspace/accounting/xero/advanced/XeroAdvancedPage.tsx | 2 +-
.../accounting/xero/export/XeroExportConfigurationPage.tsx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
index de6e62b4baa3..1fe445ea2fe6 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
@@ -28,7 +28,7 @@ function XeroAdvancedPage({policy}: WithPolicyConnectionsProps) {
const getSelectedAccountName = useMemo(
() => (accountID: string) => {
const selectedAccount = (bankAccounts ?? []).find((bank) => bank.id === accountID);
- return selectedAccount?.name ?? '';
+ return selectedAccount?.name ?? bankAccounts?.[0]?.name ?? '';
},
[bankAccounts],
);
diff --git a/src/pages/workspace/accounting/xero/export/XeroExportConfigurationPage.tsx b/src/pages/workspace/accounting/xero/export/XeroExportConfigurationPage.tsx
index fd0213ed0f89..487001f69332 100644
--- a/src/pages/workspace/accounting/xero/export/XeroExportConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroExportConfigurationPage.tsx
@@ -26,7 +26,7 @@ function XeroExportConfigurationPage({policy}: WithPolicyConnectionsProps) {
const {bankAccounts} = policy?.connections?.xero?.data ?? {};
const selectedBankAccountName = useMemo(() => {
const selectedAccount = (bankAccounts ?? []).find((bank) => bank.id === exportConfiguration?.nonReimbursableAccount);
- return selectedAccount?.name ?? '';
+ return selectedAccount?.name ?? bankAccounts?.[0]?.name ?? '';
}, [bankAccounts, exportConfiguration?.nonReimbursableAccount]);
const currentXeroOrganizationName = useMemo(() => getCurrentXeroOrganizationName(policy ?? undefined), [policy]);
From 89a68ba0af446ff37a6fd9a3427582e0bfedd2fc Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Fri, 17 May 2024 23:10:44 +0530
Subject: [PATCH 086/207] fix: default select first item
---
.../xero/export/XeroBankAccountSelectPage.tsx | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
index 897ed0b37d78..96ad0a904645 100644
--- a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
@@ -22,16 +22,16 @@ function XeroBankAccountSelectPage({policy}: WithPolicyConnectionsProps) {
const {nonReimbursableAccount: nonReimbursableAccountID} = policy?.connections?.xero?.config.export ?? {};
- const xeroSelectorOptions = useMemo(
- () =>
- (bankAccounts ?? []).map(({id, name}) => ({
- value: id,
- text: name,
- keyForList: id,
- isSelected: nonReimbursableAccountID === id,
- })),
- [nonReimbursableAccountID, bankAccounts],
- );
+ const xeroSelectorOptions = useMemo(() => {
+ const isMatchFound = bankAccounts?.some(({id}) => id === nonReimbursableAccountID);
+
+ return (bankAccounts ?? []).map(({id, name}, index) => ({
+ value: id,
+ text: name,
+ keyForList: id,
+ isSelected: isMatchFound ? nonReimbursableAccountID === id : index === 0,
+ }));
+ }, [nonReimbursableAccountID, bankAccounts]);
const listHeaderComponent = useMemo(
() => (
From 77cedd2da7b8cfa3187f8f054cbad6ea90ca344e Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Fri, 17 May 2024 23:14:25 +0530
Subject: [PATCH 087/207] fix: default select first item
---
.../XeroBillPaymentAccountSelectorPage.tsx | 20 +++++++++----------
.../XeroInvoiceAccountSelectorPage.tsx | 20 +++++++++----------
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
index 11ac106f516c..3c7ad124b8d1 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
@@ -22,16 +22,16 @@ function XeroBillPaymentAccountSelectorPage({policy}: WithPolicyConnectionsProps
const {reimbursementAccountID, syncReimbursedReports} = policy?.connections?.xero?.config.sync ?? {};
- const xeroSelectorOptions = useMemo(
- () =>
- (bankAccounts ?? []).map(({id, name}) => ({
- value: id,
- text: name,
- keyForList: id,
- isSelected: reimbursementAccountID === id,
- })),
- [reimbursementAccountID, bankAccounts],
- );
+ const xeroSelectorOptions = useMemo(() => {
+ const isMatchFound = bankAccounts?.some(({id}) => id === reimbursementAccountID);
+
+ return (bankAccounts ?? []).map(({id, name}, index) => ({
+ value: id,
+ text: name,
+ keyForList: id,
+ isSelected: isMatchFound ? reimbursementAccountID === id : index === 0,
+ }));
+ }, [reimbursementAccountID, bankAccounts]);
const listHeaderComponent = useMemo(
() => (
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
index ba7749fef4f2..86a627e74bfe 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
@@ -22,16 +22,16 @@ function XeroInvoiceAccountSelectorPage({policy}: WithPolicyConnectionsProps) {
const {invoiceCollectionsAccountID, syncReimbursedReports} = policy?.connections?.xero?.config.sync ?? {};
- const xeroSelectorOptions = useMemo(
- () =>
- (bankAccounts ?? []).map(({id, name}) => ({
- value: id,
- text: name,
- keyForList: id,
- isSelected: invoiceCollectionsAccountID === id,
- })),
- [invoiceCollectionsAccountID, bankAccounts],
- );
+ const xeroSelectorOptions = useMemo(() => {
+ const isMatchFound = bankAccounts?.some(({id}) => id === invoiceCollectionsAccountID);
+
+ return (bankAccounts ?? []).map(({id, name}, index) => ({
+ value: id,
+ text: name,
+ keyForList: id,
+ isSelected: isMatchFound ? invoiceCollectionsAccountID === id : index === 0,
+ }));
+ }, [invoiceCollectionsAccountID, bankAccounts]);
const listHeaderComponent = useMemo(
() => (
From 70e1945201fc2d5830ec086563e02aa1ea6e9412 Mon Sep 17 00:00:00 2001
From: tienifr
Date: Mon, 20 May 2024 10:07:04 +0700
Subject: [PATCH 088/207] Console error shows up when opening Preferred
exporter
---
src/ROUTES.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 2bc04c4a99ea..294219a61957 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -804,8 +804,8 @@ const ROUTES = {
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories/region` as const,
},
POLICY_ACCOUNTING_XERO_CUSTOMER: {
- route: '/settings/workspaces/:policyID/accounting/xero/import/customers',
- getRoute: (policyID: string) => `/settings/workspaces/${policyID}/accounting/xero/import/customers` as const,
+ route: 'settings/workspaces/:policyID/accounting/xero/import/customers',
+ getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/customers` as const,
},
POLICY_ACCOUNTING_XERO_TAXES: {
route: 'settings/workspaces/:policyID/accounting/xero/import/taxes',
@@ -816,8 +816,8 @@ const ROUTES = {
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/export` as const,
},
POLICY_ACCOUNTING_XERO_PREFERRED_EXPORTER_SELECT: {
- route: '/settings/workspaces/:policyID/connections/xero/export/preferred-exporter/select',
- getRoute: (policyID: string) => `/settings/workspaces/${policyID}/connections/xero/export/preferred-exporter/select` as const,
+ route: 'settings/workspaces/:policyID/connections/xero/export/preferred-exporter/select',
+ getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/xero/export/preferred-exporter/select` as const,
},
POLICY_ACCOUNTING_XERO_EXPORT_PURCHASE_BILL_DATE_SELECT: {
route: 'settings/workspaces/:policyID/accounting/xero/export/purchase-bill-date-select',
From ecdeaf425ff8bc1639828422ce168149de1fa399 Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Mon, 20 May 2024 10:47:41 +0200
Subject: [PATCH 089/207] add translations
---
src/languages/es.ts | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 536a6182f393..20450b43d647 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2342,6 +2342,17 @@ export default {
}
}
},
+ syncError: (integration?: ConnectionName): string => {
+ switch (integration) {
+ case CONST.POLICY.CONNECTIONS.NAME.QBO:
+ return 'No se pudo conectar a QuickBooks Online debido a credenciales incorrectas.';
+ case CONST.POLICY.CONNECTIONS.NAME.XERO:
+ return 'No se pudo conectar a Xero debido a credenciales incorrectas.';
+ default: {
+ return 'No se pudo conectar a la integración debido a credenciales incorrectas.';
+ }
+ }
+ },
accounts: 'Plan de cuentas',
taxes: 'Impuestos',
imported: 'Importado',
From e87d711b2e5f47e886a18b66b7dd6b777f60680c Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Mon, 20 May 2024 10:56:39 +0200
Subject: [PATCH 090/207] delete unrelated changes
---
src/pages/workspace/accounting/PolicyAccountingPage.tsx | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index 4bfa1299a69c..f0868ad4e15d 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -218,8 +218,6 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
}
Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.getRoute(policyID, currentXeroOrganization?.id ?? ''));
},
- pendingAction: policy?.connections?.xero?.config?.pendingFields?.tenantID,
- brickRoadIndicator: policy?.connections?.xero?.config?.errorFields?.tenantID ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
},
]
: []),
From 27972bffa735dec62973c7164e5d3530cf0fb4f9 Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Mon, 20 May 2024 11:12:17 +0200
Subject: [PATCH 091/207] fix PR comments
---
src/components/MenuItem.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx
index f0bcf7b1f062..1365824e8eb0 100644
--- a/src/components/MenuItem.tsx
+++ b/src/components/MenuItem.tsx
@@ -159,7 +159,7 @@ type MenuItemBaseProps = {
/** Hint to display at the bottom of the component */
hintText?: MaybePhraseKey;
- /** Should the description be shown above the title (instead of the other way around) */
+ /** Should the error text red dot indicator be shown */
shouldShowErrorTextRedDot?: boolean;
/** A boolean flag that gives the icon a green fill if true */
From 9665c0f8b0112696b9648d10e43a1336291b3d25 Mon Sep 17 00:00:00 2001
From: Hans
Date: Mon, 20 May 2024 17:07:33 +0700
Subject: [PATCH 092/207] Fix: QBO briefly shows when syncing Xero
---
src/CONST.ts | 3 ++-
src/languages/en.ts | 4 +++-
src/languages/es.ts | 6 ++++--
src/libs/actions/connections/index.ts | 7 ++++---
4 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index 99b9cc2c50e1..7bf1d38510cd 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -1777,7 +1777,8 @@ const CONST = {
XERO: 'xero',
},
SYNC_STAGE_NAME: {
- STARTING_IMPORT: 'startingImport',
+ STARTING_IMPORT_QBO: 'startingImportQBO',
+ STARTING_IMPORT_XERO: 'startingImportXero',
QBO_IMPORT_MAIN: 'quickbooksOnlineImportMain',
QBO_IMPORT_CUSTOMERS: 'quickbooksOnlineImportCustomers',
QBO_IMPORT_EMPLOYEES: 'quickbooksOnlineImportEmployees',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index f5bb3f67fadc..68c1d4120385 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2396,7 +2396,9 @@ export default {
return 'Checking QuickBooks Online connection';
case 'quickbooksOnlineImportMain':
return 'Importing your QuickBooks Online data';
- case 'startingImport':
+ case 'startingImportXero':
+ return 'Importing your Xero data';
+ case 'startingImportQBO':
return 'Importing your QuickBooks Online data';
case 'quickbooksOnlineSyncTitle':
return 'Synchronizing QuickBooks Online data';
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 1f0722254404..7183a466a0d4 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2400,8 +2400,10 @@ export default {
return 'Revisando conexión a QuickBooks Online';
case 'quickbooksOnlineImportMain':
return 'Importando datos desde QuickBooks Online';
- case 'startingImport':
- return 'Importando datos desde QuickBooks Online';
+ case 'startingImportXero':
+ return 'Importing your Xero data';
+ case 'startingImportQBO':
+ return 'Importing your QuickBooks Online data';
case 'quickbooksOnlineSyncTitle':
return 'Sincronizando datos desde QuickBooks Online';
case 'quickbooksOnlineSyncLoadData':
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 8fd406f13231..ee858a290849 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -128,12 +128,13 @@ function updatePolicyConnectionConfig
Date: Mon, 20 May 2024 17:08:15 +0700
Subject: [PATCH 093/207] fix prettier
---
src/libs/actions/connections/index.ts | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index ee858a290849..424016af38af 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -147,16 +147,15 @@ function syncConnection(policyID: string, connectionName: PolicyConnectionName |
},
];
- const parameters: SyncPolicyToQuickbooksOnlineParams | SyncPolicyToXeroParams =
- isQBOConnection
- ? ({
- policyID,
- idempotencyKey: policyID,
- } as SyncPolicyToQuickbooksOnlineParams)
- : ({
- policyID,
- idempotencyKey: policyID,
- } as SyncPolicyToXeroParams);
+ const parameters: SyncPolicyToQuickbooksOnlineParams | SyncPolicyToXeroParams = isQBOConnection
+ ? ({
+ policyID,
+ idempotencyKey: policyID,
+ } as SyncPolicyToQuickbooksOnlineParams)
+ : ({
+ policyID,
+ idempotencyKey: policyID,
+ } as SyncPolicyToXeroParams);
API.read(isQBOConnection ? READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_ONLINE : READ_COMMANDS.SYNC_POLICY_TO_XERO, parameters, {
optimisticData,
From c444695c14feeab15fafa082dc81ac2155a696cf Mon Sep 17 00:00:00 2001
From: Hans
Date: Mon, 20 May 2024 17:11:45 +0700
Subject: [PATCH 094/207] update Spanish translation
---
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 7183a466a0d4..ef2e27275775 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2401,9 +2401,9 @@ export default {
case 'quickbooksOnlineImportMain':
return 'Importando datos desde QuickBooks Online';
case 'startingImportXero':
- return 'Importing your Xero data';
+ return 'Importando datos desde Xero';
case 'startingImportQBO':
- return 'Importing your QuickBooks Online data';
+ return 'Importando datos desde QuickBooks Online';
case 'quickbooksOnlineSyncTitle':
return 'Sincronizando datos desde QuickBooks Online';
case 'quickbooksOnlineSyncLoadData':
From 8f7139b45a2108caa14d6f5b761e634422463ddb Mon Sep 17 00:00:00 2001
From: Mykhailo Kravchenko
Date: Mon, 20 May 2024 12:17:54 +0200
Subject: [PATCH 095/207] fix leave option for archived invoice room
---
src/libs/ReportUtils.ts | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index 4ebf09ad4049..458196329eb5 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -5606,28 +5606,25 @@ function temporary_getMoneyRequestOptions(
* Invoice sender, invoice receiver and auto-invited admins cannot leave
*/
function canLeaveInvoiceRoom(report: OnyxEntry): boolean {
- if (!isInvoiceRoom(report)) {
+ if (!report || !report?.invoiceReceiver) {
return false;
}
- const invoiceReport = getReport(report?.iouReportID ?? '');
-
- if (invoiceReport?.ownerAccountID === currentUserAccountID) {
- return false;
- }
-
- if (invoiceReport?.managerID === currentUserAccountID) {
+ if (report?.statusNum === CONST.REPORT.STATUS_NUM.CLOSED) {
return false;
}
- const isSenderPolicyAdmin = getPolicy(report?.policyID)?.role === CONST.POLICY.ROLE.ADMIN;
+ const isSenderPolicyAdmin = getPolicy(report.policyID)?.role === CONST.POLICY.ROLE.ADMIN;
if (isSenderPolicyAdmin) {
return false;
}
- const isReceiverPolicyAdmin =
- report?.invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.BUSINESS ? getPolicy(report?.invoiceReceiver?.policyID)?.role === CONST.POLICY.ROLE.ADMIN : false;
+ if (report.invoiceReceiver.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL) {
+ return report?.invoiceReceiver?.accountID !== currentUserAccountID;
+ }
+
+ const isReceiverPolicyAdmin = getPolicy(report.invoiceReceiver.policyID)?.role === CONST.POLICY.ROLE.ADMIN;
if (isReceiverPolicyAdmin) {
return false;
@@ -6575,8 +6572,8 @@ function canLeaveChat(report: OnyxEntry, policy: OnyxEntry): boo
return false;
}
- if (canLeaveInvoiceRoom(report)) {
- return true;
+ if (isInvoiceRoom(report)) {
+ return canLeaveInvoiceRoom(report);
}
return (isChatThread(report) && !!report?.notificationPreference?.length) || isUserCreatedPolicyRoom(report) || isNonAdminOrOwnerOfPolicyExpenseChat(report, policy);
From ef5d777a0a3ae95f6923998605cee9f11e767e7b Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Mon, 20 May 2024 17:31:20 +0200
Subject: [PATCH 096/207] fix connections lastSync unsafe access
---
src/libs/actions/connections/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 2882d9449ccc..0882d1a4ed67 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -233,7 +233,7 @@ function updateManyPolicyConnectionConfigs, connectionName: PolicyConnectionName): boolean {
- return policy?.connections?.[connectionName].lastSync?.isSuccessful === false;
+ return policy?.connections?.[connectionName]?.lastSync?.isSuccessful === false;
}
export {removePolicyConnection, updatePolicyConnectionConfig, updateManyPolicyConnectionConfigs, hasSynchronizationError, syncConnection};
From f3cbb216531481749a9683aa69ba4998e21504be Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Tue, 21 May 2024 14:05:14 +0530
Subject: [PATCH 097/207] refactor: move bank selection to utils
---
src/libs/PolicyUtils.ts | 14 ++++++++++++++
.../XeroBillPaymentAccountSelectorPage.tsx | 16 +++-------------
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts
index 6a26b1a6cfc2..17202662e769 100644
--- a/src/libs/PolicyUtils.ts
+++ b/src/libs/PolicyUtils.ts
@@ -7,6 +7,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Policy, PolicyCategories, PolicyEmployeeList, PolicyTagList, PolicyTags, TaxRate} from '@src/types/onyx';
import type {PolicyFeatureName, Rate, Tenant} from '@src/types/onyx/Policy';
+import type {SelectorType} from '@components/SelectionScreen';
import type PolicyEmployee from '@src/types/onyx/PolicyEmployee';
import type {EmptyObject} from '@src/types/utils/EmptyObject';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
@@ -408,6 +409,18 @@ function getCurrentXeroOrganizationName(policy: Policy | undefined): string | un
return findCurrentXeroOrganization(getXeroTenants(policy), policy?.connections?.xero?.config?.tenantID)?.name;
}
+function getXeroBankAccountsWithDefaultSelect(policy: Policy | undefined, selectedBankAccountId: string | undefined): SelectorType[] {
+ const bankAccounts = policy?.connections?.xero?.data?.bankAccounts ?? [];
+ const isMatchFound = bankAccounts?.some(({id}) => id === selectedBankAccountId);
+
+ return (bankAccounts ?? []).map(({id, name}, index) => ({
+ value: id,
+ text: name,
+ keyForList: id,
+ isSelected: isMatchFound ? selectedBankAccountId === id : index === 0,
+ }));
+}
+
export {
canEditTaxRate,
extractPolicyIDFromPath,
@@ -456,6 +469,7 @@ export {
getXeroTenants,
findCurrentXeroOrganization,
getCurrentXeroOrganizationName,
+ getXeroBankAccountsWithDefaultSelect
};
export type {MemberEmailsToAccountIDs};
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
index 3c7ad124b8d1..3b61c74067b0 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
@@ -12,26 +12,16 @@ import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnec
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
+import { getXeroBankAccountsWithDefaultSelect } from '@libs/PolicyUtils';
function XeroBillPaymentAccountSelectorPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const policyID = policy?.id ?? '';
- const {bankAccounts} = policy?.connections?.xero?.data ?? {};
-
+
const {reimbursementAccountID, syncReimbursedReports} = policy?.connections?.xero?.config.sync ?? {};
-
- const xeroSelectorOptions = useMemo(() => {
- const isMatchFound = bankAccounts?.some(({id}) => id === reimbursementAccountID);
-
- return (bankAccounts ?? []).map(({id, name}, index) => ({
- value: id,
- text: name,
- keyForList: id,
- isSelected: isMatchFound ? reimbursementAccountID === id : index === 0,
- }));
- }, [reimbursementAccountID, bankAccounts]);
+ const xeroSelectorOptions = useMemo(() => getXeroBankAccountsWithDefaultSelect(policy ?? undefined, reimbursementAccountID), [reimbursementAccountID, policy]);
const listHeaderComponent = useMemo(
() => (
From e143cfb8ad36c09dd7a18667a6db0177f88b6c47 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Tue, 21 May 2024 14:06:48 +0530
Subject: [PATCH 098/207] refactor: replace with utils
---
.../advanced/XeroInvoiceAccountSelectorPage.tsx | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
index 86a627e74bfe..cca34a8e9cc0 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
@@ -12,26 +12,16 @@ import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnec
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
+import { getXeroBankAccountsWithDefaultSelect } from '@libs/PolicyUtils';
function XeroInvoiceAccountSelectorPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const policyID = policy?.id ?? '';
- const {bankAccounts} = policy?.connections?.xero?.data ?? {};
const {invoiceCollectionsAccountID, syncReimbursedReports} = policy?.connections?.xero?.config.sync ?? {};
-
- const xeroSelectorOptions = useMemo(() => {
- const isMatchFound = bankAccounts?.some(({id}) => id === invoiceCollectionsAccountID);
-
- return (bankAccounts ?? []).map(({id, name}, index) => ({
- value: id,
- text: name,
- keyForList: id,
- isSelected: isMatchFound ? invoiceCollectionsAccountID === id : index === 0,
- }));
- }, [invoiceCollectionsAccountID, bankAccounts]);
+ const xeroSelectorOptions = useMemo(() => getXeroBankAccountsWithDefaultSelect(policy ?? undefined, invoiceCollectionsAccountID), [invoiceCollectionsAccountID, policy]);
const listHeaderComponent = useMemo(
() => (
From 92cd9c6d3601d5e853067700b4dd6a83ed6b2b80 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Tue, 21 May 2024 14:08:02 +0530
Subject: [PATCH 099/207] refactor: replace with utils
---
.../xero/export/XeroBankAccountSelectPage.tsx | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
index 96ad0a904645..e35468e0848e 100644
--- a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
@@ -12,26 +12,16 @@ import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnec
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
+import { getXeroBankAccountsWithDefaultSelect } from '@libs/PolicyUtils';
function XeroBankAccountSelectPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const policyID = policy?.id ?? '';
- const {bankAccounts} = policy?.connections?.xero?.data ?? {};
-
+
const {nonReimbursableAccount: nonReimbursableAccountID} = policy?.connections?.xero?.config.export ?? {};
-
- const xeroSelectorOptions = useMemo(() => {
- const isMatchFound = bankAccounts?.some(({id}) => id === nonReimbursableAccountID);
-
- return (bankAccounts ?? []).map(({id, name}, index) => ({
- value: id,
- text: name,
- keyForList: id,
- isSelected: isMatchFound ? nonReimbursableAccountID === id : index === 0,
- }));
- }, [nonReimbursableAccountID, bankAccounts]);
+ const xeroSelectorOptions = useMemo(() => getXeroBankAccountsWithDefaultSelect(policy ?? undefined, nonReimbursableAccountID), [nonReimbursableAccountID, policy]);
const listHeaderComponent = useMemo(
() => (
From a66f8cbbe7cd82e6a080058c704f5dae4452efb8 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Tue, 21 May 2024 14:09:26 +0530
Subject: [PATCH 100/207] refactor: lint fixes
---
src/libs/PolicyUtils.ts | 6 +++---
.../xero/advanced/XeroBillPaymentAccountSelectorPage.tsx | 4 ++--
.../xero/advanced/XeroInvoiceAccountSelectorPage.tsx | 2 +-
.../accounting/xero/export/XeroBankAccountSelectPage.tsx | 6 +++---
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts
index 17202662e769..227e86d6a031 100644
--- a/src/libs/PolicyUtils.ts
+++ b/src/libs/PolicyUtils.ts
@@ -2,12 +2,12 @@ import Str from 'expensify-common/lib/str';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
+import type {SelectorType} from '@components/SelectionScreen';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Policy, PolicyCategories, PolicyEmployeeList, PolicyTagList, PolicyTags, TaxRate} from '@src/types/onyx';
import type {PolicyFeatureName, Rate, Tenant} from '@src/types/onyx/Policy';
-import type {SelectorType} from '@components/SelectionScreen';
import type PolicyEmployee from '@src/types/onyx/PolicyEmployee';
import type {EmptyObject} from '@src/types/utils/EmptyObject';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
@@ -419,7 +419,7 @@ function getXeroBankAccountsWithDefaultSelect(policy: Policy | undefined, select
keyForList: id,
isSelected: isMatchFound ? selectedBankAccountId === id : index === 0,
}));
-}
+}
export {
canEditTaxRate,
@@ -469,7 +469,7 @@ export {
getXeroTenants,
findCurrentXeroOrganization,
getCurrentXeroOrganizationName,
- getXeroBankAccountsWithDefaultSelect
+ getXeroBankAccountsWithDefaultSelect,
};
export type {MemberEmailsToAccountIDs};
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
index 3b61c74067b0..baeab09cac29 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
@@ -8,18 +8,18 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections';
import Navigation from '@libs/Navigation/Navigation';
+import {getXeroBankAccountsWithDefaultSelect} from '@libs/PolicyUtils';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
-import { getXeroBankAccountsWithDefaultSelect } from '@libs/PolicyUtils';
function XeroBillPaymentAccountSelectorPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const policyID = policy?.id ?? '';
-
+
const {reimbursementAccountID, syncReimbursedReports} = policy?.connections?.xero?.config.sync ?? {};
const xeroSelectorOptions = useMemo(() => getXeroBankAccountsWithDefaultSelect(policy ?? undefined, reimbursementAccountID), [reimbursementAccountID, policy]);
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
index cca34a8e9cc0..4ef071cd54b5 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
@@ -8,11 +8,11 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections';
import Navigation from '@libs/Navigation/Navigation';
+import {getXeroBankAccountsWithDefaultSelect} from '@libs/PolicyUtils';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
-import { getXeroBankAccountsWithDefaultSelect } from '@libs/PolicyUtils';
function XeroInvoiceAccountSelectorPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
diff --git a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
index e35468e0848e..138ca8fa3800 100644
--- a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
@@ -8,20 +8,20 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections';
import Navigation from '@libs/Navigation/Navigation';
+import {getXeroBankAccountsWithDefaultSelect} from '@libs/PolicyUtils';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
-import { getXeroBankAccountsWithDefaultSelect } from '@libs/PolicyUtils';
function XeroBankAccountSelectPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const policyID = policy?.id ?? '';
-
+
const {nonReimbursableAccount: nonReimbursableAccountID} = policy?.connections?.xero?.config.export ?? {};
- const xeroSelectorOptions = useMemo(() => getXeroBankAccountsWithDefaultSelect(policy ?? undefined, nonReimbursableAccountID), [nonReimbursableAccountID, policy]);
+ const xeroSelectorOptions = useMemo(() => getXeroBankAccountsWithDefaultSelect(policy ?? undefined, nonReimbursableAccountID), [nonReimbursableAccountID, policy]);
const listHeaderComponent = useMemo(
() => (
From c960fa36f76e0eb177f29762ecb6fb67d06207c9 Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Wed, 22 May 2024 11:07:35 +0200
Subject: [PATCH 101/207] fix taxes not blocking on more features page
---
src/pages/workspace/WorkspaceMoreFeaturesPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
index 84091b52d939..9c6f8d491389 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
@@ -105,7 +105,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
titleTranslationKey: 'workspace.moreFeatures.taxes.title',
subtitleTranslationKey: 'workspace.moreFeatures.taxes.subtitle',
isActive: (policy?.tax?.trackingEnabled ?? false) || isSyncTaxEnabled,
- disabled: isSyncTaxEnabled || policy?.connections?.quickbooksOnline?.data?.country === CONST.COUNTRY.US,
+ disabled: hasAccountingConnection || policy?.connections?.quickbooksOnline?.data?.country === CONST.COUNTRY.US,
pendingAction: policy?.pendingFields?.tax,
action: (isEnabled: boolean) => {
Policy.enablePolicyTaxes(policy?.id ?? '', isEnabled);
From bff08c274e8b95b24867c8f97219448a746ebe85 Mon Sep 17 00:00:00 2001
From: Hans
Date: Wed, 22 May 2024 16:40:12 +0700
Subject: [PATCH 102/207] Update category integration name
---
src/pages/workspace/categories/WorkspaceCategoriesPage.tsx | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx
index a8f863583f7e..737f1d6e7b83 100644
--- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx
+++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx
@@ -57,6 +57,8 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
const policyId = route.params.policyID ?? '';
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyId}`);
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyId}`);
+ const isConnectedToAccounting = Object.keys(policy?.connections ?? {}).length > 0;
+ const isConnectedToQbo = policy?.connections?.quickbooksOnline;
const fetchCategories = useCallback(() => {
Policy.openPolicyCategoriesPage(policyId);
@@ -275,14 +277,14 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
/>
{isSmallScreenWidth && {getHeaderButtons()}}
- {Object.keys(policy?.connections ?? {}).length > 0 ? (
+ {isConnectedToAccounting ? (
{`${translate('workspace.categories.importedFromAccountingSoftware')} `}
- {`${translate('workspace.accounting.qbo')} ${translate('workspace.accounting.settings')}`}
+ {`${translate(isConnectedToQbo ? 'workspace.accounting.qbo' : 'workspace.accounting.xero')} ${translate('workspace.accounting.settings')}`}
) : (
From b40eaaecf835c55ee2b83364896064d4c249a5fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Wed, 22 May 2024 12:58:51 +0200
Subject: [PATCH 103/207] disable taxes if previously enabled on disconnect
---
src/pages/workspace/accounting/PolicyAccountingPage.tsx | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index d6ef27c7b00d..74e13a84c5b7 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -32,6 +32,7 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import type {AnchorPosition} from '@styles/index';
+import * as PolicyAction from '@userActions/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
@@ -369,6 +370,9 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
isVisible={isDisconnectModalOpen}
onConfirm={() => {
if (connectedIntegration) {
+ if (policy?.connections?.xero && policy?.connections?.xero?.config?.importTaxRates) {
+ PolicyAction.enablePolicyTaxes(policy?.id ?? '', false);
+ }
removePolicyConnection(policyID, connectedIntegration);
}
setIsDisconnectModalOpen(false);
From a5322ab57d2c019e86c0fbdd7d20cb4b2c0c3aca Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Wed, 22 May 2024 17:05:24 +0530
Subject: [PATCH 104/207] rm header overflow menu
---
.../workspace/accounting/PolicyAccountingPage.tsx | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index d6ef27c7b00d..9caa216d9541 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -292,21 +292,6 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
accountingIntegrations,
]);
- const headerThreeDotsMenuItems: ThreeDotsMenuProps['menuItems'] = [
- {
- icon: Expensicons.Key,
- shouldShowRightIcon: true,
- iconRight: Expensicons.NewWindow,
- text: translate('workspace.accounting.enterCredentials'),
- onSelected: () => {},
- },
- {
- icon: Expensicons.Trashcan,
- text: translate('workspace.accounting.disconnect'),
- onSelected: () => setIsDisconnectModalOpen(true),
- },
- ];
-
return (
Date: Wed, 22 May 2024 17:05:59 +0530
Subject: [PATCH 105/207] rm header overflow menu
---
src/pages/workspace/accounting/PolicyAccountingPage.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index 9caa216d9541..c6574895f0d7 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -309,7 +309,6 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
icon={Illustrations.Accounting}
shouldShowThreeDotsButton
threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)}
- threeDotsMenuItems={headerThreeDotsMenuItems}
/>
From f47f063bbca6283bbe3dc71f6730d688468e6b9c Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Wed, 22 May 2024 17:06:25 +0530
Subject: [PATCH 106/207] hide 3dot
---
src/pages/workspace/accounting/PolicyAccountingPage.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index c6574895f0d7..612336ab4259 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -307,7 +307,6 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
title={translate('workspace.common.accounting')}
shouldShowBackButton={isSmallScreenWidth}
icon={Illustrations.Accounting}
- shouldShowThreeDotsButton
threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)}
/>
From 96b58cb952eb934d798bde7e017de5a33674163a Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Wed, 22 May 2024 17:06:56 +0530
Subject: [PATCH 107/207] hide 3dot
---
src/libs/Permissions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts
index 45551fe1cad9..e24d03ec62ff 100644
--- a/src/libs/Permissions.ts
+++ b/src/libs/Permissions.ts
@@ -4,7 +4,7 @@ import type {IOUType} from '@src/CONST';
import type Beta from '@src/types/onyx/Beta';
function canUseAllBetas(betas: OnyxEntry): boolean {
- return !!betas?.includes(CONST.BETAS.ALL);
+ return true;
}
function canUseChronos(betas: OnyxEntry): boolean {
From a3e4f700be70ab635ff1bb4fb1c9f6b287a4152f Mon Sep 17 00:00:00 2001
From: Rushat Gabhane
Date: Wed, 22 May 2024 17:07:11 +0530
Subject: [PATCH 108/207] undo all beta
---
src/libs/Permissions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts
index e24d03ec62ff..45551fe1cad9 100644
--- a/src/libs/Permissions.ts
+++ b/src/libs/Permissions.ts
@@ -4,7 +4,7 @@ import type {IOUType} from '@src/CONST';
import type Beta from '@src/types/onyx/Beta';
function canUseAllBetas(betas: OnyxEntry): boolean {
- return true;
+ return !!betas?.includes(CONST.BETAS.ALL);
}
function canUseChronos(betas: OnyxEntry): boolean {
From aff888d333e6a67659d40780bf25d96e187c6302 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Wed, 22 May 2024 15:54:32 +0200
Subject: [PATCH 109/207] change logic
---
src/pages/workspace/accounting/PolicyAccountingPage.tsx | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index 74e13a84c5b7..d6ef27c7b00d 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -32,7 +32,6 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import type {AnchorPosition} from '@styles/index';
-import * as PolicyAction from '@userActions/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
@@ -370,9 +369,6 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF
isVisible={isDisconnectModalOpen}
onConfirm={() => {
if (connectedIntegration) {
- if (policy?.connections?.xero && policy?.connections?.xero?.config?.importTaxRates) {
- PolicyAction.enablePolicyTaxes(policy?.id ?? '', false);
- }
removePolicyConnection(policyID, connectedIntegration);
}
setIsDisconnectModalOpen(false);
From 83c3a6c1d90fd1e63ab15463988e2d298f165ee9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Wed, 22 May 2024 15:54:47 +0200
Subject: [PATCH 110/207] remove taxes in lhn when connecting to QBO
---
src/components/ConnectToQuickbooksOnlineButton/index.tsx | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/components/ConnectToQuickbooksOnlineButton/index.tsx b/src/components/ConnectToQuickbooksOnlineButton/index.tsx
index 37fea2b957a2..d5e68b722827 100644
--- a/src/components/ConnectToQuickbooksOnlineButton/index.tsx
+++ b/src/components/ConnectToQuickbooksOnlineButton/index.tsx
@@ -8,6 +8,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import {removePolicyConnection} from '@libs/actions/connections';
import {getQuickBooksOnlineSetupLink} from '@libs/actions/connections/QuickBooksOnline';
import * as Link from '@userActions/Link';
+import * as PolicyAction from '@userActions/Policy';
import CONST from '@src/CONST';
import type {ConnectToQuickbooksOnlineButtonProps} from './types';
@@ -27,6 +28,8 @@ function ConnectToQuickbooksOnlineButton({policyID, shouldDisconnectIntegrationB
setIsDisconnectModalOpen(true);
return;
}
+ // Since QBO doesn't support Taxes, we should disable them from the LHN when connecting to QBO
+ PolicyAction.enablePolicyTaxes(policyID, false);
Link.openLink(getQuickBooksOnlineSetupLink(policyID), environmentURL);
}}
isDisabled={isOffline}
From 539c063e23a8cece78a33a4c40dcfbb5afba4a06 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Thu, 23 May 2024 00:01:40 +0530
Subject: [PATCH 111/207] fix: replace connection name
---
src/pages/workspace/tags/WorkspaceTagsPage.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx
index eca339be0fc4..242022c01ee0 100644
--- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx
+++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx
@@ -52,6 +52,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`);
const {environmentURL} = useEnvironment();
const isConnectedToAccounting = Object.keys(policy?.connections ?? {}).length > 0;
+ const isConnectedToQbo = policy?.connections?.quickbooksOnline;
const [policyTagLists, isMultiLevelTags] = useMemo(() => [PolicyUtils.getTagLists(policyTags), PolicyUtils.isMultiLevelTags(policyTags)], [policyTags]);
const canSelectMultiple = !isMultiLevelTags;
@@ -308,7 +309,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
style={[styles.textNormal, styles.link]}
href={`${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(policyID)}`}
>
- {`${translate('workspace.accounting.qbo')} ${translate('workspace.accounting.settings')}`}
+ {`${translate(isConnectedToQbo ? 'workspace.accounting.qbo' : 'workspace.accounting.xero')} ${translate('workspace.accounting.settings')}`}
) : (
From 0dea1e16ed20026113cb94176d17d4a0b00547c2 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Thu, 23 May 2024 00:08:05 +0530
Subject: [PATCH 112/207] feat: added content for taxes page
---
src/languages/en.ts | 1 +
src/languages/es.ts | 1 +
.../workspace/taxes/WorkspaceTaxesPage.tsx | 19 +++++++++++++++++++
3 files changed, 21 insertions(+)
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 68c1d4120385..fff29854e8d5 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2240,6 +2240,7 @@ export default {
enable: 'Enable rate',
enableMultiple: 'Enable rates',
},
+ importedFromAccountingSoftware: 'The taxes below are imported from your',
},
emptyWorkspace: {
title: 'Create a workspace',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index ef2e27275775..123494816a03 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2276,6 +2276,7 @@ export default {
enable: 'Activar tasa',
enableMultiple: 'Activar tasas',
},
+ importedFromAccountingSoftware: 'Impuestos importadas desde',
},
emptyWorkspace: {
title: 'Crea un espacio de trabajo',
diff --git a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
index f5532157094a..b83b02134922 100644
--- a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
+++ b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
@@ -34,6 +34,8 @@ import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {TaxRate} from '@src/types/onyx';
+import TextLink from '@components/TextLink';
+import useEnvironment from '@hooks/useEnvironment';
type WorkspaceTaxesPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps;
@@ -47,12 +49,17 @@ function WorkspaceTaxesPage({
const styles = useThemeStyles();
const theme = useTheme();
const {translate} = useLocalize();
+ const {environmentURL} = useEnvironment();
const [selectedTaxesIDs, setSelectedTaxesIDs] = useState([]);
const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false);
const defaultExternalID = policy?.taxRates?.defaultExternalID;
const foreignTaxDefault = policy?.taxRates?.foreignTaxDefault;
const isFocused = useIsFocused();
+ const isConnectedToAccounting = Object.keys(policy?.connections ?? {}).length > 0;
+ const isConnectedToQbo = policy?.connections?.quickbooksOnline;
+
+
const fetchTaxes = useCallback(() => {
openPolicyTaxesPage(policyID);
}, [policyID]);
@@ -260,7 +267,19 @@ function WorkspaceTaxesPage({
{isSmallScreenWidth && {headerButtons}}
+ {isConnectedToAccounting ? (
+
+ {`${translate('workspace.categories.importedFromAccountingSoftware')} `}
+
+ {`${translate(isConnectedToQbo ? 'workspace.accounting.qbo' : 'workspace.accounting.xero')} ${translate('workspace.accounting.settings')}`}
+
+
+ ) : (
{translate('workspace.taxes.subtitle')}
+ )}
{isLoading && (
Date: Thu, 23 May 2024 00:13:22 +0530
Subject: [PATCH 113/207] fix: update translate path
---
src/pages/workspace/taxes/WorkspaceTaxesPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
index b83b02134922..8d8012cda38a 100644
--- a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
+++ b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
@@ -269,7 +269,7 @@ function WorkspaceTaxesPage({
{isConnectedToAccounting ? (
- {`${translate('workspace.categories.importedFromAccountingSoftware')} `}
+ {`${translate('workspace.taxes.importedFromAccountingSoftware')} `}
Date: Thu, 23 May 2024 00:53:20 +0530
Subject: [PATCH 114/207] feat: footer text for more features
---
.../workspace/WorkspaceMoreFeaturesPage.tsx | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
index 84091b52d939..cc7661fa8459 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
@@ -2,13 +2,17 @@ import {useFocusEffect} from '@react-navigation/native';
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback} from 'react';
import {View} from 'react-native';
+import ROUTES from '@src/ROUTES';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Illustrations from '@components/Icon/Illustrations';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
+import Text from '@components/Text';
+import TextLink from '@components/TextLink';
import Section from '@components/Section';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
+import useEnvironment from '@hooks/useEnvironment';
import usePermissions from '@hooks/usePermissions';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
@@ -26,6 +30,7 @@ import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscree
import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading';
import ToggleSettingOptionRow from './workflows/ToggleSettingsOptionRow';
+
type WorkspaceMoreFeaturesPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps;
type Item = {
@@ -44,6 +49,7 @@ type SectionObject = {
titleTranslationKey: TranslationPaths;
subtitleTranslationKey: TranslationPaths;
items: Item[];
+ footer?: React.ReactNode;
};
function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPageProps) {
@@ -51,9 +57,30 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
const {isSmallScreenWidth} = useWindowDimensions();
const {translate} = useLocalize();
const {canUseAccountingIntegrations} = usePermissions();
+ const {environmentURL} = useEnvironment();
const hasAccountingConnection = !!policy?.areConnectionsEnabled && !isEmptyObject(policy?.connections);
+ const policyID = policy?.id ?? '';
+ const isConnectedToQbo = policy?.connections?.quickbooksOnline;
const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config.syncTax || !!policy?.connections?.xero?.config.importTaxRates;
+ const renderIntegrationFooter = () => (
+
+ {hasAccountingConnection ? (
+
+ {`${translate('workspace.categories.importedFromAccountingSoftware')} `}
+
+ {`${translate(isConnectedToQbo ? 'workspace.accounting.qbo' : 'workspace.accounting.xero')} ${translate('workspace.accounting.settings')}`}
+
+
+ ) : (
+ {translate('workspace.categories.subtitle')}
+ )}
+
+ )
+
const spendItems: Item[] = [
{
icon: Illustrations.Car,
@@ -139,6 +166,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
titleTranslationKey: 'workspace.moreFeatures.organizeSection.title',
subtitleTranslationKey: 'workspace.moreFeatures.organizeSection.subtitle',
items: organizeItems,
+ footer: renderIntegrationFooter()
},
];
@@ -188,7 +216,10 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitleMuted
>
{section.items.map(renderItem)}
+
+ {section.footer}
+
),
[isSmallScreenWidth, styles, renderItem, translate],
From 3bf730903e7bea91b29d69eeea422a9fc96291d8 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Thu, 23 May 2024 01:07:20 +0530
Subject: [PATCH 115/207] feat: added content for more features
---
src/languages/en.ts | 4 ++++
src/languages/es.ts | 4 ++++
.../workspace/WorkspaceMoreFeaturesPage.tsx | 19 +++++++++++++------
3 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/src/languages/en.ts b/src/languages/en.ts
index fff29854e8d5..17d7dda667d0 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2152,6 +2152,10 @@ export default {
organizeSection: {
title: 'Organize',
subtitle: 'Group and analyze spend, record every tax paid.',
+ footer: {
+ text: "These options can't be changed when",
+ link: "integrated with other systems"
+ }
},
integrateSection: {
title: 'Integrate',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 123494816a03..6e24d3d15f77 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2188,6 +2188,10 @@ export default {
organizeSection: {
title: 'Organizar',
subtitle: 'Agrupa y analiza el gasto, registra cada impuesto pagado.',
+ footer: {
+ text: "Estas opciones no se pueden cambiar cuando",
+ link: "integrado con otros sistemas"
+ }
},
integrateSection: {
title: 'Integrar',
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
index cc7661fa8459..d220e8c7f144 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
@@ -9,6 +9,7 @@ import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
+import Icon from '@components/Icon';
import Section from '@components/Section';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
@@ -19,6 +20,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
import * as ErrorUtils from '@libs/ErrorUtils';
import type {FullScreenNavigatorParamList} from '@libs/Navigation/types';
import * as Policy from '@userActions/Policy';
+import * as Expensicons from '@components/Icon/Expensicons';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type SCREENS from '@src/SCREENS';
@@ -30,7 +32,6 @@ import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscree
import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading';
import ToggleSettingOptionRow from './workflows/ToggleSettingsOptionRow';
-
type WorkspaceMoreFeaturesPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps;
type Item = {
@@ -60,21 +61,27 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
const {environmentURL} = useEnvironment();
const hasAccountingConnection = !!policy?.areConnectionsEnabled && !isEmptyObject(policy?.connections);
const policyID = policy?.id ?? '';
- const isConnectedToQbo = policy?.connections?.quickbooksOnline;
const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config.syncTax || !!policy?.connections?.xero?.config.importTaxRates;
const renderIntegrationFooter = () => (
{hasAccountingConnection ? (
-
- {`${translate('workspace.categories.importedFromAccountingSoftware')} `}
+
+
+
+ {`${translate('workspace.moreFeatures.organizeSection.footer.text')} `}
- {`${translate(isConnectedToQbo ? 'workspace.accounting.qbo' : 'workspace.accounting.xero')} ${translate('workspace.accounting.settings')}`}
+ {`${translate('workspace.moreFeatures.organizeSection.footer.link')}`}
-
+ .
+
+
) : (
{translate('workspace.categories.subtitle')}
)}
From 9cb30efe652a465eba92e2d47dab8c4963595804 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Thu, 23 May 2024 01:09:20 +0530
Subject: [PATCH 116/207] fix: add margin
---
src/pages/workspace/WorkspaceMoreFeaturesPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
index d220e8c7f144..d6879a61cfa8 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
@@ -71,7 +71,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
src={Expensicons.Lock}
fill={styles.colorMuted.color}
/>
-
+
{`${translate('workspace.moreFeatures.organizeSection.footer.text')} `}
Date: Thu, 23 May 2024 01:11:06 +0530
Subject: [PATCH 117/207] refactor: prettier fix
---
src/languages/en.ts | 4 +-
src/languages/es.ts | 6 +-
.../workspace/WorkspaceMoreFeaturesPage.tsx | 57 +++++++++----------
.../workspace/taxes/WorkspaceTaxesPage.tsx | 9 ++-
4 files changed, 37 insertions(+), 39 deletions(-)
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 17d7dda667d0..4a9c7db67bd8 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2154,8 +2154,8 @@ export default {
subtitle: 'Group and analyze spend, record every tax paid.',
footer: {
text: "These options can't be changed when",
- link: "integrated with other systems"
- }
+ link: 'integrated with other systems',
+ },
},
integrateSection: {
title: 'Integrate',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 6e24d3d15f77..955f4b571e51 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2189,9 +2189,9 @@ export default {
title: 'Organizar',
subtitle: 'Agrupa y analiza el gasto, registra cada impuesto pagado.',
footer: {
- text: "Estas opciones no se pueden cambiar cuando",
- link: "integrado con otros sistemas"
- }
+ text: 'Estas opciones no se pueden cambiar cuando',
+ link: 'integrado con otros sistemas',
+ },
},
integrateSection: {
title: 'Integrar',
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
index d6879a61cfa8..8caf737fabe9 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
@@ -2,27 +2,27 @@ import {useFocusEffect} from '@react-navigation/native';
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback} from 'react';
import {View} from 'react-native';
-import ROUTES from '@src/ROUTES';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import Icon from '@components/Icon';
+import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
+import Section from '@components/Section';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
-import Icon from '@components/Icon';
-import Section from '@components/Section';
+import useEnvironment from '@hooks/useEnvironment';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
-import useEnvironment from '@hooks/useEnvironment';
import usePermissions from '@hooks/usePermissions';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as ErrorUtils from '@libs/ErrorUtils';
import type {FullScreenNavigatorParamList} from '@libs/Navigation/types';
import * as Policy from '@userActions/Policy';
-import * as Expensicons from '@components/Icon/Expensicons';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
+import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {Errors, PendingAction} from '@src/types/onyx/OnyxCommon';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
@@ -64,29 +64,29 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config.syncTax || !!policy?.connections?.xero?.config.importTaxRates;
const renderIntegrationFooter = () => (
-
- {hasAccountingConnection ? (
-
-
-
- {`${translate('workspace.moreFeatures.organizeSection.footer.text')} `}
-
- {`${translate('workspace.moreFeatures.organizeSection.footer.link')}`}
-
- .
-
-
- ) : (
- {translate('workspace.categories.subtitle')}
- )}
+
+ {hasAccountingConnection ? (
+
+
+
+ {`${translate('workspace.moreFeatures.organizeSection.footer.text')} `}
+
+ {`${translate('workspace.moreFeatures.organizeSection.footer.link')}`}
+
+ .
+
- )
+ ) : (
+ {translate('workspace.categories.subtitle')}
+ )}
+
+ );
const spendItems: Item[] = [
{
@@ -173,7 +173,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
titleTranslationKey: 'workspace.moreFeatures.organizeSection.title',
subtitleTranslationKey: 'workspace.moreFeatures.organizeSection.subtitle',
items: organizeItems,
- footer: renderIntegrationFooter()
+ footer: renderIntegrationFooter(),
},
];
@@ -226,7 +226,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
{section.footer}
-
),
[isSmallScreenWidth, styles, renderItem, translate],
diff --git a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
index 8d8012cda38a..08a7d48ee76f 100644
--- a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
+++ b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
@@ -15,6 +15,8 @@ import ListItemRightCaretWithLabel from '@components/SelectionList/ListItemRight
import TableListItem from '@components/SelectionList/TableListItem';
import type {ListItem} from '@components/SelectionList/types';
import Text from '@components/Text';
+import TextLink from '@components/TextLink';
+import useEnvironment from '@hooks/useEnvironment';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useTheme from '@hooks/useTheme';
@@ -34,8 +36,6 @@ import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {TaxRate} from '@src/types/onyx';
-import TextLink from '@components/TextLink';
-import useEnvironment from '@hooks/useEnvironment';
type WorkspaceTaxesPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps;
@@ -59,7 +59,6 @@ function WorkspaceTaxesPage({
const isConnectedToAccounting = Object.keys(policy?.connections ?? {}).length > 0;
const isConnectedToQbo = policy?.connections?.quickbooksOnline;
-
const fetchTaxes = useCallback(() => {
openPolicyTaxesPage(policyID);
}, [policyID]);
@@ -267,7 +266,7 @@ function WorkspaceTaxesPage({
{isSmallScreenWidth && {headerButtons}}
- {isConnectedToAccounting ? (
+ {isConnectedToAccounting ? (
{`${translate('workspace.taxes.importedFromAccountingSoftware')} `}
) : (
- {translate('workspace.taxes.subtitle')}
+ {translate('workspace.taxes.subtitle')}
)}
{isLoading && (
From 6204f368622123c99740798a93492cb90380c541 Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Thu, 23 May 2024 01:13:37 +0530
Subject: [PATCH 118/207] fix: update styling
---
src/pages/workspace/WorkspaceMoreFeaturesPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
index 8caf737fabe9..e24ce5cd22e2 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
@@ -64,7 +64,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config.syncTax || !!policy?.connections?.xero?.config.importTaxRates;
const renderIntegrationFooter = () => (
-
+
{hasAccountingConnection ? (
Date: Thu, 23 May 2024 11:31:26 +0200
Subject: [PATCH 119/207] fix PR comments
---
src/pages/workspace/WorkspaceMoreFeaturesPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
index 9c6f8d491389..bab18c5bda8e 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
@@ -105,7 +105,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
titleTranslationKey: 'workspace.moreFeatures.taxes.title',
subtitleTranslationKey: 'workspace.moreFeatures.taxes.subtitle',
isActive: (policy?.tax?.trackingEnabled ?? false) || isSyncTaxEnabled,
- disabled: hasAccountingConnection || policy?.connections?.quickbooksOnline?.data?.country === CONST.COUNTRY.US,
+ disabled: hasAccountingConnection,
pendingAction: policy?.pendingFields?.tax,
action: (isEnabled: boolean) => {
Policy.enablePolicyTaxes(policy?.id ?? '', isEnabled);
From 5979a35a1405c53f90d06b8938a9b3fe31201017 Mon Sep 17 00:00:00 2001
From: Jakub Szymczak
Date: Thu, 23 May 2024 17:25:13 +0200
Subject: [PATCH 120/207] change translations
---
src/languages/en.ts | 6 +++---
src/languages/es.ts | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/languages/en.ts b/src/languages/en.ts
index d769f5222368..ebf51413924d 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2343,11 +2343,11 @@ export default {
syncError: (integration?: ConnectionName): string => {
switch (integration) {
case CONST.POLICY.CONNECTIONS.NAME.QBO:
- return "Couldn't connect to QuickBooks Online due to incorrect credentials.";
+ return "Couldn't connect to QuickBooks Online.";
case CONST.POLICY.CONNECTIONS.NAME.XERO:
- return "Couldn't connect to Xero due to incorrect credentials.";
+ return "Couldn't connect to Xero.";
default: {
- return "Couldn't connect to integration due to incorrect credentials.";
+ return "Couldn't connect to integration.";
}
}
},
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 183af720f09c..9440381c6c6a 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2347,11 +2347,11 @@ export default {
syncError: (integration?: ConnectionName): string => {
switch (integration) {
case CONST.POLICY.CONNECTIONS.NAME.QBO:
- return 'No se pudo conectar a QuickBooks Online debido a credenciales incorrectas.';
+ return 'No se puede conectar a QuickBooks Online.';
case CONST.POLICY.CONNECTIONS.NAME.XERO:
- return 'No se pudo conectar a Xero debido a credenciales incorrectas.';
+ return 'No se puede conectar a Xero';
default: {
- return 'No se pudo conectar a la integración debido a credenciales incorrectas.';
+ return 'No se ha podido conectar a la integración.';
}
}
},
From 95f1ed992dc38650ca42e755cd4a3eb7ed57bbcb Mon Sep 17 00:00:00 2001
From: Andrew Rosiclair
Date: Thu, 23 May 2024 12:56:01 -0400
Subject: [PATCH 121/207] Merge pull request #42315 from
Expensify/hayata-call-api-for-multi-level-tags
Enable / Disable multi level tags
---
src/libs/API/parameters/SetPolicyTagsEnabled.ts | 5 +++++
src/libs/actions/Policy.ts | 8 +++++---
src/pages/workspace/tags/TagSettingsPage.tsx | 2 +-
src/pages/workspace/tags/WorkspaceTagsPage.tsx | 4 ++--
src/pages/workspace/tags/WorkspaceViewTagsPage.tsx | 4 ++--
tests/actions/PolicyTagTest.ts | 4 ++--
6 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/src/libs/API/parameters/SetPolicyTagsEnabled.ts b/src/libs/API/parameters/SetPolicyTagsEnabled.ts
index 86720b84bf8b..67928a3227e3 100644
--- a/src/libs/API/parameters/SetPolicyTagsEnabled.ts
+++ b/src/libs/API/parameters/SetPolicyTagsEnabled.ts
@@ -5,6 +5,11 @@ type SetPolicyTagsEnabled = {
* Array<{name: string; enabled: boolean}>
*/
tags: string;
+ /**
+ * When the tags are imported as multi level tags, the index of the top
+ * most tag list item
+ */
+ tagListIndex: number;
};
export default SetPolicyTagsEnabled;
diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts
index 3e09524e1dd1..08499edc7e5d 100644
--- a/src/libs/actions/Policy.ts
+++ b/src/libs/actions/Policy.ts
@@ -54,6 +54,7 @@ import type {
UpdateWorkspaceGeneralSettingsParams,
UpdateWorkspaceMembersRoleParams,
} from '@libs/API/parameters';
+import type SetPolicyTagsEnabled from '@libs/API/parameters/SetPolicyTagsEnabled';
import type UpdatePolicyAddressParams from '@libs/API/parameters/UpdatePolicyAddressParams';
import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import DateUtils from '@libs/DateUtils';
@@ -3466,8 +3467,8 @@ function createPolicyTag(policyID: string, tagName: string) {
API.write(WRITE_COMMANDS.CREATE_POLICY_TAG, parameters, onyxData);
}
-function setWorkspaceTagEnabled(policyID: string, tagsToUpdate: Record) {
- const policyTag = PolicyUtils.getTagLists(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})?.[0] ?? {};
+function setWorkspaceTagEnabled(policyID: string, tagsToUpdate: Record, tagListIndex: number) {
+ const policyTag = PolicyUtils.getTagLists(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})?.[tagListIndex] ?? {};
const onyxData: OnyxData = {
optimisticData: [
@@ -3547,9 +3548,10 @@ function setWorkspaceTagEnabled(policyID: string, tagsToUpdate: Record tagsToUpdate[key])),
+ tagListIndex,
};
API.write(WRITE_COMMANDS.SET_POLICY_TAGS_ENABLED, parameters, onyxData);
diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx
index 1f9d440108ae..abbccc321827 100644
--- a/src/pages/workspace/tags/TagSettingsPage.tsx
+++ b/src/pages/workspace/tags/TagSettingsPage.tsx
@@ -66,7 +66,7 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps)
};
const updateWorkspaceTagEnabled = (value: boolean) => {
- setWorkspaceTagEnabled(route.params.policyID, {[currentPolicyTag.name]: {name: currentPolicyTag.name, enabled: value}});
+ setWorkspaceTagEnabled(route.params.policyID, {[currentPolicyTag.name]: {name: currentPolicyTag.name, enabled: value}}, policyTag.orderWeight);
};
const navigateToEditTag = () => {
diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx
index eca339be0fc4..a1299b6d4406 100644
--- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx
+++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx
@@ -238,7 +238,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
value: CONST.POLICY.TAGS_BULK_ACTION_TYPES.DISABLE,
onSelected: () => {
setSelectedTags({});
- Policy.setWorkspaceTagEnabled(policyID, tagsToDisable);
+ Policy.setWorkspaceTagEnabled(policyID, tagsToDisable, 0);
},
});
}
@@ -250,7 +250,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
value: CONST.POLICY.TAGS_BULK_ACTION_TYPES.ENABLE,
onSelected: () => {
setSelectedTags({});
- Policy.setWorkspaceTagEnabled(policyID, tagsToEnable);
+ Policy.setWorkspaceTagEnabled(policyID, tagsToEnable, 0);
},
});
}
diff --git a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
index 09ba086e3a14..39485f45f0a8 100644
--- a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
+++ b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
@@ -174,7 +174,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
value: CONST.POLICY.TAGS_BULK_ACTION_TYPES.DISABLE,
onSelected: () => {
setSelectedTags({});
- Policy.setWorkspaceTagEnabled(policyID, tagsToDisable);
+ Policy.setWorkspaceTagEnabled(policyID, tagsToDisable, route.params.orderWeight);
},
});
}
@@ -186,7 +186,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
value: CONST.POLICY.TAGS_BULK_ACTION_TYPES.ENABLE,
onSelected: () => {
setSelectedTags({});
- Policy.setWorkspaceTagEnabled(policyID, tagsToEnable);
+ Policy.setWorkspaceTagEnabled(policyID, tagsToEnable, route.params.orderWeight);
},
});
}
diff --git a/tests/actions/PolicyTagTest.ts b/tests/actions/PolicyTagTest.ts
index 74ea13f3d139..a0982a78b70a 100644
--- a/tests/actions/PolicyTagTest.ts
+++ b/tests/actions/PolicyTagTest.ts
@@ -395,7 +395,7 @@ describe('actions/Policy', () => {
Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${fakePolicy.id}`, fakePolicyTags);
})
.then(() => {
- Policy.setWorkspaceTagEnabled(fakePolicy.id, tagsToUpdate);
+ Policy.setWorkspaceTagEnabled(fakePolicy.id, tagsToUpdate, 0);
return waitForBatchedUpdates();
})
.then(
@@ -468,7 +468,7 @@ describe('actions/Policy', () => {
.then(() => {
mockFetch?.fail?.();
- Policy.setWorkspaceTagEnabled(fakePolicy.id, tagsToUpdate);
+ Policy.setWorkspaceTagEnabled(fakePolicy.id, tagsToUpdate, 0);
return waitForBatchedUpdates();
})
.then(mockFetch?.resume)
From 1ebaeedda29e357933bb4fdab3be41933ed1a19a Mon Sep 17 00:00:00 2001
From: Hayata Suenaga
Date: Mon, 20 May 2024 16:29:13 -0700
Subject: [PATCH 122/207] Merge pull request #42149 from
s77rt/multi-level-tags-fix-not-found
[NoQA] Add orderWeight to tag view and tag edit routes
---
src/ROUTES.ts | 8 ++++----
src/libs/Navigation/linkingConfig/config.ts | 2 ++
src/libs/Navigation/types.ts | 3 ++-
src/pages/workspace/tags/EditTagPage.tsx | 4 ++--
src/pages/workspace/tags/TagSettingsPage.tsx | 4 ++--
src/pages/workspace/tags/WorkspaceTagsPage.tsx | 4 ++--
src/pages/workspace/tags/WorkspaceViewTagsPage.tsx | 2 +-
7 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 5fd0c8890fd3..9ffe725ebb7c 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -672,12 +672,12 @@ const ROUTES = {
getRoute: (policyID: string, orderWeight: number) => `settings/workspaces/${policyID}/tags/${orderWeight}/edit` as const,
},
WORKSPACE_TAG_EDIT: {
- route: 'settings/workspace/:policyID/tag/:tagName/edit',
- getRoute: (policyID: string, tagName: string) => `settings/workspace/${policyID}/tag/${encodeURIComponent(tagName)}/edit` as const,
+ route: 'settings/workspaces/:policyID/tag/:orderWeight/:tagName/edit',
+ getRoute: (policyID: string, orderWeight: number, tagName: string) => `settings/workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}/edit` as const,
},
WORKSPACE_TAG_SETTINGS: {
- route: 'settings/workspaces/:policyID/tag/:tagName',
- getRoute: (policyID: string, tagName: string) => `settings/workspaces/${policyID}/tag/${encodeURIComponent(tagName)}` as const,
+ route: 'settings/workspaces/:policyID/tag/:orderWeight/:tagName',
+ getRoute: (policyID: string, orderWeight: number, tagName: string) => `settings/workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}` as const,
},
WORKSPACE_TAG_LIST_VIEW: {
route: 'settings/workspaces/:policyID/tag-list/:orderWeight',
diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts
index 697225e467db..b49b7795d292 100644
--- a/src/libs/Navigation/linkingConfig/config.ts
+++ b/src/libs/Navigation/linkingConfig/config.ts
@@ -428,12 +428,14 @@ const config: LinkingOptions['config'] = {
[SCREENS.WORKSPACE.TAG_EDIT]: {
path: ROUTES.WORKSPACE_TAG_EDIT.route,
parse: {
+ orderWeight: Number,
tagName: (tagName: string) => decodeURIComponent(tagName),
},
},
[SCREENS.WORKSPACE.TAG_SETTINGS]: {
path: ROUTES.WORKSPACE_TAG_SETTINGS.route,
parse: {
+ orderWeight: Number,
tagName: (tagName: string) => decodeURIComponent(tagName),
},
},
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index 55e1c35a874c..0583fc8cc630 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -211,6 +211,7 @@ type SettingsNavigatorParamList = {
};
[SCREENS.WORKSPACE.TAG_SETTINGS]: {
policyID: string;
+ orderWeight: number;
tagName: string;
};
[SCREENS.WORKSPACE.TAG_LIST_VIEW]: {
@@ -223,6 +224,7 @@ type SettingsNavigatorParamList = {
};
[SCREENS.WORKSPACE.TAG_EDIT]: {
policyID: string;
+ orderWeight: number;
tagName: string;
};
[SCREENS.WORKSPACE.TAXES_SETTINGS]: {
@@ -794,7 +796,6 @@ type FullScreenNavigatorParamList = {
};
[SCREENS.WORKSPACE.TAGS]: {
policyID: string;
- tagName: string;
};
[SCREENS.WORKSPACE.TAXES]: {
policyID: string;
diff --git a/src/pages/workspace/tags/EditTagPage.tsx b/src/pages/workspace/tags/EditTagPage.tsx
index 663cbd4f37be..1f60e9eb6567 100644
--- a/src/pages/workspace/tags/EditTagPage.tsx
+++ b/src/pages/workspace/tags/EditTagPage.tsx
@@ -41,7 +41,7 @@ function EditTagPage({route, policyTags}: EditTagPageProps) {
(values: FormOnyxValues) => {
const errors: FormInputErrors = {};
const tagName = values.tagName.trim();
- const {tags} = PolicyUtils.getTagList(policyTags, 0);
+ const {tags} = PolicyUtils.getTagList(policyTags, route.params.orderWeight);
if (!ValidationUtils.isRequiredFulfilled(tagName)) {
errors.tagName = 'workspace.tags.tagRequiredError';
} else if (tags?.[tagName] && currentTagName !== tagName) {
@@ -50,7 +50,7 @@ function EditTagPage({route, policyTags}: EditTagPageProps) {
return errors;
},
- [currentTagName, policyTags],
+ [route.params.orderWeight, currentTagName, policyTags],
);
const editTag = useCallback(
diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx
index abbccc321827..a668502b29a1 100644
--- a/src/pages/workspace/tags/TagSettingsPage.tsx
+++ b/src/pages/workspace/tags/TagSettingsPage.tsx
@@ -38,7 +38,7 @@ type TagSettingsPageProps = TagSettingsPageOnyxProps & StackScreenProps PolicyUtils.getTagList(policyTags, 0), [policyTags]);
+ const policyTag = useMemo(() => PolicyUtils.getTagList(policyTags, route.params.orderWeight), [policyTags, route.params.orderWeight]);
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${route.params.policyID}`);
const {windowWidth} = useWindowDimensions();
@@ -70,7 +70,7 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps)
};
const navigateToEditTag = () => {
- Navigation.navigate(ROUTES.WORKSPACE_TAG_EDIT.getRoute(route.params.policyID, currentPolicyTag.name));
+ Navigation.navigate(ROUTES.WORKSPACE_TAG_EDIT.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name));
};
const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0;
diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx
index a1299b6d4406..9c916affc1ab 100644
--- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx
+++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx
@@ -154,11 +154,11 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
};
const navigateToTagSettings = (tag: TagListItem) => {
- if (tag.orderWeight != null) {
+ if (tag.orderWeight !== undefined) {
Navigation.navigate(ROUTES.WORKSPACE_TAG_LIST_VIEW.getRoute(policyID, tag.orderWeight));
return;
}
- Navigation.navigate(ROUTES.WORKSPACE_TAG_SETTINGS.getRoute(policyID, tag.value));
+ Navigation.navigate(ROUTES.WORKSPACE_TAG_SETTINGS.getRoute(policyID, 0, tag.value));
};
const selectedTagsArray = Object.keys(selectedTags).filter((key) => selectedTags[key]);
diff --git a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
index 39485f45f0a8..13a773a15f3d 100644
--- a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
+++ b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
@@ -117,7 +117,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
);
const navigateToTagSettings = (tag: TagListItem) => {
- Navigation.navigate(ROUTES.WORKSPACE_TAG_SETTINGS.getRoute(policyID, tag.value));
+ Navigation.navigate(ROUTES.WORKSPACE_TAG_SETTINGS.getRoute(policyID, route.params.orderWeight, tag.value));
};
const selectedTagsArray = Object.keys(selectedTags).filter((key) => selectedTags[key]);
From 86bbf4bcddc7238f37070dfcf72486ad9334d73b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:05:40 +0200
Subject: [PATCH 123/207] make translations dynamic for xero tracking
categories
---
src/languages/en.ts | 6 ++----
src/languages/es.ts | 6 ++----
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 68c1d4120385..1b524c53ab91 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2041,10 +2041,8 @@ export default {
accountsSwitchDescription: 'Enabled categories are available for members to select when creating their expenses.',
trackingCategories: 'Tracking categories',
trackingCategoriesDescription: 'Choose whether to import tracking categories and see where they are displayed.',
- mapXeroCostCentersTo: 'Map Xero cost centers to',
- mapXeroRegionsTo: 'Map Xero regions to',
- mapXeroCostCentersToDescription: 'Choose where to map cost centers to when exporting to Xero.',
- mapXeroRegionsToDescription: 'Choose where to map employee regions when exporting expense reports to Xero.',
+ mapTrackingCategoryTo: ({categoryName}) => `Map Xero ${categoryName} to`,
+ mapTrackingCategoryToDescription: ({categoryName}) => `Choose where to map ${categoryName} to when exporting to Xero.`,
customers: 'Re-bill customers',
customersDescription: 'Import customer contacts. Billable expenses need tags for export. Expenses will carry the customer information to Xero for sales invoices.',
taxesDescription: 'Choose whether to import tax rates and tax defaults from your accounting integration.',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index ef2e27275775..9eed722deb3e 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2073,10 +2073,8 @@ export default {
accountsSwitchDescription: 'Las categorías activas estarán disponibles para ser escogidas cuando se crea un gasto.',
trackingCategories: 'Categorías de seguimiento',
trackingCategoriesDescription: 'Elige si deseas importar categorías de seguimiento y ver dónde se muestran.',
- mapXeroCostCentersTo: 'Asignar centros de coste de Xero a',
- mapXeroRegionsTo: 'Asignar regiones de Xero a',
- mapXeroCostCentersToDescription: 'Elige dónde mapear los centros de coste al exportar a Xero.',
- mapXeroRegionsToDescription: 'Elige dónde asignar las regiones de los empleados al exportar informes de gastos a Xero.',
+ mapTrackingCategoryTo: ({categoryName}) => `Asignar ${categoryName} de Xero a`,
+ mapTrackingCategoryToDescription: ({categoryName}) => `Elige dónde mapear ${categoryName} al exportar a Xero.`,
customers: 'Volver a facturar a los clientes',
customersDescription:
'Importar contactos de clientes. Los gastos facturables necesitan etiquetas para la exportación. Los gastos llevarán la información del cliente a Xero para las facturas de ventas.',
From ff704d1fd00333399aaae3bbf6ee34dba6f32716 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:06:12 +0200
Subject: [PATCH 124/207] use only one route for tracking category mapping
---
src/ROUTES.ts | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 9ffe725ebb7c..245eee116c96 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -795,13 +795,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/accounting/xero/import/tracking-categories',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories` as const,
},
- POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP_COST_CENTERS: {
- route: 'settings/workspaces/:policyID/accounting/xero/import/tracking-categories/cost-centers',
- getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories/cost-centers` as const,
- },
- POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP_REGION: {
- route: 'settings/workspaces/:policyID/accounting/xero/import/tracking-categories/region',
- getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories/region` as const,
+ POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP: {
+ route: 'settings/workspaces/:policyID/accounting/xero/import/tracking-categories/mapping/:categoryId/:categoryName',
+ getRoute: (policyID: string, categoryId: string, categoryName: string) =>
+ `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories/mapping/${categoryId}/${categoryName}` as const,
},
POLICY_ACCOUNTING_XERO_CUSTOMER: {
route: 'settings/workspaces/:policyID/accounting/xero/import/customers',
From 9e860f3c9e4580c7dabdd00f70651f82bd6db36d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:21:49 +0200
Subject: [PATCH 125/207] use one screen for the tracking category mapping
---
src/SCREENS.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index 87d31b071050..79e66e6dea32 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -244,8 +244,7 @@ const SCREENS = {
XERO_CUSTOMER: 'Policy_Acounting_Xero_Import_Customer',
XERO_TAXES: 'Policy_Accounting_Xero_Taxes',
XERO_TRACKING_CATEGORIES: 'Policy_Accounting_Xero_Tracking_Categories',
- XERO_MAP_COST_CENTERS: 'Policy_Accounting_Xero_Map_Cost_Centers',
- XERO_MAP_REGION: 'Policy_Accounting_Xero_Map_Region',
+ XERO_MAP_TRACKING_CATEGORY: 'Policy_Accounting_Xero_Map_Tracking_Category',
XERO_EXPORT: 'Policy_Accounting_Xero_Export',
XERO_EXPORT_PURCHASE_BILL_DATE_SELECT: 'Policy_Accounting_Xero_Export_Purchase_Bill_Date_Select',
XERO_ADVANCED: 'Policy_Accounting_Xero_Advanced',
From 1b8901a4d58c9df39b284c54b16b2769a7c96ae0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:22:25 +0200
Subject: [PATCH 126/207] handle navigation for the new page for tracking
category
---
.../Navigation/AppNavigator/ModalStackNavigators/index.tsx | 4 ++--
src/libs/Navigation/linkingConfig/config.ts | 3 +--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
index 25bf6fe06265..da9081a2b46a 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
@@ -299,8 +299,8 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/accounting/xero/XeroTaxesConfigurationPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TRACKING_CATEGORIES]: () =>
require('../../../../pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage').default as React.ComponentType,
- [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_COST_CENTERS]: () => require('../../../../pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage').default as React.ComponentType,
- [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_REGION]: () => require('../../../../pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage').default as React.ComponentType,
+ [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_TRACKING_CATEGORY]: () =>
+ require('../../../../pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT]: () => require('../../../../pages/workspace/accounting/xero/export/XeroExportConfigurationPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT_PURCHASE_BILL_DATE_SELECT]: () =>
require('../../../../pages/workspace/accounting/xero/export/XeroPurchaseBillDateSelectPage').default as React.ComponentType,
diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts
index b49b7795d292..ac4aba4501b3 100644
--- a/src/libs/Navigation/linkingConfig/config.ts
+++ b/src/libs/Navigation/linkingConfig/config.ts
@@ -326,8 +326,7 @@ const config: LinkingOptions['config'] = {
[SCREENS.WORKSPACE.ACCOUNTING.XERO_CHART_OF_ACCOUNTS]: {path: ROUTES.POLICY_ACCOUNTING_XERO_CHART_OF_ACCOUNTS.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: {path: ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TRACKING_CATEGORIES]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES.route},
- [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_COST_CENTERS]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP_COST_CENTERS.route},
- [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_REGION]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP_REGION.route},
+ [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_TRACKING_CATEGORY]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: {path: ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TAXES.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT]: {path: ROUTES.POLICY_ACCOUNTING_XERO_EXPORT.route},
From c837440986f154c27fdcc6504129fe2dc4c32ae5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:22:40 +0200
Subject: [PATCH 127/207] add new types for tracking category mapping
---
src/libs/Navigation/types.ts | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index 0583fc8cc630..4ae0cca8ed0b 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -332,11 +332,10 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TRACKING_CATEGORIES]: {
policyID: string;
};
- [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_COST_CENTERS]: {
- policyID: string;
- };
- [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_REGION]: {
+ [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_TRACKING_CATEGORY]: {
policyID: string;
+ categoryId: string;
+ categoryName: string;
};
[SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT]: {
policyID: string;
From 2256423ba9b3cae76c821efa7c7dae4336422f65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:23:06 +0200
Subject: [PATCH 128/207] map the tracking category page to rhp
---
.../Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts
index 50e51e03da9c..2aaceb96f52a 100755
--- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts
+++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts
@@ -45,8 +45,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = {
SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER,
SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES,
SCREENS.WORKSPACE.ACCOUNTING.XERO_TRACKING_CATEGORIES,
- SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_COST_CENTERS,
- SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_REGION,
+ SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_TRACKING_CATEGORY,
SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT,
SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT_PURCHASE_BILL_DATE_SELECT,
SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED,
From bb8c24ee90996b4a9d4713383f77be9359ba0417 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:23:50 +0200
Subject: [PATCH 129/207] create function to get tracking categories
---
src/libs/actions/connections/ConnectToXero.ts | 20 ++++++-------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/src/libs/actions/connections/ConnectToXero.ts b/src/libs/actions/connections/ConnectToXero.ts
index 43972e540d58..e327b218989c 100644
--- a/src/libs/actions/connections/ConnectToXero.ts
+++ b/src/libs/actions/connections/ConnectToXero.ts
@@ -12,26 +12,18 @@ const getXeroSetupLink = (policyID: string) => {
return commandURL + new URLSearchParams(params).toString();
};
-/**
- * Fetches the category object from the xero.data.trackingCategories based on the category name.
- * This is required to get Xero category object with current value stored in the xero.config.mappings
- * @param policy
- * @param key
- * @returns Filtered category matching the category name or undefined.
- */
-const getTrackingCategory = (policy: OnyxEntry, categoryName: string): (XeroTrackingCategory & {value: string}) | undefined => {
+const getTrackingCategories = (policy: OnyxEntry): Array => {
const {trackingCategories} = policy?.connections?.xero?.data ?? {};
const {mappings} = policy?.connections?.xero?.config ?? {};
- const category = trackingCategories?.find((currentCategory) => currentCategory.name.toLowerCase() === categoryName.toLowerCase());
- if (!category) {
- return undefined;
+ if (!trackingCategories) {
+ return [];
}
- return {
+ return trackingCategories.map((category) => ({
...category,
value: mappings?.[`${CONST.XERO_CONFIG.TRACKING_CATEGORY_PREFIX}${category.id}`] ?? '',
- };
+ }));
};
-export {getXeroSetupLink, getTrackingCategory};
+export {getXeroSetupLink, getTrackingCategories};
From 5b797b62d3019ede54b5cc1084a264f847546af5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:25:32 +0200
Subject: [PATCH 130/207] modify component for dynamic translations
---
src/components/ConnectionLayout.tsx | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/src/components/ConnectionLayout.tsx b/src/components/ConnectionLayout.tsx
index 6d17b84bfffa..aac0404ddc8a 100644
--- a/src/components/ConnectionLayout.tsx
+++ b/src/components/ConnectionLayout.tsx
@@ -17,8 +17,8 @@ type ConnectionLayoutProps = {
/** Used to set the testID for tests */
displayName: string;
- /** Header title for the connection */
- headerTitle: TranslationPaths;
+ /** Header title to be translated for the connection component */
+ headerTitle?: TranslationPaths;
/** The subtitle to show in the header */
headerSubtitle?: string;
@@ -26,7 +26,7 @@ type ConnectionLayoutProps = {
/** React nodes that will be shown */
children?: React.ReactNode;
- /** Title of the connection component */
+ /** Title to be translated for the connection component */
title?: TranslationPaths;
/** The current policyID */
@@ -49,16 +49,22 @@ type ConnectionLayoutProps = {
/** Whether to use ScrollView or not */
shouldUseScrollView?: boolean;
+
+ /** Used for dynamic header title translation with parameters */
+ headerTitleAlreadyTranslated?: string;
+
+ /** Used for dynamic title translation with parameters */
+ titleAlreadyTranslated?: string;
};
-type ConnectionLayoutContentProps = Pick;
+type ConnectionLayoutContentProps = Pick;
-function ConnectionLayoutContent({title, titleStyle, children}: ConnectionLayoutContentProps) {
+function ConnectionLayoutContent({title, titleStyle, children, titleAlreadyTranslated}: ConnectionLayoutContentProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
return (
<>
- {title && {translate(title)}}
+ {title && {titleAlreadyTranslated ?? translate(title)}}
{children}
>
);
@@ -77,6 +83,8 @@ function ConnectionLayout({
titleStyle,
shouldIncludeSafeAreaPaddingBottom,
shouldUseScrollView = true,
+ headerTitleAlreadyTranslated,
+ titleAlreadyTranslated,
}: ConnectionLayoutProps) {
const {translate} = useLocalize();
@@ -85,11 +93,12 @@ function ConnectionLayout({
{children}
),
- [title, titleStyle, children],
+ [title, titleStyle, children, titleAlreadyTranslated],
);
return (
@@ -104,7 +113,7 @@ function ConnectionLayout({
testID={displayName}
>
Navigation.goBack()}
/>
From ed4c53f0993e24528a652e08f231fbf3351ac153 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:26:00 +0200
Subject: [PATCH 131/207] make the handling of tracking categories dynamic
---
...roMapTrackingCategoryConfigurationPage.tsx | 76 +++++++++++++++++++
.../XeroTrackingCategoryConfigurationPage.tsx | 33 +++-----
2 files changed, 85 insertions(+), 24 deletions(-)
create mode 100644 src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
diff --git a/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
new file mode 100644
index 000000000000..572ec476d632
--- /dev/null
+++ b/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
@@ -0,0 +1,76 @@
+import {useRoute} from '@react-navigation/native';
+import React, {useCallback, useMemo} from 'react';
+import ConnectionLayout from '@components/ConnectionLayout';
+import SelectionList from '@components/SelectionList';
+import RadioListItem from '@components/SelectionList/RadioListItem';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@hooks/useThemeStyles';
+import * as Connections from '@libs/actions/connections';
+import Navigation from '@libs/Navigation/Navigation';
+import type {WithPolicyProps} from '@pages/workspace/withPolicy';
+import withPolicyConnections from '@pages/workspace/withPolicyConnections';
+import CONST from '@src/CONST';
+import type {TranslationPaths} from '@src/languages/types';
+import ROUTES from '@src/ROUTES';
+
+type RouteParams = {
+ categoryId?: string;
+ categoryName?: string;
+};
+
+function XeroMapTrackingCategoryConfigurationPage({policy}: WithPolicyProps) {
+ const {translate} = useLocalize();
+ const route = useRoute();
+ const params = route.params as RouteParams;
+ const styles = useThemeStyles();
+ const categoryId = params?.categoryId ?? '';
+ const categoryName = params?.categoryName ?? '';
+ const policyID = policy?.id ?? '';
+
+ const optionsList = useMemo(
+ () =>
+ Object.values(CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS).map((option) => ({
+ value: option,
+ text: translate(`workspace.xero.trackingCategoriesOptions.${option.toLowerCase()}` as TranslationPaths),
+ keyForList: option,
+ isSelected: option.toLowerCase() === categoryName.toLowerCase(),
+ })),
+ [translate, categoryName],
+ );
+
+ const updateMapping = useCallback(
+ (option: {value: string}) => {
+ if (option.value !== categoryName) {
+ Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.MAPPINGS, {
+ ...(policy?.connections?.xero?.config?.mappings ?? {}),
+ ...(categoryId ? {[`${CONST.XERO_CONFIG.TRACKING_CATEGORY_PREFIX}${categoryId}`]: option.value} : {}),
+ });
+ }
+ Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES.getRoute(policyID));
+ },
+ [categoryId, categoryName, policyID, policy?.connections?.xero?.config?.mappings],
+ );
+
+ return (
+
+
+
+ );
+}
+
+XeroMapTrackingCategoryConfigurationPage.displayName = 'XeroMapTrackingCategoryConfigurationPage';
+export default withPolicyConnections(XeroMapTrackingCategoryConfigurationPage);
diff --git a/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
index 2742060eaa2b..2a8b67839c9d 100644
--- a/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
@@ -6,7 +6,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections';
-import {getTrackingCategory} from '@libs/actions/connections/ConnectToXero';
+import {getTrackingCategories} from '@libs/actions/connections/ConnectToXero';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import type {WithPolicyProps} from '@pages/workspace/withPolicy';
@@ -16,6 +16,7 @@ import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ROUTES from '@src/ROUTES';
+import type {XeroTrackingCategory} from '@src/types/onyx/Policy';
function XeroTrackingCategoryConfigurationPage({policy}: WithPolicyProps) {
const {translate} = useLocalize();
@@ -25,30 +26,14 @@ function XeroTrackingCategoryConfigurationPage({policy}: WithPolicyProps) {
const isSwitchOn = !!xeroConfig?.importTrackingCategories;
const menuItems: MenuItemProps[] = useMemo(() => {
- const availableCategories = [];
-
- const costCenterCategoryValue = getTrackingCategory(policy, CONST.XERO_CONFIG.TRACKING_CATEGORY_FIELDS.COST_CENTERS)?.value ?? '';
- const regionCategoryValue = getTrackingCategory(policy, CONST.XERO_CONFIG.TRACKING_CATEGORY_FIELDS.REGION)?.value ?? '';
- if (costCenterCategoryValue) {
- const isValidOption = Object.values(CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS).findIndex((option) => option.toLowerCase() === costCenterCategoryValue.toLowerCase()) > -1;
- availableCategories.push({
- description: translate('workspace.xero.mapXeroCostCentersTo'),
- onPress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP_COST_CENTERS.getRoute(policyID)),
- title: isValidOption ? translate(`workspace.xero.trackingCategoriesOptions.${costCenterCategoryValue.toLowerCase()}` as TranslationPaths) : '',
- });
- }
-
- if (regionCategoryValue) {
- const isValidOption = Object.values(CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS).findIndex((option) => option.toLowerCase() === regionCategoryValue.toLowerCase()) > -1;
- availableCategories.push({
- description: translate('workspace.xero.mapXeroRegionsTo'),
- onPress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP_REGION.getRoute(policyID)),
- title: isValidOption ? translate(`workspace.xero.trackingCategoriesOptions.${regionCategoryValue.toLowerCase()}` as TranslationPaths) : '',
- });
- }
- return availableCategories;
+ const trackingCategories = getTrackingCategories(policy);
+ return trackingCategories.map((category: XeroTrackingCategory & {value: string}) => ({
+ description: translate('workspace.xero.mapTrackingCategoryTo', {categoryName: category.name}) as TranslationPaths,
+ onPress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP.getRoute(policyID, category.id, category.name)),
+ title: translate(`workspace.xero.trackingCategoriesOptions.${category.value.toLowerCase()}` as TranslationPaths),
+ }));
}, [translate, policy, policyID]);
-
+
return (
Date: Fri, 24 May 2024 15:37:14 +0200
Subject: [PATCH 132/207] fix style
---
.../accounting/xero/XeroTrackingCategoryConfigurationPage.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
index 2a8b67839c9d..dd9e9ca06a33 100644
--- a/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx
@@ -33,7 +33,7 @@ function XeroTrackingCategoryConfigurationPage({policy}: WithPolicyProps) {
title: translate(`workspace.xero.trackingCategoriesOptions.${category.value.toLowerCase()}` as TranslationPaths),
}));
}, [translate, policy, policyID]);
-
+
return (
Date: Fri, 24 May 2024 15:37:22 +0200
Subject: [PATCH 133/207] delete specific tracking categories pages
---
.../XeroMapCostCentersToConfigurationPage.tsx | 71 -------------------
.../XeroMapRegionsToConfigurationPage.tsx | 70 ------------------
2 files changed, 141 deletions(-)
delete mode 100644 src/pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage.tsx
delete mode 100644 src/pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage.tsx
diff --git a/src/pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage.tsx
deleted file mode 100644
index 1d1307a0d31c..000000000000
--- a/src/pages/workspace/accounting/xero/XeroMapCostCentersToConfigurationPage.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import React, {useCallback, useMemo} from 'react';
-import ConnectionLayout from '@components/ConnectionLayout';
-import SelectionList from '@components/SelectionList';
-import RadioListItem from '@components/SelectionList/RadioListItem';
-import useLocalize from '@hooks/useLocalize';
-import useThemeStyles from '@hooks/useThemeStyles';
-import * as Connections from '@libs/actions/connections';
-import {getTrackingCategory} from '@libs/actions/connections/ConnectToXero';
-import Navigation from '@libs/Navigation/Navigation';
-import type {WithPolicyProps} from '@pages/workspace/withPolicy';
-import withPolicyConnections from '@pages/workspace/withPolicyConnections';
-import CONST from '@src/CONST';
-import type {TranslationPaths} from '@src/languages/types';
-import ROUTES from '@src/ROUTES';
-
-function XeroMapCostCentersToConfigurationPage({policy}: WithPolicyProps) {
- const {translate} = useLocalize();
- const styles = useThemeStyles();
-
- const policyID = policy?.id ?? '';
-
- const category = getTrackingCategory(policy, CONST.XERO_CONFIG.TRACKING_CATEGORY_FIELDS.COST_CENTERS);
-
- const optionsList = useMemo(
- () =>
- Object.values(CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS).map((option) => ({
- value: option,
- text: translate(`workspace.xero.trackingCategoriesOptions.${option.toLowerCase()}` as TranslationPaths),
- keyForList: option,
- isSelected: option.toLowerCase() === category?.value?.toLowerCase(),
- })),
- [translate, category],
- );
-
- const updateMapping = useCallback(
- (option: {value: string}) => {
- if (option.value !== category?.value) {
- Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.MAPPINGS, {
- ...(policy?.connections?.xero?.config?.mappings ?? {}),
- ...(category?.id ? {[`${CONST.XERO_CONFIG.TRACKING_CATEGORY_PREFIX}${category.id}`]: option.value} : {}),
- });
- }
- Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES.getRoute(policyID));
- },
- [category, policyID, policy?.connections?.xero?.config?.mappings],
- );
-
- return (
-
- option.isSelected)?.keyForList}
- />
-
- );
-}
-
-XeroMapCostCentersToConfigurationPage.displayName = 'XeroMapCostCentersToConfigurationPage';
-export default withPolicyConnections(XeroMapCostCentersToConfigurationPage);
diff --git a/src/pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage.tsx
deleted file mode 100644
index 5c97de36d353..000000000000
--- a/src/pages/workspace/accounting/xero/XeroMapRegionsToConfigurationPage.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import React, {useCallback, useMemo} from 'react';
-import ConnectionLayout from '@components/ConnectionLayout';
-import SelectionList from '@components/SelectionList';
-import RadioListItem from '@components/SelectionList/RadioListItem';
-import useLocalize from '@hooks/useLocalize';
-import useThemeStyles from '@hooks/useThemeStyles';
-import * as Connections from '@libs/actions/connections';
-import {getTrackingCategory} from '@libs/actions/connections/ConnectToXero';
-import Navigation from '@libs/Navigation/Navigation';
-import type {WithPolicyProps} from '@pages/workspace/withPolicy';
-import withPolicyConnections from '@pages/workspace/withPolicyConnections';
-import CONST from '@src/CONST';
-import type {TranslationPaths} from '@src/languages/types';
-import ROUTES from '@src/ROUTES';
-
-function XeroMapRegionsToConfigurationPage({policy}: WithPolicyProps) {
- const {translate} = useLocalize();
- const styles = useThemeStyles();
-
- const policyID = policy?.id ?? '';
- const category = getTrackingCategory(policy, CONST.XERO_CONFIG.TRACKING_CATEGORY_FIELDS.REGION);
-
- const optionsList = useMemo(
- () =>
- Object.values(CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS).map((option) => ({
- value: option,
- text: translate(`workspace.xero.trackingCategoriesOptions.${option.toLowerCase()}` as TranslationPaths),
- keyForList: option,
- isSelected: option.toLowerCase() === category?.value?.toLowerCase(),
- })),
- [translate, category],
- );
-
- const updateMapping = useCallback(
- (option: {value: string}) => {
- if (option.value !== category?.value) {
- Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.MAPPINGS, {
- ...(policy?.connections?.xero?.config?.mappings ?? {}),
- ...(category?.id ? {[`${CONST.XERO_CONFIG.TRACKING_CATEGORY_PREFIX}${category.id}`]: option.value} : {}),
- });
- }
- Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES.getRoute(policyID));
- },
- [category, policyID, policy?.connections?.xero?.config?.mappings],
- );
-
- return (
-
- option.isSelected)?.keyForList}
- />
-
- );
-}
-
-XeroMapRegionsToConfigurationPage.displayName = 'XeroMapRegionsToConfigurationPage';
-export default withPolicyConnections(XeroMapRegionsToConfigurationPage);
From be8013448754349cde689f2849c321ff07d7aa56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucien=20Akchot=C3=A9?=
Date: Fri, 24 May 2024 15:37:28 +0200
Subject: [PATCH 134/207] make the handling of tracking categories dynamic
---
.../accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
index 572ec476d632..b8705cd87d5c 100644
--- a/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
@@ -67,6 +67,7 @@ function XeroMapTrackingCategoryConfigurationPage({policy}: WithPolicyProps) {
sections={[{data: optionsList}]}
ListItem={RadioListItem}
onSelectRow={updateMapping}
+ initiallyFocusedOptionKey={optionsList.find((option) => option.isSelected)?.keyForList}
/>
);
From 5d82268249a1b9435c1cc0a77f5ba183ac6fafdc Mon Sep 17 00:00:00 2001
From: Manan Jadhav
Date: Sat, 25 May 2024 01:18:24 +0530
Subject: [PATCH 135/207] fix: revert in-line text
---
.../workspace/WorkspaceMoreFeaturesPage.tsx | 29 -------------------
1 file changed, 29 deletions(-)
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
index 2f2a4b7e68e3..3f07889076b5 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
@@ -50,7 +50,6 @@ type SectionObject = {
titleTranslationKey: TranslationPaths;
subtitleTranslationKey: TranslationPaths;
items: Item[];
- footer?: React.ReactNode;
};
function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPageProps) {
@@ -63,31 +62,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
const policyID = policy?.id ?? '';
const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config.syncTax || !!policy?.connections?.xero?.config.importTaxRates;
- const renderIntegrationFooter = () => (
-
- {hasAccountingConnection ? (
-
-
-
-