From 7ccadb2c75d7e176f8326df45a11677344044334 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Tue, 2 Apr 2024 15:02:27 +0500 Subject: [PATCH 0001/1260] temp feature --- assets/images/receipt-location-marker.svg | 134 ++++++++++++++++++ src/components/LocationPermissionModal.tsx | 48 +++++++ ...oraryForRefactorRequestConfirmationList.js | 2 + 3 files changed, 184 insertions(+) create mode 100644 assets/images/receipt-location-marker.svg create mode 100644 src/components/LocationPermissionModal.tsx diff --git a/assets/images/receipt-location-marker.svg b/assets/images/receipt-location-marker.svg new file mode 100644 index 000000000000..674db76464f7 --- /dev/null +++ b/assets/images/receipt-location-marker.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/LocationPermissionModal.tsx b/src/components/LocationPermissionModal.tsx new file mode 100644 index 000000000000..f73289a22aee --- /dev/null +++ b/src/components/LocationPermissionModal.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import LocationMarker from '@assets/images/receipt-location-marker.svg'; +import ConfirmModal from './ConfirmModal'; + +type LocationPermissionModalProps = { + /** A callback to call when the form has been submitted */ + onConfirm: () => void; + + /** A callback to call when the form has been closed */ + onCancel?: () => void; + + /** Modal visibility */ + isVisible: boolean; + + /** Callback method fired when the modal is hidden */ + onModalHide?: () => void; + + /** Should we announce the Modal visibility changes? */ + shouldSetModalVisibility?: boolean; +}; + +function LocationPermissionModal({ + shouldSetModalVisibility = true, + onModalHide = () => {}, + isVisible, + onConfirm, + onCancel, +}: LocationPermissionModalProps) { + + return ( + + ); +} + +LocationPermissionModal.displayName = 'LocationPermissionModal'; + +export default LocationPermissionModal; diff --git a/src/components/MoneyTemporaryForRefactorRequestConfirmationList.js b/src/components/MoneyTemporaryForRefactorRequestConfirmationList.js index 3fd76eea657b..fed91f87677e 100755 --- a/src/components/MoneyTemporaryForRefactorRequestConfirmationList.js +++ b/src/components/MoneyTemporaryForRefactorRequestConfirmationList.js @@ -31,6 +31,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import Button from './Button'; +import LocationPermissionModal from './LocationPermissionModal'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import categoryPropTypes from './categoryPropTypes'; import ConfirmedRoute from './ConfirmedRoute'; @@ -978,6 +979,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({ )} {shouldShowAllFields && supplementaryFields} + {}} isVisible /> Date: Tue, 9 Apr 2024 01:06:06 +0500 Subject: [PATCH 0002/1260] design ready --- src/components/ConfirmContent.tsx | 63 +++++++++++++++++-- src/components/ConfirmModal.tsx | 30 +++++++++ src/components/LocationPermissionModal.tsx | 29 +++++---- ...oraryForRefactorRequestConfirmationList.js | 7 ++- src/languages/en.ts | 5 ++ src/languages/es.ts | 5 ++ 6 files changed, 119 insertions(+), 20 deletions(-) diff --git a/src/components/ConfirmContent.tsx b/src/components/ConfirmContent.tsx index 26331f92401c..adade9fc09c5 100644 --- a/src/components/ConfirmContent.tsx +++ b/src/components/ConfirmContent.tsx @@ -14,8 +14,11 @@ import type IconAsset from '@src/types/utils/IconAsset'; import Button from './Button'; import Header from './Header'; import Icon from './Icon'; +import {Close} from './Icon/Expensicons'; import ImageSVG from './ImageSVG'; +import {PressableWithoutFeedback} from './Pressable'; import Text from './Text'; +import Tooltip from './Tooltip'; type ConfirmContentProps = { /** Title of the modal */ @@ -51,15 +54,33 @@ type ConfirmContentProps = { /** Icon to display above the title */ iconSource?: IconAsset; + /** Icon width */ + iconWidth?: number; + + /** Icon height */ + iconHeight?: number; + + /** Should the icon be centered? */ + shouldCenterIcon?: boolean; + /** Whether to center the icon / text content */ shouldCenterContent?: boolean; + /** Whether to show the dismiss icon */ + shouldShowDismissIcon?: boolean; + /** Whether to stack the buttons */ shouldStackButtons?: boolean; + /** Whether to reverse the order of the stacked buttons */ + shouldReverseStackedButtons?: boolean; + /** Styles for title */ titleStyles?: StyleProp; + /** Styles for title container */ + titleContainerStyles?: StyleProp; + /** Styles for prompt */ promptStyles?: StyleProp; @@ -91,7 +112,13 @@ function ConfirmContent({ promptStyles, contentStyles, iconAdditionalStyles, + iconWidth = variables.appModalAppIconSize, + iconHeight = variables.appModalAppIconSize, + shouldCenterIcon = false, + shouldShowDismissIcon = false, image, + titleContainerStyles, + shouldReverseStackedButtons = false, }: ConfirmContentProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -116,19 +143,35 @@ function ConfirmContent({ )} + {shouldShowDismissIcon && ( + + + + + + + + )} {typeof iconSource === 'function' && ( - + )} - +
+ {shouldShowCancelButton && shouldReverseStackedButtons && ( + + + + + + ); +} + +export default EmptyStateComponent; diff --git a/src/components/EmptyStateComponent/types.ts b/src/components/EmptyStateComponent/types.ts new file mode 100644 index 000000000000..7a7cc9b4ff57 --- /dev/null +++ b/src/components/EmptyStateComponent/types.ts @@ -0,0 +1,29 @@ +import type DotLottieAnimation from '@components/LottieAnimations/types'; +import type SearchRowSkeleton from '@components/Skeletons/SearchRowSkeleton'; +import type TableRowSkeleton from '@components/Skeletons/TableRowSkeleton'; +import type IconAsset from '@src/types/utils/IconAsset'; + +type ValidSkeletons = typeof SearchRowSkeleton | typeof TableRowSkeleton; +type MediaTypes = 'video' | 'illustration' | 'animation'; + +type SharedProps = { + SkeletonComponent: ValidSkeletons; + titleText: string; + subtitleText: string; + buttonText?: string; + buttonAction?: () => void; + headerMediaType: T; +}; + +type MediaType = SharedProps & { + headerMedia: HeaderMedia; +}; + +type VideoProps = MediaType; +type IllustrationProps = MediaType; +type AnimationProps = MediaType; + +type EmptyStateComponentProps = VideoProps | IllustrationProps | AnimationProps; + +// eslint-disable-next-line import/prefer-default-export +export type {EmptyStateComponentProps}; diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index b4da5c0b0fa2..f49f74a6724a 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -1,4 +1,4 @@ -import type {ImageContentFit} from 'expo-image'; +import type {ImageContentFit, ImageStyle} from 'expo-image'; import React from 'react'; import type {StyleProp, ViewStyle} from 'react-native'; import {View} from 'react-native'; diff --git a/src/components/OptionsListSkeletonView.tsx b/src/components/OptionsListSkeletonView.tsx index 1f09876b18d3..8b2a53b5c59e 100644 --- a/src/components/OptionsListSkeletonView.tsx +++ b/src/components/OptionsListSkeletonView.tsx @@ -17,12 +17,14 @@ function getLinedWidth(index: number): string { type OptionsListSkeletonViewProps = { shouldAnimate?: boolean; + gradientOpacity?: boolean; }; -function OptionsListSkeletonView({shouldAnimate = true}: OptionsListSkeletonViewProps) { +function OptionsListSkeletonView({shouldAnimate = true, gradientOpacity = false}: OptionsListSkeletonViewProps) { return ( { const lineWidth = getLinedWidth(itemIndex); diff --git a/src/components/Search.tsx b/src/components/Search.tsx index e4faa15bfb94..442bc5937b76 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -14,7 +14,6 @@ import * as SearchUtils from '@libs/SearchUtils'; import type {SearchColumnType, SortOrder} from '@libs/SearchUtils'; import Navigation from '@navigation/Navigation'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; -import EmptySearchView from '@pages/Search/EmptySearchView'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -23,10 +22,12 @@ import type {SearchQuery} from '@src/types/onyx/SearchResults'; import type SearchResults from '@src/types/onyx/SearchResults'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; +import EmptyStateComponent from './EmptyStateComponent'; import SelectionList from './SelectionList'; import SearchTableHeader from './SelectionList/SearchTableHeader'; import type {ReportListItemType, TransactionListItemType} from './SelectionList/types'; -import TableListItemSkeleton from './Skeletons/TableListItemSkeleton'; +import SearchRowSkeleton from './Skeletons/SearchRowSkeleton'; +import TableRowSkeleton from './Skeletons/TableRowSkeleton'; type SearchProps = { query: SearchQuery; @@ -97,11 +98,21 @@ function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) { const shouldShowEmptyState = !isLoadingItems && isEmptyObject(searchResults?.data); if (isLoadingItems) { - return ; + return ; } if (shouldShowEmptyState) { - return ; + return ( + Navigation.navigate(ROUTES.CONCIERGE)} + buttonText="Go to Workspaces" + /> + ); } const openReport = (item: TransactionListItemType | ReportListItemType) => { @@ -188,7 +199,7 @@ function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) { onEndReached={fetchMoreResults} listFooterContent={ isLoadingMoreItems ? ( - diff --git a/src/components/Skeletons/ItemListSkeletonView.tsx b/src/components/Skeletons/ItemListSkeletonView.tsx index 5c46dbdddbfc..62e1e5afad13 100644 --- a/src/components/Skeletons/ItemListSkeletonView.tsx +++ b/src/components/Skeletons/ItemListSkeletonView.tsx @@ -1,5 +1,6 @@ import React, {useMemo, useState} from 'react'; import {View} from 'react-native'; +import type {StyleProp, ViewStyle} from 'react-native'; import SkeletonViewContentLoader from '@components/SkeletonViewContentLoader'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -9,9 +10,19 @@ type ListItemSkeletonProps = { shouldAnimate?: boolean; renderSkeletonItem: (args: {itemIndex: number}) => React.ReactNode; fixedNumItems?: number; + gradientOpacity?: boolean; + itemViewStyle?: StyleProp; + itemViewHeight?: number; }; -function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem, fixedNumItems}: ListItemSkeletonProps) { +function ItemListSkeletonView({ + shouldAnimate = true, + renderSkeletonItem, + fixedNumItems, + gradientOpacity = false, + itemViewStyle = {}, + itemViewHeight = CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT, +}: ListItemSkeletonProps) { const theme = useTheme(); const themeStyles = useThemeStyles(); @@ -19,22 +30,25 @@ function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem, fixedNu const skeletonViewItems = useMemo(() => { const items = []; for (let i = 0; i < numItems; i++) { + const opacity = gradientOpacity ? 1 - i / numItems : 1; items.push( - - {renderSkeletonItem({itemIndex: i})} - , + + + + {renderSkeletonItem({itemIndex: i})} + + + , ); } return items; - }, [numItems, shouldAnimate, theme, themeStyles, renderSkeletonItem]); - + }, [numItems, shouldAnimate, theme, themeStyles, renderSkeletonItem, gradientOpacity, itemViewHeight, itemViewStyle]); return ( ( <> ( + <> + + + + + )} + /> + ); +} + +TableListItemSkeleton.displayName = 'TableListItemSkeleton'; + +export default TableListItemSkeleton; diff --git a/src/styles/index.ts b/src/styles/index.ts index b031e665594f..a12090ff275f 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -1663,6 +1663,7 @@ const styles = (theme: ThemeColors) => welcomeVideoNarrowLayout: { width: variables.onboardingModalWidth, + height: 500, }, onlyEmojisText: { @@ -5033,6 +5034,28 @@ const styles = (theme: ThemeColors) => fontSize: variables.fontSizeNormal, fontWeight: FontUtils.fontWeight.bold, }, + + skeletonBackground: { + flex: 1, + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%', + }, + + emptyStateForeground: (isSmallScreenWidth: boolean) => ({ + justifyContent: 'center', + alignItems: 'center', + height: '100%', + padding: isSmallScreenWidth ? 24 : 0, + }), + + emptyStateContent: (isSmallScreenWidth: boolean) => ({ + width: isSmallScreenWidth ? '100%' : 400, + backgroundColor: theme.cardBG, + borderRadius: variables.componentBorderRadiusLarge, + }), } satisfies Styles); type ThemeStyles = ReturnType; From 6d91057bf954ea8979b7da97de69a35382b3526c Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 20 Jun 2024 17:08:26 +0700 Subject: [PATCH 0149/1260] check active route approach --- src/components/ReportActionItem/TaskView.tsx | 6 ++++++ src/components/TaskHeaderActionButton.tsx | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/TaskView.tsx b/src/components/ReportActionItem/TaskView.tsx index 43e896fe6578..ebe442dd8d75 100644 --- a/src/components/ReportActionItem/TaskView.tsx +++ b/src/components/ReportActionItem/TaskView.tsx @@ -96,6 +96,12 @@ function TaskView({report, ...props}: TaskViewProps) { { + if ( + Navigation.isActiveRoute(ROUTES.TASK_ASSIGNEE.getRoute(report.reportID)) || + Navigation.isActiveRoute(ROUTES.REPORT_DESCRIPTION.getRoute(report.reportID)) + ) { + return; + } if (isCompleted) { Task.reopenTask(report); } else { diff --git a/src/components/TaskHeaderActionButton.tsx b/src/components/TaskHeaderActionButton.tsx index 0c7e603a4aa2..ccf3e22ecc5f 100644 --- a/src/components/TaskHeaderActionButton.tsx +++ b/src/components/TaskHeaderActionButton.tsx @@ -4,10 +4,12 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import * as Session from '@userActions/Session'; import * as Task from '@userActions/Task'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import Button from './Button'; @@ -36,7 +38,16 @@ function TaskHeaderActionButton({report, session}: TaskHeaderActionButtonProps) isDisabled={!Task.canModifyTask(report, session?.accountID ?? -1)} medium text={translate(ReportUtils.isCompletedTaskReport(report) ? 'task.markAsIncomplete' : 'task.markAsComplete')} - onPress={Session.checkIfActionIsAllowed(() => (ReportUtils.isCompletedTaskReport(report) ? Task.reopenTask(report) : Task.completeTask(report)))} + onPress={Session.checkIfActionIsAllowed(() => { + if (Navigation.isActiveRoute(ROUTES.TASK_ASSIGNEE.getRoute(report.reportID)) || Navigation.isActiveRoute(ROUTES.REPORT_DESCRIPTION.getRoute(report.reportID))) { + return; + } + if (ReportUtils.isCompletedTaskReport(report)) { + Task.reopenTask(report); + } else { + Task.completeTask(report); + } + })} style={styles.flex1} /> From 0308f12e27abcd6e6486ebf1d37ebec5a79bcd16 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 20 Jun 2024 17:19:06 +0700 Subject: [PATCH 0150/1260] remove redundant changes --- src/components/MenuItem.tsx | 10 +- src/pages/home/ReportScreen.tsx | 4 +- src/pages/settings/Profile/ProfilePage.tsx | 101 +++++++++++---------- 3 files changed, 61 insertions(+), 54 deletions(-) diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index fad11c8e3a79..c1fe4270d4e1 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -394,7 +394,7 @@ function MenuItem( const StyleUtils = useStyleUtils(); const combinedStyle = [styles.popoverMenuItem, style]; const {shouldUseNarrowLayout} = useResponsiveLayout(); - const {isExecuting, singleExecution} = useContext(MenuItemGroupContext) ?? {}; + const {isExecuting, singleExecution, waitForNavigate} = useContext(MenuItemGroupContext) ?? {}; const isDeleted = style && Array.isArray(style) ? style.includes(styles.offlineFeedback.deleted) : false; const descriptionVerticalMargin = shouldShowDescriptionOnTop ? styles.mb1 : styles.mt1; @@ -469,11 +469,15 @@ function MenuItem( } if (onPress && event) { - if (!singleExecution) { + if (!singleExecution || !waitForNavigate) { onPress(event); return; } - singleExecution(onPress)(event); + singleExecution( + waitForNavigate(() => { + onPress(event); + }), + )(); } }; diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 20d4f1fa175e..ade50c0e2c9b 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -719,8 +719,8 @@ function ReportScreen({ )} {/* Note: The ReportActionsSkeletonView should be allowed to mount even if the initial report actions are not loaded. - If we prevent rendering the report while they are loading then - we'll unnecessarily unmount the ReportActionsView which will clear the new marker lines initial state. */} + If we prevent rendering the report while they are loading then + we'll unnecessarily unmount the ReportActionsView which will clear the new marker lines initial state. */} {shouldShowSkeleton && } {isCurrentReportLoadedFromOnyx ? ( diff --git a/src/pages/settings/Profile/ProfilePage.tsx b/src/pages/settings/Profile/ProfilePage.tsx index 011d5956be58..4c5ed88e6898 100755 --- a/src/pages/settings/Profile/ProfilePage.tsx +++ b/src/pages/settings/Profile/ProfilePage.tsx @@ -5,6 +5,7 @@ import {withOnyx} from 'react-native-onyx'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Illustrations from '@components/Icon/Illustrations'; +import MenuItemGroup from '@components/MenuItemGroup'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; @@ -135,55 +136,57 @@ function ProfilePage({ icon={Illustrations.Profile} /> - -
- {publicOptions.map((detail, index) => ( - Navigation.navigate(detail.pageRoute)} - brickRoadIndicator={detail.brickRoadIndicator} - /> - ))} -
-
- {isLoadingApp ? ( - - ) : ( - <> - {privateOptions.map((detail, index) => ( - Navigation.navigate(detail.pageRoute)} - /> - ))} - - )} -
-
+ + +
+ {publicOptions.map((detail, index) => ( + Navigation.navigate(detail.pageRoute)} + brickRoadIndicator={detail.brickRoadIndicator} + /> + ))} +
+
+ {isLoadingApp ? ( + + ) : ( + <> + {privateOptions.map((detail, index) => ( + Navigation.navigate(detail.pageRoute)} + /> + ))} + + )} +
+
+
); From d815a068568f27edf32e714a15d24b583ae21fe3 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Thu, 20 Jun 2024 19:12:42 +0200 Subject: [PATCH 0151/1260] add mapping pages --- src/CONST.ts | 16 +++++ src/ROUTES.ts | 10 +++ src/SCREENS.ts | 4 +- .../ModalStackNavigators/index.tsx | 4 ++ .../FULL_SCREEN_TO_RHP_MAPPING.ts | 2 + src/libs/Navigation/linkingConfig/config.ts | 2 + src/libs/Navigation/types.ts | 8 +++ .../intacct/import/SageIntacctImportPage.tsx | 15 +++-- .../import/SageIntacctMappingsTypePage.tsx | 64 +++++++++++++++++++ .../import/SageIntacctToggleMappingsPage.tsx | 59 +++++++++++++++++ src/types/onyx/Policy.ts | 36 ++++++----- 11 files changed, 197 insertions(+), 23 deletions(-) create mode 100644 src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx create mode 100644 src/pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage.tsx diff --git a/src/CONST.ts b/src/CONST.ts index 0b71123c7a9f..5da604569236 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1346,6 +1346,22 @@ const CONST = { }, }, + SAGE_INTACCT_CONFIG: { + MAPPING_VALUE: { + NONE: 'NONE', + DEFAULT: 'DEFAULT', + TAG: 'TAG', + REPORT_FIELD: 'REPORT_FIELD', + }, + MAPPINGS: { + DEPARTMENTS: 'departments', + CLASSES: 'classes', + LOCATIONS: 'locations', + CUSTOMERS: 'customers', + PROJECTS: 'projects', + }, + }, + QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE: { VENDOR_BILL: 'bill', CHECK: 'check', diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 6342d27b7448..1052a2e92e27 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -912,6 +912,16 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/sage-intacct/import', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/sage-intacct/import` as const, }, + POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS: { + route: 'settings/workspaces/:policyID/accounting/sage-intacct/import/toggle-mapping/:mapping', + getRoute: (policyID: string, mapping: ValueOf) => + `settings/workspaces/${policyID}/accounting/sage-intacct/import/toggle-mapping/${mapping}` as const, + }, + POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE: { + route: 'settings/workspaces/:policyID/accounting/sage-intacct/import/mapping-type/:mapping', + getRoute: (policyID: string, mapping: ValueOf) => + `settings/workspaces/${policyID}/accounting/sage-intacct/import/mapping-type/${mapping}` as const, + }, } as const; /** diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 7534593a14c5..c6dfe37642b5 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -263,7 +263,9 @@ const SCREENS = { XERO_EXPORT_PREFERRED_EXPORTER_SELECT: 'Workspace_Accounting_Xero_Export_Preferred_Exporter_Select', XERO_BILL_PAYMENT_ACCOUNT_SELECTOR: 'Policy_Accounting_Xero_Bill_Payment_Account_Selector', XERO_EXPORT_BANK_ACCOUNT_SELECT: 'Policy_Accounting_Xero_Export_Bank_Account_Select', - SAGE_INTACCT_IMPORT: 'Policy_Accounting_Sage_Import', + SAGE_INTACCT_IMPORT: 'Policy_Accounting_Sage_Intacct_Import', + SAGE_INTACCT_TOGGLE_MAPPING: 'Policy_Accounting_Sage_Intacct_Toggle_Mapping', + SAGE_INTACCT_MAPPING_TYPE: 'Policy_Accounting_Sage_Intacct_Mapping_Type', }, INITIAL: 'Workspace_Initial', PROFILE: 'Workspace_Profile', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 5d12a68dc527..9ead60059fa2 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -319,6 +319,10 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage').default as React.ComponentType, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_IMPORT]: () => require('../../../../pages/workspace/accounting/intacct/import/SageIntacctImportPage').default as React.ComponentType, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_TOGGLE_MAPPING]: () => + require('../../../../pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage').default as React.ComponentType, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_MAPPING_TYPE]: () => + require('../../../../pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage').default as React.ComponentType, [SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET]: () => require('../../../../pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage').default as React.ComponentType, [SCREENS.WORKSPACE.TAX_EDIT]: () => require('../../../../pages/workspace/taxes/WorkspaceEditTaxPage').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 49343973e656..d656c0cb12c9 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -55,6 +55,8 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.ACCOUNTING.XERO_BILL_PAYMENT_ACCOUNT_SELECTOR, SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT_BANK_ACCOUNT_SELECT, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_IMPORT, + SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_MAPPING_TYPE, + SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_TOGGLE_MAPPING, ], [SCREENS.WORKSPACE.TAXES]: [ SCREENS.WORKSPACE.TAXES_SETTINGS, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 89165b7865e0..33762640ce66 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -338,6 +338,8 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT_PREFERRED_EXPORTER_SELECT]: {path: ROUTES.POLICY_ACCOUNTING_XERO_PREFERRED_EXPORTER_SELECT.route}, [SCREENS.WORKSPACE.ACCOUNTING.XERO_BILL_PAYMENT_ACCOUNT_SELECTOR]: {path: ROUTES.POLICY_ACCOUNTING_XERO_BILL_PAYMENT_ACCOUNT_SELECTOR.route}, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_IMPORT]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_IMPORT.route}, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_MAPPING_TYPE]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.route}, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_TOGGLE_MAPPING]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS.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 04da914bf8b4..ee0bf2dca5a3 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -388,6 +388,14 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_IMPORT]: { policyID: string; }; + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_TOGGLE_MAPPING]: { + policyID: string; + mapping: ValueOf; + }; + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_MAPPING_TYPE]: { + policyID: string; + mapping: ValueOf; + }; [SCREENS.GET_ASSISTANCE]: { backTo: Routes; }; diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx index 3c4beb44e81c..4773634ee7bc 100644 --- a/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx +++ b/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx @@ -21,26 +21,31 @@ function SageIntacctImportPage({policy}: WithPolicyProps) { const {importCustomers, importTaxRates, importTrackingCategories, pendingFields, errorFields} = policy?.connections?.xero?.config ?? {}; const currentXeroOrganizationName = useMemo(() => getCurrentXeroOrganizationName(policy ?? undefined), [policy]); + console.log( + '%%%%%\n', + 'ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.DEPARTMENTS)', + ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.DEPARTMENTS), + ); const sections = useMemo( () => [ { description: 'Departments', - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_CHART_OF_ACCOUNTS.getRoute(policyID)), + action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.DEPARTMENTS)), title: 'Sage Intacct employee default', hasError: !!errorFields?.enableNewCategories, pendingAction: pendingFields?.enableNewCategories, }, { description: 'Classes', - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES.getRoute(policyID)), + action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CLASSES)), hasError: !!errorFields?.importTrackingCategories, pendingAction: pendingFields?.importTrackingCategories, }, { description: 'Locations', action: () => { - Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.getRoute(policyID)); + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.LOCATIONS)); }, hasError: !!errorFields?.importCustomers, title: 'Imported, displayed as tags', @@ -48,14 +53,14 @@ function SageIntacctImportPage({policy}: WithPolicyProps) { }, { description: 'Customers', - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_TAXES.getRoute(policyID)), + action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CUSTOMERS)), hasError: !!errorFields?.importTaxRates, title: 'Imported, displayed as report fields', pendingAction: pendingFields?.importTaxRates, }, { description: 'Projects (jobs)', - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_TAXES.getRoute(policyID)), + action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.PROJECTS)), hasError: !!errorFields?.importTaxRates, pendingAction: pendingFields?.importTaxRates, }, diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx new file mode 100644 index 000000000000..cdc24e849776 --- /dev/null +++ b/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx @@ -0,0 +1,64 @@ +import {useNavigationState} from '@react-navigation/native'; +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useMemo} from 'react'; +import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; +import ConnectionLayout from '@components/ConnectionLayout'; +import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@libs/Navigation/Navigation'; +import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; +import {getCurrentXeroOrganizationName} from '@libs/PolicyUtils'; +import withPolicy from '@pages/workspace/withPolicy'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; +import type {Policy} from '@src/types/onyx'; + +type SageIntacctMappingsTypePageProps = StackScreenProps; + +function SageIntacctMappingsTypePage({route}: SageIntacctMappingsTypePageProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + console.log('%%%%%\n', 'route', route.params.mapping); + + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${route.params.policyID ?? '-1'}`); + const policyID = policy?.id ?? '-1'; + + const currentXeroOrganizationName = useMemo(() => getCurrentXeroOrganizationName(policy ?? undefined), [policy]); + + return ( + + {}} + disabled + /> + + ); +} + +SageIntacctMappingsTypePage.displayName = 'PolicySageIntacctImportPage'; + +export default SageIntacctMappingsTypePage; diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage.tsx new file mode 100644 index 000000000000..4c9834814efb --- /dev/null +++ b/src/pages/workspace/accounting/intacct/import/SageIntacctToggleMappingsPage.tsx @@ -0,0 +1,59 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useMemo} from 'react'; +import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; +import ConnectionLayout from '@components/ConnectionLayout'; +import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@libs/Navigation/Navigation'; +import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; +import {getCurrentXeroOrganizationName} from '@libs/PolicyUtils'; +import withPolicy from '@pages/workspace/withPolicy'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; + +type SageIntacctToggleMappingsPageProps = StackScreenProps; + +function SageIntacctToggleMappingsPage({route}: SageIntacctToggleMappingsPageProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${route.params.policyID ?? '-1'}`); + console.log('%%%%%\n', 'route.params', route.params); + const policyID = policy?.id ?? '-1'; + + return ( + + {}} + disabled + /> + + ); +} + +SageIntacctToggleMappingsPage.displayName = 'PolicySageIntacctImportPage'; + +export default SageIntacctToggleMappingsPage; diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index a1e80feabc76..faf8d496e83b 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -633,26 +633,22 @@ type SageIntacctConnectionData = { taxSolutionIDs: string[]; }; -/** - * Sage Intacct credentials - */ -type SageIntacctCredentials = { - /** Sage Intacct companyID */ - companyID: string; +/** Mapping type for Sage Intacct */ +type SageIntacctMappingType = { + /** Mapping type for Sage Intacct */ + departments: ValueOf; - /** Sage Intacct password */ - password: string; + /** Mapping type for Sage Intacct */ + classes: ValueOf; - /** Sage Intacct userID */ - userID: string; -}; + /** Mapping type for Sage Intacct */ + locations: ValueOf; -/** - * Sage Intacct tax - */ -type SageIntacctTax = { - /** Sage Intacct tax solution ID */ - taxSolutionID: string; + /** Mapping type for Sage Intacct */ + customers: ValueOf; + + /** Mapping type for Sage Intacct */ + projects: ValueOf; }; /** @@ -683,10 +679,16 @@ type SageIntacctConnectiosConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{ userID: string; }; + /** Sage Intacct mappings */ + mappings: SageIntacctMappingType; + /** Sage Intacct tax */ tax: { /** Sage Intacct tax solution ID */ taxSolutionID: string; + + /** Whether should sync tax with Sage Intacct */ + syncTax: boolean; }; /** Configuration of automatic synchronization from Sage Intacct to the app */ From a245b253a4b3b0dec9c22046ab6aa764f5059797 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Tue, 7 May 2024 10:34:13 +0200 Subject: [PATCH 0152/1260] Add handling of actions to TransactionListItem --- .../Search/TransactionListItemRow.tsx | 65 ++++++++++++++++--- src/libs/SearchUtils.ts | 29 ++++++++- src/libs/actions/Search.ts | 23 ++++++- src/types/onyx/SearchResults.ts | 5 +- 4 files changed, 109 insertions(+), 13 deletions(-) diff --git a/src/components/SelectionList/Search/TransactionListItemRow.tsx b/src/components/SelectionList/Search/TransactionListItemRow.tsx index c0fff452d1e5..0a51adf0e6df 100644 --- a/src/components/SelectionList/Search/TransactionListItemRow.tsx +++ b/src/components/SelectionList/Search/TransactionListItemRow.tsx @@ -1,6 +1,7 @@ import React from 'react'; import type {StyleProp, ViewStyle} from 'react-native'; import {View} from 'react-native'; +import Badge from '@components/Badge'; import Button from '@components/Button'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -14,11 +15,13 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import DateUtils from '@libs/DateUtils'; +import * as SearchUtils from '@libs/SearchUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import type {SearchTransactionType} from '@src/types/onyx/SearchResults'; +import type {TranslationPaths} from '@src/languages/types'; +import type {SearchTransactionAction, SearchTransactionType} from '@src/types/onyx/SearchResults'; import ExpenseItemHeaderNarrow from './ExpenseItemHeaderNarrow'; import TextWithIconCell from './TextWithIconCell'; import UserInfoCell from './UserInfoCell'; @@ -35,8 +38,8 @@ type TransactionCellProps = { } & CellProps; type ActionCellProps = { - onButtonPress: () => void; -} & CellProps; + goToItem: () => void; +} & TransactionCellProps; type TotalCellProps = { isChildListItem: boolean; @@ -64,6 +67,18 @@ const getTypeIcon = (type?: SearchTransactionType) => { } }; +const actionTranslationsMap: Record = { + view: 'common.view', + // Todo add translation for Review + review: 'common.view', + done: 'common.done', + paid: 'iou.settledExpensify', + approve: 'iou.approve', + pay: 'iou.pay', + submit: 'common.submit', + hold: 'iou.hold', +}; + function ReceiptCell({transactionItem}: TransactionCellProps) { const theme = useTheme(); const styles = useThemeStyles(); @@ -148,17 +163,50 @@ function TypeCell({transactionItem, isLargeScreenWidth}: TransactionCellProps) { ); } -function ActionCell({onButtonPress}: ActionCellProps) { +function ActionCell({transactionItem, goToItem}: ActionCellProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); + const {action, amount} = transactionItem; + + const text = translate(actionTranslationsMap[action]); + + if (['done', 'paid'].includes(action)) { + return ( + + ); + } + + if (['view', 'review'].includes(action)) { + return ( + + {buttonText && buttonAction && ( + + )}
diff --git a/src/components/EmptyStateComponent/types.ts b/src/components/EmptyStateComponent/types.ts index 7a7cc9b4ff57..a3ef4ad75f59 100644 --- a/src/components/EmptyStateComponent/types.ts +++ b/src/components/EmptyStateComponent/types.ts @@ -1,3 +1,4 @@ +import type {StyleProp, ViewStyle} from 'react-native'; import type DotLottieAnimation from '@components/LottieAnimations/types'; import type SearchRowSkeleton from '@components/Skeletons/SearchRowSkeleton'; import type TableRowSkeleton from '@components/Skeletons/TableRowSkeleton'; @@ -12,6 +13,7 @@ type SharedProps = { subtitleText: string; buttonText?: string; buttonAction?: () => void; + headerStyles?: StyleProp; headerMediaType: T; }; diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index c3e50cff3178..3ac4e346ccb5 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -118,6 +118,7 @@ import Meter from '@assets/images/meter.svg'; import MoneyBag from '@assets/images/money-bag.svg'; import MoneyCircle from '@assets/images/money-circle.svg'; import MoneySearch from '@assets/images/money-search.svg'; +import MoneyStack from '@assets/images/money-stack.svg'; import MoneyWaving from '@assets/images/money-waving.svg'; import Monitor from '@assets/images/monitor.svg'; import Mute from '@assets/images/mute.svg'; @@ -366,4 +367,5 @@ export { Clear, CheckCircle, CheckmarkCircle, + MoneyStack, }; diff --git a/src/components/ImageSVG/index.tsx b/src/components/ImageSVG/index.tsx index 3ce04a1a190a..cf58aa873584 100644 --- a/src/components/ImageSVG/index.tsx +++ b/src/components/ImageSVG/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import type {SvgProps} from 'react-native-svg'; import type ImageSVGProps from './types'; -function ImageSVG({src, width = '100%', height = '100%', fill, hovered = false, pressed = false, style, pointerEvents, preserveAspectRatio}: ImageSVGProps) { +function ImageSVG({src, width, height = '100%', fill, hovered = false, pressed = false, style, pointerEvents, preserveAspectRatio}: ImageSVGProps) { const ImageSvgComponent = src as React.FC; const additionalProps: Pick = {}; diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 442bc5937b76..449dfb4dfe9f 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -3,6 +3,7 @@ import type {StackNavigationProp} from '@react-navigation/stack'; import React, {useCallback, useEffect, useRef} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; +import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; @@ -23,11 +24,11 @@ import type SearchResults from '@src/types/onyx/SearchResults'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; import EmptyStateComponent from './EmptyStateComponent'; +import LottieAnimations from './LottieAnimations'; import SelectionList from './SelectionList'; import SearchTableHeader from './SelectionList/SearchTableHeader'; import type {ReportListItemType, TransactionListItemType} from './SelectionList/types'; import SearchRowSkeleton from './Skeletons/SearchRowSkeleton'; -import TableRowSkeleton from './Skeletons/TableRowSkeleton'; type SearchProps = { query: SearchQuery; @@ -50,6 +51,7 @@ function isTransactionListItemType(item: TransactionListItemType | ReportListIte function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) { const {isOffline} = useNetwork(); const styles = useThemeStyles(); + const {translate} = useLocalize(); const {isLargeScreenWidth} = useWindowDimensions(); const navigation = useNavigation>(); const lastSearchResultsRef = useRef>(); @@ -105,12 +107,11 @@ function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) { return ( Navigation.navigate(ROUTES.CONCIERGE)} - buttonText="Go to Workspaces" + headerMediaType="animation" + headerMedia={LottieAnimations.Coin} + headerStyles={styles.activeComponentBG} + titleText={translate('search.searchResults.emptyState.title')} + subtitleText={translate('search.searchResults.emptyState.subtitle')} /> ); } diff --git a/src/components/Skeletons/ItemListSkeletonView.tsx b/src/components/Skeletons/ItemListSkeletonView.tsx index 62e1e5afad13..79b8dec1c183 100644 --- a/src/components/Skeletons/ItemListSkeletonView.tsx +++ b/src/components/Skeletons/ItemListSkeletonView.tsx @@ -1,6 +1,6 @@ -import React, {useMemo, useState} from 'react'; +import React, {useCallback, useMemo, useState} from 'react'; +import type {LayoutChangeEvent, StyleProp, ViewStyle} from 'react-native'; import {View} from 'react-native'; -import type {StyleProp, ViewStyle} from 'react-native'; import SkeletonViewContentLoader from '@components/SkeletonViewContentLoader'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -15,6 +15,14 @@ type ListItemSkeletonProps = { itemViewHeight?: number; }; +const getVerticalMargin = (style: StyleProp): number => { + if (!style) { + return 0; + } + const flattenStyle = style instanceof Array ? Object.assign({}, ...style) : style; + return Number((flattenStyle.marginVertical || 0) + (flattenStyle.marginTop || 0) + (flattenStyle.marginBottom || 0)); +}; + function ItemListSkeletonView({ shouldAnimate = true, renderSkeletonItem, @@ -27,13 +35,36 @@ function ItemListSkeletonView({ const themeStyles = useThemeStyles(); const [numItems, setNumItems] = useState(fixedNumItems ?? 0); + + const totalItemHeight = itemViewHeight + getVerticalMargin(itemViewStyle); + + const handleLayout = useCallback( + (event: LayoutChangeEvent) => { + if (fixedNumItems) { + return; + } + + const totalHeight = event.nativeEvent.layout.height; + + const newNumItems = Math.ceil(totalHeight / totalItemHeight); + + if (newNumItems !== numItems) { + setNumItems(newNumItems); + } + }, + [fixedNumItems, numItems, totalItemHeight], + ); + const skeletonViewItems = useMemo(() => { const items = []; for (let i = 0; i < numItems; i++) { const opacity = gradientOpacity ? 1 - i / numItems : 1; items.push( - - + + { - if (fixedNumItems) { - return; - } - - const newNumItems = Math.ceil(event.nativeEvent.layout.height / itemViewHeight); - if (newNumItems === numItems) { - return; - } - setNumItems(newNumItems); - }} + onLayout={handleLayout} > {skeletonViewItems} diff --git a/src/languages/en.ts b/src/languages/en.ts index 3a569801bb6a..3f0ca3299185 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2804,6 +2804,10 @@ export default { title: 'Nothing to show', subtitle: 'Try creating something using the green + button.', }, + emptyState: { + title: 'No expenses to display', + subtitle: 'Try creating something using the green + button.', + }, }, groupedExpenses: 'grouped expenses', }, diff --git a/src/languages/es.ts b/src/languages/es.ts index a2118d55e43c..ad4c3973a6fd 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2843,6 +2843,10 @@ export default { title: 'No hay nada que ver aquí', subtitle: 'Por favor intenta crear algo usando el botón verde.', }, + emptyState: { + title: 'Sin gastos de exposición', + subtitle: 'Intenta crear algo utilizando el botón verde.', + }, }, groupedExpenses: 'gastos agrupados', }, diff --git a/src/styles/index.ts b/src/styles/index.ts index a12090ff275f..5bf96be3d3c1 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -5056,6 +5056,11 @@ const styles = (theme: ThemeColors) => backgroundColor: theme.cardBG, borderRadius: variables.componentBorderRadiusLarge, }), + + emptyStateHeader: { + borderTopLeftRadius: variables.componentBorderRadiusLarge, + borderTopRightRadius: variables.componentBorderRadiusLarge, + }, } satisfies Styles); type ThemeStyles = ReturnType; From 264707ebffb3a1d99285c4f6b18775bbb769b838 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Mon, 24 Jun 2024 15:25:57 +0200 Subject: [PATCH 0167/1260] bump common and live-markdown --- package-lock.json | 19 +++++++++---------- package.json | 4 ++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd3055698f72..5584906d2ddd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@dotlottie/react-player": "^1.6.3", - "@expensify/react-native-live-markdown": "0.1.85", + "@expensify/react-native-live-markdown": "0.1.91", "@expo/metro-runtime": "~3.1.1", "@formatjs/intl-datetimeformat": "^6.10.0", "@formatjs/intl-listformat": "^7.2.2", @@ -60,7 +60,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "^2.0.12", + "expensify-common": "2.0.23", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.11.0", @@ -3562,9 +3562,9 @@ } }, "node_modules/@expensify/react-native-live-markdown": { - "version": "0.1.85", - "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.85.tgz", - "integrity": "sha512-jeP4JBzN34pGSpjHKM7Zj3d0cqcKbID3//WrqC+SI7SK/1iJT4SdhZptVCxUg+Dcxq5XwzYIhdnhTNimeya0Fg==", + "version": "0.1.91", + "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.91.tgz", + "integrity": "sha512-6uQTgwhpvLqQKdtNqSgh45sRuQRXzv/WwyhdvQNge6EYtulyGFqT82GIP+LIGW8Xnl73nzFZTuMKwWxFFR/Cow==", "workspaces": [ "parser", "example", @@ -20770,9 +20770,9 @@ } }, "node_modules/expensify-common": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/expensify-common/-/expensify-common-2.0.12.tgz", - "integrity": "sha512-idIm9mAGDX1qyfA2Ky/1ZJZVMbGydtpIdwl6zl1Yc7FO11IGvAYLh2cH9VsQk98AapRTiJu7QUaRWLLGDaHIcQ==", + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/expensify-common/-/expensify-common-2.0.23.tgz", + "integrity": "sha512-hhoumr9lyGcWoS81gUQlb894zzCdinKS1R+3a44pghMk7t3NbmYavuK6F5njH9nGYYfqU2I6Pb5rUGeDLa9wew==", "dependencies": { "awesome-phonenumber": "^5.4.0", "classnames": "2.5.0", @@ -20786,8 +20786,7 @@ "react-dom": "16.12.0", "semver": "^7.6.0", "simply-deferred": "git+https://github.com/Expensify/simply-deferred.git#77a08a95754660c7bd6e0b6979fdf84e8e831bf5", - "ua-parser-js": "^1.0.37", - "underscore": "1.13.6" + "ua-parser-js": "^1.0.37" } }, "node_modules/expensify-common/node_modules/react": { diff --git a/package.json b/package.json index 0b463d950cfc..fc75695dbff4 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@dotlottie/react-player": "^1.6.3", - "@expensify/react-native-live-markdown": "0.1.85", + "@expensify/react-native-live-markdown": "0.1.91", "@expo/metro-runtime": "~3.1.1", "@formatjs/intl-datetimeformat": "^6.10.0", "@formatjs/intl-listformat": "^7.2.2", @@ -112,7 +112,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "^2.0.12", + "expensify-common": "2.0.23", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.11.0", From 364708b1fdaac03ee37c216e2d30b62363b4d828 Mon Sep 17 00:00:00 2001 From: Kaushik Kapadiya Date: Mon, 24 Jun 2024 18:57:11 +0530 Subject: [PATCH 0168/1260] Reset amount on reset button click --- src/components/MoneyRequestAmountInput.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index ec38c04ec8e2..5a8d3742b5f8 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -9,7 +9,6 @@ import getOperatingSystem from '@libs/getOperatingSystem'; import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; import shouldIgnoreSelectionWhenUpdatedManually from '@libs/shouldIgnoreSelectionWhenUpdatedManually'; import CONST from '@src/CONST'; -import isTextInputFocused from './TextInput/BaseTextInput/isTextInputFocused'; import type {BaseTextInputRef} from './TextInput/BaseTextInput/types'; import TextInputWithCurrencySymbol from './TextInputWithCurrencySymbol'; @@ -107,7 +106,7 @@ const getNewSelection = (oldSelection: Selection, prevLength: number, newLength: return {start: cursorPosition, end: cursorPosition}; }; -const defaultOnFormatAmount = (amount: number) => CurrencyUtils.convertToFrontendAmountAsString(amount); +const defaultOnFormatAmount = (amount: number, currency?: string): string => CurrencyUtils.convertToFrontendAmountAsString(amount); function MoneyRequestAmountInput( { From 52d8765c80a391fa1330bf368917506aa2882df5 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 24 Jun 2024 15:27:33 +0200 Subject: [PATCH 0169/1260] add default vendor for reimbursable expenses (and unify this page) --- src/ROUTES.ts | 6 +- src/SCREENS.ts | 2 +- .../ModalStackNavigators/index.tsx | 3 +- .../FULL_SCREEN_TO_RHP_MAPPING.ts | 2 +- src/libs/Navigation/linkingConfig/config.ts | 2 +- src/libs/Navigation/types.ts | 3 +- src/libs/PolicyUtils.ts | 21 ++--- .../intacct/export/SageIntacctDatePage.tsx | 2 +- ...e.tsx => SageIntacctDefaultVendorPage.tsx} | 69 +++++++++----- .../intacct/export/SageIntacctExportPage.tsx | 10 +- ...SageIntacctNonReimbursableExpensesPage.tsx | 45 +++++---- .../SageIntacctReimbursableExpensesPage.tsx | 93 +++++++++++++++---- src/types/onyx/Policy.ts | 79 +++++++++++++++- 13 files changed, 245 insertions(+), 92 deletions(-) rename src/pages/workspace/accounting/intacct/export/{SageIntacctNonReimbursableDefaultVendorPage.tsx => SageIntacctDefaultVendorPage.tsx} (50%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index cced1dddfa36..515661e93152 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -933,9 +933,9 @@ const ROUTES = { route: 'settings/workspaces/:policyID/connections/sage-intacct/export/non-reimbursable', getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/sage-intacct/export/non-reimbursable` as const, }, - POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_DEFAULT_VENDOR: { - route: 'settings/workspaces/:policyID/connections/sage-intacct/export/non-reimbursable/default-vendor', - getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/sage-intacct/export/non-reimbursable/default-vendor` as const, + POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR: { + route: 'settings/workspaces/:policyID/connections/sage-intacct/export/:reimbursable/default-vendor', + getRoute: (policyID: string, reimbursable: string) => `settings/workspaces/${policyID}/connections/sage-intacct/export/${reimbursable}/default-vendor` as const, }, POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT: { route: 'settings/workspaces/:policyID/connections/sage-intacct/export/non-reimbursable/credit-card-account', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 79d59e587f46..e7acea4185cb 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -273,7 +273,7 @@ const SCREENS = { SAGE_INTACCT_EXPORT_DATE: 'Policy_Accounting_Sage_Intacct_Export_Date', SAGE_INTACCT_REIMBURSABLE_EXPENSES: 'Policy_Accounting_Sage_Intacct_Reimbursable_Expenses', SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES: 'Policy_Accounting_Sage_Intacct_Non_Reimbursable_Expenses', - SAGE_INTACCT_NON_REIMBURSABLE_DEFAULT_VENDOR: 'Policy_Accounting_Sage_Intacct_Non_Reimbursable_Default_Vendor', + SAGE_INTACCT_DEFAULT_VENDOR: 'Policy_Accounting_Sage_Intacct_Default_Vendor', SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT: 'Policy_Accounting_Sage_Intacct_Non_Reimbursable_Credit_Card_Account', }, INITIAL: 'Workspace_Initial', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 63b38c06e55e..70cf6b6a5cfe 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -326,8 +326,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('@pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage').default as React.ComponentType, - [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_DEFAULT_VENDOR]: () => - require('@pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableDefaultVendorPage').default as React.ComponentType, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_DEFAULT_VENDOR]: () => require('@pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage').default as React.ComponentType, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT]: () => require('@pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage').default as React.ComponentType, [SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY]: () => require('../../../../pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage').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 2c4294e24c7f..7882b92bbc6d 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -59,7 +59,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_EXPORT_DATE, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_REIMBURSABLE_EXPENSES, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES, - SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_DEFAULT_VENDOR, + SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_DEFAULT_VENDOR, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT, ], [SCREENS.WORKSPACE.TAXES]: [ diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 3790e529caef..7104e7bf4b65 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -342,7 +342,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_EXPORT_DATE]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT_DATE.route}, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_REIMBURSABLE_EXPENSES]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_REIMBURSABLE_EXPENSES.route}, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.route}, - [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_DEFAULT_VENDOR]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_DEFAULT_VENDOR.route}, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_DEFAULT_VENDOR]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR.route}, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT]: { path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 34805c979a07..deb5c2d431ba 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -400,8 +400,9 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES]: { policyID: string; }; - [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_DEFAULT_VENDOR]: { + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_DEFAULT_VENDOR]: { policyID: string; + reimbursable: string; }; [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT]: { policyID: string; diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 4753658d59af..2d21e2da8197 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -461,7 +461,7 @@ function getXeroBankAccountsWithDefaultSelect(policy: Policy | undefined, select })); } -function getSageIntacctVendors(policy: Policy | undefined, selectedVendorId: string | undefined): SelectorType[] { +function getSageIntacctVendors(policy: Policy | undefined, selectedVendorId: string | null | undefined): SelectorType[] { const vendors = policy?.connections?.intacct?.data?.vendors ?? []; const isMatchFound = vendors?.some(({id}) => id === selectedVendorId); @@ -473,25 +473,24 @@ function getSageIntacctVendors(policy: Policy | undefined, selectedVendorId: str })); } -function getSageIntacctActiveDefaultVendor(policy: Policy | undefined): string | null { +function getSageIntacctNonReimbursableActiveDefaultVendor(policy: Policy | undefined): string | null | undefined { const { nonReimbursableCreditCardChargeDefaultVendor: creditCardDefaultVendor, - nonReimbursableExpenseReportDefaultVendor: expenseReportDefaultVendor, + nonReimbursableVendor: expenseReportDefaultVendor, nonReimbursable, } = policy?.connections?.intacct?.config.export ?? {}; return nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE ? creditCardDefaultVendor : expenseReportDefaultVendor; } -function getSageIntacctCreditCards(policy: Policy | undefined, selectedAccountId: string | undefined): SelectorType[] { +function getSageIntacctCreditCards(policy: Policy | undefined, selectedAccount: string | undefined): SelectorType[] { const creditCards = policy?.connections?.intacct?.data?.creditCards ?? []; - const isMatchFound = creditCards?.some(({id}) => id === selectedAccountId); + const isMatchFound = creditCards?.some(({name}) => name === selectedAccount); - return (creditCards ?? []).map(({id, name}) => ({ - value: id, - text: name, - keyForList: id, - isSelected: isMatchFound && selectedAccountId === id, + return (creditCards ?? []).map(({name}) => ({ + value: name, + keyForList: name, + isSelected: isMatchFound && name === selectedAccount, })); } @@ -581,7 +580,7 @@ export { getCurrentXeroOrganizationName, getXeroBankAccountsWithDefaultSelect, getSageIntacctVendors, - getSageIntacctActiveDefaultVendor, + getSageIntacctNonReimbursableActiveDefaultVendor, getSageIntacctCreditCards, getCustomUnit, getCustomUnitRate, diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx index 7a8cebfeb921..e8d0150dab90 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx @@ -42,7 +42,7 @@ function SageIntacctDatePage({policy}: WithPolicyProps) { ); const selectExportDate = useCallback( - (row: SelectorType) => { + (row: MenuListItem) => { if (row.value !== exportDate) { Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, {exportDate: row.value}); } diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableDefaultVendorPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx similarity index 50% rename from src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableDefaultVendorPage.tsx rename to src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx index dec468f2d886..911177dddcaf 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableDefaultVendorPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx @@ -1,5 +1,7 @@ +import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; import BlockingView from '@components/BlockingViews/BlockingView'; import * as Illustrations from '@components/Icon/Illustrations'; import RadioListItem from '@components/SelectionList/RadioListItem'; @@ -10,24 +12,34 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Connections from '@libs/actions/connections'; import Navigation from '@libs/Navigation/Navigation'; -import {getSageIntacctActiveDefaultVendor, getSageIntacctVendors} from '@libs/PolicyUtils'; -import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; -import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import {getSageIntacctNonReimbursableActiveDefaultVendor, getSageIntacctVendors} from '@libs/PolicyUtils'; +import type {SettingsNavigatorParamList} from '@navigation/types'; import variables from '@styles/variables'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; -function SageIntacctNonReimbursableDefaultVendorPage({policy}: WithPolicyConnectionsProps) { +type SageIntacctDefaultVendorPageProps = StackScreenProps; + +function SageIntacctDefaultVendorPage({route}: SageIntacctDefaultVendorPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const policyID = policy?.id ?? '-1'; + const policyID = route.params.policyID ?? '-1'; + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); - const {nonReimbursable} = policy?.connections?.intacct?.config.export ?? {}; + const isReimbursable = route.params.reimbursable === 'reimbursable'; - const activeDefaultVendor = getSageIntacctActiveDefaultVendor(policy); + let defaultVendor; + if (!isReimbursable) { + defaultVendor = getSageIntacctNonReimbursableActiveDefaultVendor(policy); + } else { + const {reimbursableExpenseReportDefaultVendor} = policy?.connections?.intacct?.config.export ?? {}; + defaultVendor = reimbursableExpenseReportDefaultVendor; + } - const vendorSelectorOptions = useMemo(() => getSageIntacctVendors(policy ?? undefined, activeDefaultVendor), [activeDefaultVendor, policy]); + const vendorSelectorOptions = useMemo(() => getSageIntacctVendors(policy ?? undefined, defaultVendor), [defaultVendor, policy]); const listHeaderComponent = useMemo( () => ( @@ -40,21 +52,24 @@ function SageIntacctNonReimbursableDefaultVendorPage({policy}: WithPolicyConnect const updateDefaultVendor = useCallback( ({value}: SelectorType) => { - if (value !== activeDefaultVendor) { - Connections.updatePolicyConnectionConfig( - policyID, - CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, - CONST.XERO_CONFIG.EXPORT, - nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE - ? { - nonReimbursableCreditCardChargeDefaultVendor: value, - } - : {nonReimbursableExpenseReportDefaultVendor: value}, - ); + if (value !== defaultVendor) { + let settingValue; + if (isReimbursable) { + settingValue = {reimbursableExpenseReportDefaultVendor: value}; + } else { + const {nonReimbursable} = policy?.connections?.intacct?.config.export ?? {}; + settingValue = + nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE + ? { + nonReimbursableCreditCardChargeDefaultVendor: value, + } + : {nonReimbursableVendor: value}; + } + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, settingValue); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID)); }, - [policyID, activeDefaultVendor, nonReimbursable], + [policyID, defaultVendor], ); // TODO: test on empty list @@ -76,13 +91,19 @@ function SageIntacctNonReimbursableDefaultVendorPage({policy}: WithPolicyConnect mode.isSelected)?.keyForList} headerContent={listHeaderComponent} - onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID))} + onBackButtonPress={() => + Navigation.goBack( + isReimbursable + ? ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_REIMBURSABLE_EXPENSES.getRoute(policyID) + : ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID), + ) + } title="workspace.sageIntacct.defaultVendor" listEmptyContent={listEmptyContent} connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT} @@ -90,6 +111,6 @@ function SageIntacctNonReimbursableDefaultVendorPage({policy}: WithPolicyConnect ); } -SageIntacctNonReimbursableDefaultVendorPage.displayName = 'PolicySageIntacctNonReimbursableDefaultVendorPage'; +SageIntacctDefaultVendorPage.displayName = 'PolicySageIntacctDefaultVendorPage'; -export default withPolicyConnections(SageIntacctNonReimbursableDefaultVendorPage); +export default SageIntacctDefaultVendorPage; diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctExportPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctExportPage.tsx index 4484c2daa24c..dc9686710dad 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctExportPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctExportPage.tsx @@ -22,21 +22,21 @@ function SageIntacctExportPage({policy}: WithPolicyProps) { { description: translate('workspace.sageIntacct.preferredExporter'), action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_PREFERRED_EXPORTER.getRoute(policyID)), - title: exportConfig.exporter || translate('workspace.sageIntacct.notConfigured'), + title: exportConfig?.exporter ?? translate('workspace.sageIntacct.notConfigured'), hasError: !!errorFields?.exporter, pendingAction: pendingFields?.export, }, { description: translate('workspace.sageIntacct.exportDate.label'), action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT_DATE.getRoute(policyID)), - title: exportConfig.exportDate ? translate(`workspace.sageIntacct.exportDate.values.${exportConfig.exportDate}.label`) : translate(`workspace.sageIntacct.notConfigured`), + title: exportConfig?.exportDate ? translate(`workspace.sageIntacct.exportDate.values.${exportConfig.exportDate}.label`) : translate(`workspace.sageIntacct.notConfigured`), hasError: !!errorFields?.exportDate, pendingAction: pendingFields?.export, }, { description: translate('workspace.sageIntacct.reimbursableExpenses.label'), action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_REIMBURSABLE_EXPENSES.getRoute(policyID)), - title: exportConfig.reimbursable + title: exportConfig?.reimbursable ? translate(`workspace.sageIntacct.reimbursableExpenses.values.${exportConfig.reimbursable}`) : translate('workspace.sageIntacct.notConfigured'), hasError: !!errorFields?.reimbursable, @@ -45,7 +45,7 @@ function SageIntacctExportPage({policy}: WithPolicyProps) { { description: translate('workspace.sageIntacct.nonReimbursableExpenses.label'), action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID)), - title: exportConfig.nonReimbursable + title: exportConfig?.nonReimbursable ? translate(`workspace.sageIntacct.nonReimbursableExpenses.values.${exportConfig.nonReimbursable}`) : translate('workspace.sageIntacct.notConfigured'), hasError: !!errorFields?.nonReimbursable, @@ -59,7 +59,7 @@ function SageIntacctExportPage({policy}: WithPolicyProps) { ; }; +function getDefaultVendorName(defaultVendor: string, vendors: SageIntacctDataElementWithValue[]): string { + return vendors.find((vendor) => vendor.id === defaultVendor)?.value ?? defaultVendor; +} + function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; const styles = useThemeStyles(); - const { - data: intacctData, - config: {export: exportConfig, pendingFields, errorFields}, - } = policy?.connections?.intacct ?? {}; + const {data: intacctData, config} = policy?.connections?.intacct ?? {}; - const [isSwitchOn, setIsSwitchOn] = useState(!!exportConfig.nonReimbursableCreditCardChargeDefaultVendor); + const [isSwitchOn, setIsSwitchOn] = useState(!!config?.export.nonReimbursableCreditCardChargeDefaultVendor); const data: MenuListItem[] = Object.values(CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE).map((expenseType) => ({ value: expenseType, text: translate(`workspace.sageIntacct.nonReimbursableExpenses.values.${expenseType}`), keyForList: expenseType, - isSelected: exportConfig.nonReimbursable === expenseType, + isSelected: config?.export.nonReimbursable === expenseType, })); const headerContent = useMemo( @@ -51,22 +52,22 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { ); const selectNonReimbursableExpense = useCallback( - (row: SelectorType) => { - if (row.value === exportConfig.nonReimbursable) { + (row: MenuListItem) => { + if (row.value === config?.export.nonReimbursable) { return; } Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, {nonReimbursable: row.value}); }, - [exportConfig.nonReimbursable, policyID], + [config?.export.nonReimbursable, policyID], ); - const activeDefaultVendor = getSageIntacctActiveDefaultVendor(policy); + const activeDefaultVendor = getSageIntacctNonReimbursableActiveDefaultVendor(policy); const defaultVendorSection = { description: translate('workspace.sageIntacct.defaultVendor'), - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_DEFAULT_VENDOR.getRoute(policyID)), - title: activeDefaultVendor ? intacctData.vendors.find((vendor) => vendor.id === activeDefaultVendor).value : translate('workspace.sageIntacct.notConfigured'), - hasError: !!errorFields?.exporter, - pendingAction: pendingFields?.export, + action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR.getRoute(policyID, 'non-reimbursable')), + title: activeDefaultVendor ? getDefaultVendorName(activeDefaultVendor, intacctData?.vendors ?? []) : translate('workspace.sageIntacct.notConfigured'), + hasError: !!config?.errorFields?.exporter, + pendingAction: config?.pendingFields?.export, }; const defaultVendor = ( @@ -87,11 +88,9 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { const creditCardAccountSection = { description: translate('workspace.sageIntacct.creditCardAccount'), action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT.getRoute(policyID)), - title: exportConfig.nonReimbursableAccount - ? intacctData.creditCards.find((creditCard) => creditCard.id === exportConfig.nonReimbursableAccount).name - : translate('workspace.sageIntacct.notConfigured'), - hasError: !!errorFields?.exporter, - pendingAction: pendingFields?.export, + title: config?.export.nonReimbursableAccount ? config.export.nonReimbursableAccount : translate('workspace.sageIntacct.notConfigured'), + hasError: !!config?.errorFields?.exporter, + pendingAction: config?.pendingFields?.export, }; const creditCardAccount = ( @@ -125,8 +124,8 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID))} connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT} /> - {exportConfig.nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL && defaultVendor} - {exportConfig.nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE && ( + {config?.export.nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL && defaultVendor} + {config?.export.nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE && ( {creditCardAccount} ; }; +function getDefaultVendorName(defaultVendor: string, vendors: SageIntacctDataElementWithValue[]): string { + return vendors.find((vendor) => vendor.id === defaultVendor)?.value ?? defaultVendor; +} + function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; const styles = useThemeStyles(); - const {reimbursable} = policy?.connections?.intacct?.config?.export ?? {}; + const {data: intacctData, config} = policy?.connections?.intacct ?? {}; + const {reimbursable, reimbursableExpenseReportDefaultVendor} = policy?.connections?.intacct?.config?.export ?? {}; + + const [isSwitchOn, setIsSwitchOn] = useState(!!reimbursableExpenseReportDefaultVendor); + const data: MenuListItem[] = Object.values(CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE).map((expenseType) => ({ value: expenseType, text: translate(`workspace.sageIntacct.reimbursableExpenses.values.${expenseType}`), @@ -41,7 +52,7 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { ); const selectExportDate = useCallback( - (row: SelectorType) => { + (row: MenuListItem) => { if (row.value !== reimbursable) { Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, {reimbursable: row.value}); } @@ -50,21 +61,67 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { [reimbursable, policyID], ); + const defaultVendorSection = { + description: translate('workspace.sageIntacct.defaultVendor'), + action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR.getRoute(policyID, 'reimbursable')), + title: reimbursableExpenseReportDefaultVendor + ? getDefaultVendorName(reimbursableExpenseReportDefaultVendor, intacctData?.vendors ?? []) + : translate('workspace.sageIntacct.notConfigured'), + hasError: !!config?.errorFields?.exporter, + pendingAction: config?.pendingFields?.export, + }; + + const defaultVendor = ( + + + + ); + return ( - 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_SAGE_INTACCT_EXPORT.getRoute(policyID))} - connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT} - /> + + 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_SAGE_INTACCT_EXPORT.getRoute(policyID))} + connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT} + /> + {reimbursable === CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT && ( + + { + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, { + reimbursableExpenseReportDefaultVendor: null, + }); + setIsSwitchOn(!isSwitchOn); + }} + wrapperStyle={[styles.ph5, styles.pv3]} + /> + {isSwitchOn && defaultVendor} + + )} + ); } diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index bd8f5e7d33d9..a67ead8fe4eb 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -594,6 +594,79 @@ type XeroConnectionConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{ errorFields?: OnyxCommon.ErrorFields; }>; +/** One of the SageIntacctConnectionData object elements */ +type SageIntacctDataElement = { + /** Element ID */ + id: string; + + /** Element name */ + name: string; +}; + +/** One of the SageIntacctConnectionData object elements with value */ +type SageIntacctDataElementWithValue = SageIntacctDataElement & { + /** Element value */ + value: string; +}; + +/** + * Connection data for Sage Intacct + */ +type SageIntacctConnectionData = { + /** Collection of credit cards */ + creditCards: SageIntacctDataElement[]; + + /** Collection of bank accounts */ + bankAccounts: SageIntacctDataElement[]; + + /** Collection of vendors */ + vendors: SageIntacctDataElementWithValue[]; +}; + +/** + * Connection config for Sage Intacct + */ +type SageIntacctConnectiosConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{ + /** Sage Intacct credentials */ + credentials: { + /** Sage Intacct companyID */ + companyID: string; + }; + + /** Sage Intacct export configs */ + export: { + /** Current export status */ + exportDate: ValueOf; + + /** The e-mail of the exporter */ + exporter: string; + + /** TODO: Will be handled in another issue */ + nonReimbursable: ValueOf; + + /** TODO: Will be handled in another issue */ + nonReimbursableAccount: string; + + /** */ + nonReimbursableCreditCardChargeDefaultVendor: string | null; + + /** */ + nonReimbursableVendor: string | null; + + /** TODO: Will be handled in another issue */ + reimbursable: ValueOf; + + /** */ + reimbursableExpenseReportDefaultVendor: string | null; + }; + + /** Collection of Sage Intacct config errors */ + errors?: OnyxCommon.Errors; + + /** Collection of form field errors */ + errorFields?: OnyxCommon.ErrorFields; +}>; + /** Data stored about subsidiaries from NetSuite */ type Subsidiary = { /** ID of the subsidiary */ @@ -952,7 +1025,7 @@ type NetSuiteConnection = { /** State of integration connection */ type Connection = { /** State of the last synchronization */ - lastSync?: ConnectionLastSync; + lastSync?: ConnectionLxastSync; /** Data imported from integration */ data?: ConnectionData; @@ -971,6 +1044,9 @@ type Connections = { /** NetSuite integration connection */ netsuite: NetSuiteConnection; + + /** Sage Intacct integration connection */ + intacct: Connection; }; /** Names of integration connections */ @@ -1314,4 +1390,5 @@ export type { QBOReimbursableExportAccountType, QBOConnectionConfig, XeroTrackingCategory, + SageIntacctDataElementWithValue, }; From 6f9fb6a3c2b6ca671c5dc061921f0dc2ddcc167e Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Mon, 24 Jun 2024 15:44:14 +0200 Subject: [PATCH 0170/1260] pod install --- ios/Podfile.lock | 113 ++++++----------------------------------------- 1 file changed, 14 insertions(+), 99 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 35dccc2de393..102984e29c9c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -282,27 +282,10 @@ PODS: - nanopb/encode (= 2.30908.0) - nanopb/decode (2.30908.0) - nanopb/encode (2.30908.0) - - Onfido (29.7.1) + - Onfido (29.6.0) - onfido-react-native-sdk (10.6.0): - - glog - - hermes-engine - - Onfido (~> 29.7.0) - - RCT-Folly (= 2022.05.16.00) - - RCTRequired - - RCTTypeSafety - - React-Codegen - - React-Core - - React-debug - - React-Fabric - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga + - Onfido (~> 29.6.0) + - React - Plaid (5.2.1) - PromisesObjC (2.4.0) - RCT-Folly (2022.05.16.00): @@ -1319,24 +1302,7 @@ PODS: - react-native-launch-arguments (4.0.2): - React - react-native-netinfo (11.2.1): - - glog - - hermes-engine - - RCT-Folly (= 2022.05.16.00) - - RCTRequired - - RCTTypeSafety - - React-Codegen - React-Core - - React-debug - - React-Fabric - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga - react-native-pager-view (6.2.3): - glog - hermes-engine @@ -1395,25 +1361,8 @@ PODS: - ReactCommon/turbomodule/core - Yoga - react-native-plaid-link-sdk (11.5.0): - - glog - - hermes-engine - Plaid (~> 5.2.0) - - RCT-Folly (= 2022.05.16.00) - - RCTRequired - - RCTTypeSafety - - React-Codegen - React-Core - - React-debug - - React-Fabric - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga - react-native-quick-sqlite (8.0.6): - glog - hermes-engine @@ -1785,24 +1734,7 @@ PODS: - ReactCommon/turbomodule/core - Yoga - RNDeviceInfo (10.3.1): - - glog - - hermes-engine - - RCT-Folly (= 2022.05.16.00) - - RCTRequired - - RCTTypeSafety - - React-Codegen - React-Core - - React-debug - - React-Fabric - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga - RNDevMenu (4.1.1): - React-Core - React-Core/DevSupport @@ -1823,24 +1755,7 @@ PODS: - React-Core - RNFBApp - RNFlashList (1.6.3): - - glog - - hermes-engine - - RCT-Folly (= 2022.05.16.00) - - RCTRequired - - RCTTypeSafety - - React-Codegen - React-Core - - React-debug - - React-Fabric - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga - RNFS (2.20.0): - React-Core - RNGestureHandler (2.14.1): @@ -1865,7 +1780,7 @@ PODS: - RNGoogleSignin (10.0.1): - GoogleSignIn (~> 7.0) - React-Core - - RNLiveMarkdown (0.1.88): + - RNLiveMarkdown (0.1.91): - glog - hermes-engine - RCT-Folly (= 2022.05.16.00) @@ -1883,9 +1798,9 @@ PODS: - React-utils - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNLiveMarkdown/common (= 0.1.88) + - RNLiveMarkdown/common (= 0.1.91) - Yoga - - RNLiveMarkdown/common (0.1.88): + - RNLiveMarkdown/common (0.1.91): - glog - hermes-engine - RCT-Folly (= 2022.05.16.00) @@ -2523,8 +2438,8 @@ SPEC CHECKSUMS: MapboxMaps: 87ef0003e6db46e45e7a16939f29ae87e38e7ce2 MapboxMobileEvents: de50b3a4de180dd129c326e09cd12c8adaaa46d6 nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 - Onfido: 342cbecd7a4383e98dfe7f9c35e98aaece599062 - onfido-react-native-sdk: 3e3b0dd70afa97410fb318d54c6a415137968ef2 + Onfido: c52e797b10cc9e6d29ba91996cb62e501000bfdd + onfido-react-native-sdk: 4e7f0a7a986ed93cb906d2e0b67a6aab9202de0b Plaid: 7829e84db6d766a751c91a402702946d2977ddcb PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0 @@ -2559,11 +2474,11 @@ SPEC CHECKSUMS: react-native-key-command: 28ccfa09520e7d7e30739480dea4df003493bfe8 react-native-keyboard-controller: 47c01b0741ae5fc84e53cf282e61cfa5c2edb19b react-native-launch-arguments: 5f41e0abf88a15e3c5309b8875d6fd5ac43df49d - react-native-netinfo: 02d31de0e08ab043d48f2a1a8baade109d7b6ca5 + react-native-netinfo: 8a7fd3f7130ef4ad2fb4276d5c9f8d3f28d2df3d react-native-pager-view: ccd4bbf9fc7effaf8f91f8dae43389844d9ef9fa react-native-pdf: 762369633665ec02ac227aefe2f4558b92475c23 react-native-performance: fb21ff0c9bd7a10789c69d948f25b0067d29f7a9 - react-native-plaid-link-sdk: 2a91ef7e257ae16d180a1ca14ba3041ae0836fbf + react-native-plaid-link-sdk: 6c4d3d4f14288c546151d404aea812fa55edeea9 react-native-quick-sqlite: e3ab3e0a29d8c705f47a60aaa6ceaa42eb6a9ec1 react-native-release-profiler: 14ccdc0eeb03bedf625cf68d53d80275a81b19dd react-native-render-html: 96c979fe7452a0a41559685d2f83b12b93edac8c @@ -2596,17 +2511,17 @@ SPEC CHECKSUMS: RNAppleAuthentication: 0571c08da8c327ae2afc0261b48b4a515b0286a6 RNCClipboard: 081418ae3b391b1012c3f41d045e5e39f1beed71 RNCPicker: 106d11a1c159ce937009b2bd52db2bdb1577454f - RNDeviceInfo: 449272e9faf2afe94a3fe2896d169e92277fffa8 + RNDeviceInfo: 468a7cd19ad2b6697bab25c8baebf22c0603cb7c RNDevMenu: 72807568fe4188bd4c40ce32675d82434b43c45d RNFBAnalytics: f76bfa164ac235b00505deb9fc1776634056898c RNFBApp: 729c0666395b1953198dc4a1ec6deb8fbe1c302e RNFBCrashlytics: 2061ca863e8e2fa1aae9b12477d7dfa8e88ca0f9 RNFBPerf: 389914cda4000fe0d996a752532a591132cbf3f9 - RNFlashList: 76c2fab003330924ab1a140d13aadf3834dc32e0 + RNFlashList: 4b4b6b093afc0df60ae08f9cbf6ccd4c836c667a RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 RNGestureHandler: 74b7b3d06d667ba0bbf41da7718f2607ae0dfe8f RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0 - RNLiveMarkdown: e33d2c97863d5480f8f4b45f8b25f801cc43c7f5 + RNLiveMarkdown: 24fbb7370eefee2f325fb64cfe904b111ffcd81b RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81 rnmapbox-maps: df8fe93dbd251f25022f4023d31bc04160d4d65c RNPermissions: 0b61d30d21acbeafe25baaa47d9bae40a0c65216 @@ -2623,7 +2538,7 @@ SPEC CHECKSUMS: SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 Turf: 13d1a92d969ca0311bbc26e8356cca178ce95da2 VisionCamera: 1394a316c7add37e619c48d7aa40b38b954bf055 - Yoga: 64cd2a583ead952b0315d5135bf39e053ae9be70 + Yoga: 1b901a6d6eeba4e8a2e8f308f708691cdb5db312 PODFILE CHECKSUM: d5e281e5370cb0211a104efd90eb5fa7af936e14 From def13fe85939736652926e23c0a40b308f1bc1ce Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 24 Jun 2024 15:44:28 +0200 Subject: [PATCH 0171/1260] fix typecheck --- src/languages/es.ts | 13 +++++++++++++ .../intacct/export/SageIntacctDatePage.tsx | 2 +- .../intacct/export/SageIntacctDefaultVendorPage.tsx | 2 +- .../SageIntacctNonReimbursableExpensesPage.tsx | 3 ++- .../export/SageIntacctReimbursableExpensesPage.tsx | 3 ++- src/types/onyx/Policy.ts | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 9f95e03e5099..df2f8653df51 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2454,6 +2454,19 @@ export default { subtitle: 'Conecta a tu sistema de contabilidad para codificar transacciones con tu plan de cuentas, auto-cotejar pagos, y mantener tus finanzas sincronizadas.', qbo: 'Quickbooks Online', xero: 'Xero', + intacct: 'Sage Intacct', + integrationName: (integration?: ConnectionName): string => { + switch (integration) { + case CONST.POLICY.CONNECTIONS.NAME.QBO: + return 'Quickbooks Online'; + case CONST.POLICY.CONNECTIONS.NAME.XERO: + return 'Xero'; + case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: + return 'Sage Intacct'; + default: + return 'Integration'; + } + }, setup: 'Configurar', lastSync: 'Recién sincronizado', import: 'Importar', diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx index e8d0150dab90..1c3889de2986 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx @@ -58,7 +58,7 @@ function SageIntacctDatePage({policy}: WithPolicyProps) { headerContent={headerContent} sections={[{data}]} listItem={RadioListItem} - onSelectRow={selectExportDate} + onSelectRow={(selection: SelectorType) => selectExportDate(selection as MenuListItem)} initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} policyID={policyID} accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]} diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx index 911177dddcaf..c7c958558b28 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx @@ -69,7 +69,7 @@ function SageIntacctDefaultVendorPage({route}: SageIntacctDefaultVendorPageProps } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID)); }, - [policyID, defaultVendor], + [defaultVendor, policyID, isReimbursable, policy?.connections?.intacct?.config.export], ); // TODO: test on empty list diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx index 000388a5c32c..b1ab9b6c3ae5 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx @@ -5,6 +5,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import RadioListItem from '@components/SelectionList/RadioListItem'; import type {ListItem} from '@components/SelectionList/types'; +import type {SelectorType} from '@components/SelectionScreen'; import SelectionScreen from '@components/SelectionScreen'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; @@ -116,7 +117,7 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { headerContent={headerContent} sections={[{data}]} listItem={RadioListItem} - onSelectRow={selectNonReimbursableExpense} + onSelectRow={(selection: SelectorType) => selectNonReimbursableExpense(selection as MenuListItem)} initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} policyID={policyID} accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]} diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx index 4aa84c931203..521a98beed1d 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx @@ -5,6 +5,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import RadioListItem from '@components/SelectionList/RadioListItem'; import type {ListItem} from '@components/SelectionList/types'; +import type {SelectorType} from '@components/SelectionScreen'; import SelectionScreen from '@components/SelectionScreen'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; @@ -94,7 +95,7 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { headerContent={headerContent} sections={[{data}]} listItem={RadioListItem} - onSelectRow={selectExportDate} + onSelectRow={(selection: SelectorType) => selectExportDate(selection as MenuListItem)} initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} policyID={policyID} accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]} diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index a67ead8fe4eb..1a26722492f0 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1025,7 +1025,7 @@ type NetSuiteConnection = { /** State of integration connection */ type Connection = { /** State of the last synchronization */ - lastSync?: ConnectionLxastSync; + lastSync?: ConnectionLastSync; /** Data imported from integration */ data?: ConnectionData; From b454ac27ae3a971f0b9033ca9863cad34be3051d Mon Sep 17 00:00:00 2001 From: Kaushik Kapadiya Date: Mon, 24 Jun 2024 19:16:09 +0530 Subject: [PATCH 0172/1260] Reset amount on reset button click --- src/components/MoneyRequestAmountInput.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index 5a8d3742b5f8..80b86afc9e06 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -106,7 +106,7 @@ const getNewSelection = (oldSelection: Selection, prevLength: number, newLength: return {start: cursorPosition, end: cursorPosition}; }; -const defaultOnFormatAmount = (amount: number, currency?: string): string => CurrencyUtils.convertToFrontendAmountAsString(amount); +const defaultOnFormatAmount = (amount: number) => CurrencyUtils.convertToFrontendAmountAsString(amount); function MoneyRequestAmountInput( { @@ -208,7 +208,7 @@ function MoneyRequestAmountInput( useEffect(() => { const shouldExitEarly = !currency || typeof amount !== 'number' || (formatAmountOnBlur && textInput.current?.isFocused()) || shouldKeepUserInput; - const frontendAmount = onFormatAmount(amount, currency); + const frontendAmount = onFormatAmount ? onFormatAmount(amount, currency) : defaultOnFormatAmount(amount, currency); if (shouldResetAmount) { setCurrentAmount(frontendAmount); From 7fe8f3e78f66078d253a107d4ec9b5a7ed5250a9 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Mon, 24 Jun 2024 15:47:07 +0200 Subject: [PATCH 0173/1260] preloaded linking --- src/libs/E2E/reactNativeLaunchingTest.ts | 1 + .../E2E/tests/preloadedLinkingTest.e2e.ts | 77 +++++++++++++++++++ tests/e2e/config.ts | 10 +++ 3 files changed, 88 insertions(+) create mode 100644 src/libs/E2E/tests/preloadedLinkingTest.e2e.ts diff --git a/src/libs/E2E/reactNativeLaunchingTest.ts b/src/libs/E2E/reactNativeLaunchingTest.ts index f23508987268..26b250ce3814 100644 --- a/src/libs/E2E/reactNativeLaunchingTest.ts +++ b/src/libs/E2E/reactNativeLaunchingTest.ts @@ -39,6 +39,7 @@ const tests: Tests = { [E2EConfig.TEST_NAMES.ChatOpening]: require('./tests/chatOpeningTest.e2e').default, [E2EConfig.TEST_NAMES.ReportTyping]: require('./tests/reportTypingTest.e2e').default, [E2EConfig.TEST_NAMES.Linking]: require('./tests/linkingTest.e2e').default, + [E2EConfig.TEST_NAMES.PreloadedLinking]: require('./tests/preloadedLinkingTest.e2e').default, }; // Once we receive the TII measurement we know that the app is initialized and ready to be used: diff --git a/src/libs/E2E/tests/preloadedLinkingTest.e2e.ts b/src/libs/E2E/tests/preloadedLinkingTest.e2e.ts new file mode 100644 index 000000000000..e718ef0ecdfc --- /dev/null +++ b/src/libs/E2E/tests/preloadedLinkingTest.e2e.ts @@ -0,0 +1,77 @@ +import {DeviceEventEmitter} from 'react-native'; +import type {NativeConfig} from 'react-native-config'; +import Config from 'react-native-config'; +import Timing from '@libs/actions/Timing'; +import E2ELogin from '@libs/E2E/actions/e2eLogin'; +import waitForAppLoaded from '@libs/E2E/actions/waitForAppLoaded'; +import E2EClient from '@libs/E2E/client'; +import getConfigValueOrThrow from '@libs/E2E/utils/getConfigValueOrThrow'; +import getPromiseWithResolve from '@libs/E2E/utils/getPromiseWithResolve'; +import Navigation from '@libs/Navigation/Navigation'; +import Performance from '@libs/Performance'; +import CONST from '@src/CONST'; +import ROUTES from '@src/ROUTES'; + +const test = (config: NativeConfig) => { + console.debug('[E2E] Logging in for comment linking'); + + const reportID = getConfigValueOrThrow('reportID', config); + const linkedReportActionID = getConfigValueOrThrow('linkedReportActionID', config); + + E2ELogin().then((neededLogin) => { + if (neededLogin) { + return waitForAppLoaded().then(() => E2EClient.submitTestDone()); + } + + const [appearMessagePromise, appearMessageResolve] = getPromiseWithResolve(); + const [switchReportPromise, switchReportResolve] = getPromiseWithResolve(); + + Promise.all([appearMessagePromise, switchReportPromise]) + .then(() => { + console.debug('[E2E] Test completed successfully, exiting…'); + E2EClient.submitTestDone(); + }) + .catch((err) => { + console.debug('[E2E] Error while submitting test results:', err); + }); + + const subscription = DeviceEventEmitter.addListener('onViewableItemsChanged', (res) => { + console.debug('[E2E] Viewable items retrieved, verifying correct message…', res); + if (!!res && res[0]?.item?.reportActionID === linkedReportActionID) { + appearMessageResolve(); + subscription.remove(); + } else { + console.debug(`[E2E] Provided message id '${res?.[0]?.item?.reportActionID}' doesn't match to an expected '${linkedReportActionID}'. Waiting for a next one…`); + } + }); + + Performance.subscribeToMeasurements((entry) => { + if (entry.name === CONST.TIMING.SIDEBAR_LOADED) { + console.debug('[E2E] Sidebar loaded, navigating to a report…'); + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID)); + return; + } + + if (entry.name === CONST.TIMING.REPORT_INITIAL_RENDER) { + console.debug('[E2E] Navigating to linked report action…'); + Timing.start(CONST.TIMING.SWITCH_REPORT); + Performance.markStart(CONST.TIMING.SWITCH_REPORT); + + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID, linkedReportActionID)); + return; + } + + if (entry.name === CONST.TIMING.CHAT_RENDER) { + E2EClient.submitTestResults({ + branch: Config.E2E_BRANCH, + name: 'Comment linking', + duration: entry.duration, + }); + + switchReportResolve(); + } + }); + }); +}; + +export default test; diff --git a/tests/e2e/config.ts b/tests/e2e/config.ts index 6eb6bb839ae2..5bd72913c87c 100644 --- a/tests/e2e/config.ts +++ b/tests/e2e/config.ts @@ -8,6 +8,7 @@ const TEST_NAMES = { ReportTyping: 'Report typing', ChatOpening: 'Chat opening', Linking: 'Linking', + PreloadedLinking: 'Preloaded linking', }; /** @@ -96,6 +97,15 @@ export default { linkedReportID: '5421294415618529', linkedReportActionID: '2845024374735019929', }, + [TEST_NAMES.PreloadedLinking]: { + name: TEST_NAMES.PreloadedLinking, + reportScreen: { + autoFocus: true, + }, + // Crowded Policy (Do Not Delete) Report, has a input bar available: + reportID: '5421294415618529', + linkedReportActionID: '8984197495983183608', // Message 4897 + }, }, }; From bc1069262f87cdd9eac9f6b7c37f4318bf6af8a8 Mon Sep 17 00:00:00 2001 From: Kaushik Kapadiya Date: Mon, 24 Jun 2024 19:22:30 +0530 Subject: [PATCH 0174/1260] Reset amount on reset button click --- src/components/MoneyRequestAmountInput.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index 80b86afc9e06..05b733c85fff 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -208,7 +208,7 @@ function MoneyRequestAmountInput( useEffect(() => { const shouldExitEarly = !currency || typeof amount !== 'number' || (formatAmountOnBlur && textInput.current?.isFocused()) || shouldKeepUserInput; - const frontendAmount = onFormatAmount ? onFormatAmount(amount, currency) : defaultOnFormatAmount(amount, currency); + const frontendAmount = onFormatAmount(amount, currency); if (shouldResetAmount) { setCurrentAmount(frontendAmount); From 105cd0a82711ca35b47edb82f58876916d74b8c0 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 24 Jun 2024 15:52:33 +0200 Subject: [PATCH 0175/1260] address review comments --- src/CONST.ts | 4 ++++ .../accounting/intacct/export/SageIntacctDatePage.tsx | 4 ++-- .../intacct/export/SageIntacctDefaultVendorPage.tsx | 2 +- .../SageIntacctNonReimbursableCreditCardAccountPage.tsx | 2 +- .../intacct/export/SageIntacctNonReimbursableExpensesPage.tsx | 4 ++-- .../intacct/export/SageIntacctPreferredExporterPage.tsx | 4 ++-- .../intacct/export/SageIntacctReimbursableExpensesPage.tsx | 4 ++-- 7 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 697444ad42a9..1ef6cd9aa54d 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1347,6 +1347,10 @@ const CONST = { }, }, + SAGE_INTACCT_CONFIG: { + EXPORT: 'export', + }, + QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE: { VENDOR_BILL: 'bill', CHECK: 'check', diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx index 1c3889de2986..2a0564844073 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx @@ -16,7 +16,7 @@ import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; type MenuListItem = ListItem & { - value: ValueOf; + value: ValueOf; }; function SageIntacctDatePage({policy}: WithPolicyProps) { @@ -44,7 +44,7 @@ function SageIntacctDatePage({policy}: WithPolicyProps) { const selectExportDate = useCallback( (row: MenuListItem) => { if (row.value !== exportDate) { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, {exportDate: row.value}); + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, {exportDate: row.value}); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID)); }, diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx index c7c958558b28..d86eea3edc48 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx @@ -65,7 +65,7 @@ function SageIntacctDefaultVendorPage({route}: SageIntacctDefaultVendorPageProps } : {nonReimbursableVendor: value}; } - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, settingValue); + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, settingValue); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID)); }, diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx index 62a99dba7faa..a5c03617c792 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx @@ -39,7 +39,7 @@ function SageIntacctNonReimbursableCreditCardAccountPage({policy}: WithPolicyCon const updateCreditCardAccount = useCallback( ({value}: SelectorType) => { if (value !== nonReimbursableAccount) { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, { + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, { nonReimbursableAccount: value, }); } diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx index b1ab9b6c3ae5..26c532aea8af 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx @@ -57,7 +57,7 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { if (row.value === config?.export.nonReimbursable) { return; } - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, {nonReimbursable: row.value}); + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, {nonReimbursable: row.value}); }, [config?.export.nonReimbursable, policyID], ); @@ -136,7 +136,7 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { switchAccessibilityLabel={translate('workspace.sageIntacct.defaultVendor')} isActive={isSwitchOn} onToggle={() => { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, { + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, { nonReimbursableCreditCardChargeDefaultVendor: null, }); setIsSwitchOn(!isSwitchOn); diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx index 31596d9826a1..0e8fa0a340f5 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx @@ -64,9 +64,9 @@ function SageIntacctPreferredExporterPage({policy}: WithPolicyProps) { const selectExporter = useCallback( (row: CardListItem) => { if (row.value !== exportConfiguration?.exporter) { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, {exporter: row.value}); + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, {exporter: row.value}); } - Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_EXPORT.getRoute(policyID)); + Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID)); }, [policyID, exportConfiguration], ); diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx index 521a98beed1d..38452f1d75b2 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx @@ -55,7 +55,7 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { const selectExportDate = useCallback( (row: MenuListItem) => { if (row.value !== reimbursable) { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, {reimbursable: row.value}); + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, {reimbursable: row.value}); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID)); }, @@ -112,7 +112,7 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { switchAccessibilityLabel={translate('workspace.sageIntacct.defaultVendor')} isActive={isSwitchOn} onToggle={() => { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.XERO_CONFIG.EXPORT, { + Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, { reimbursableExpenseReportDefaultVendor: null, }); setIsSwitchOn(!isSwitchOn); From 049c22743d2b326a8e180be3be14d376b623a315 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 24 Jun 2024 16:08:57 +0200 Subject: [PATCH 0176/1260] add customizable translation for default vendor --- src/languages/en.ts | 3 ++- .../accounting/intacct/export/SageIntacctDefaultVendorPage.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 3deace7da721..7d4365211927 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2222,7 +2222,8 @@ export default { creditCardAccount: 'Credit card account', creditCardAccountDescription: 'We should have some description here, right?', defaultVendor: 'Default vendor', - defaultVendorDescription: "Set a default vendor that will apply to nonreimbursable expenses that don't have a matching vendor in Sage Intacct.", + defaultVendorDescription: (isReimbursable: boolean): string => + `Set a default vendor that will apply to ${isReimbursable ? '' : 'non-'}reimbursable expenses that don't have a matching vendor in Sage Intacct.`, exportDescription: 'Configure how data in Expensify gets exported to Sage Inacct.', exportPreferredExporterNote: 'The preferred exporter can be any workspace admin, but must also be a Domain Admin if you set different export accounts for individual company cards in Domain Settings.', diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx index d86eea3edc48..581ed20b816d 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx @@ -44,7 +44,7 @@ function SageIntacctDefaultVendorPage({route}: SageIntacctDefaultVendorPageProps const listHeaderComponent = useMemo( () => ( - {translate('workspace.sageIntacct.defaultVendorDescription')} + {translate('workspace.sageIntacct.defaultVendorDescription', isReimbursable)} ), [translate, styles.pb2, styles.ph5, styles.pb5, styles.textNormal], From 4db9a0afc2cdd53daec37ccfbd0d61f407303570 Mon Sep 17 00:00:00 2001 From: Kaushik Kapadiya Date: Mon, 24 Jun 2024 19:45:59 +0530 Subject: [PATCH 0177/1260] Reset amount on reset button click --- src/components/MoneyRequestAmountInput.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index 05b733c85fff..a63622eb4434 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -9,6 +9,7 @@ import getOperatingSystem from '@libs/getOperatingSystem'; import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; import shouldIgnoreSelectionWhenUpdatedManually from '@libs/shouldIgnoreSelectionWhenUpdatedManually'; import CONST from '@src/CONST'; +import isTextInputFocused from './TextInput/BaseTextInput/isTextInputFocused'; import type {BaseTextInputRef} from './TextInput/BaseTextInput/types'; import TextInputWithCurrencySymbol from './TextInputWithCurrencySymbol'; @@ -207,7 +208,7 @@ function MoneyRequestAmountInput( })); useEffect(() => { - const shouldExitEarly = !currency || typeof amount !== 'number' || (formatAmountOnBlur && textInput.current?.isFocused()) || shouldKeepUserInput; + const shouldExitEarly = (!currency || typeof amount !== 'number' || (formatAmountOnBlur && isTextInputFocused(textInput))) || shouldKeepUserInput; const frontendAmount = onFormatAmount(amount, currency); if (shouldResetAmount) { From b3087ed1561f1f2661de3574275621adeac5849f Mon Sep 17 00:00:00 2001 From: Kaushik Kapadiya Date: Mon, 24 Jun 2024 19:56:21 +0530 Subject: [PATCH 0178/1260] Reset amount on reset button click --- src/components/MoneyRequestAmountInput.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index a63622eb4434..6569e1fbdd8e 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -208,7 +208,7 @@ function MoneyRequestAmountInput( })); useEffect(() => { - const shouldExitEarly = (!currency || typeof amount !== 'number' || (formatAmountOnBlur && isTextInputFocused(textInput))) || shouldKeepUserInput; + const shouldExitEarly = (!currency || typeof amount !== 'number' || (formatAmountOnBlur && isTextInputFocused(textInput))) ?? shouldKeepUserInput; const frontendAmount = onFormatAmount(amount, currency); if (shouldResetAmount) { From ec7f075a70eb4cfbb76699e6c8f74aa9cc6e835a Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 24 Jun 2024 17:40:05 +0200 Subject: [PATCH 0179/1260] create functions for api calls --- src/libs/PolicyUtils.ts | 1 + src/libs/actions/connections/SageIntacct.ts | 138 ++++++++++++++++++ .../intacct/export/SageIntacctDatePage.tsx | 4 +- .../export/SageIntacctDefaultVendorPage.tsx | 6 +- ...ctNonReimbursableCreditCardAccountPage.tsx | 6 +- ...SageIntacctNonReimbursableExpensesPage.tsx | 8 +- .../SageIntacctPreferredExporterPage.tsx | 4 +- .../SageIntacctReimbursableExpensesPage.tsx | 10 +- 8 files changed, 156 insertions(+), 21 deletions(-) create mode 100644 src/libs/actions/connections/SageIntacct.ts diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 2d21e2da8197..a5788fc05ba7 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -489,6 +489,7 @@ function getSageIntacctCreditCards(policy: Policy | undefined, selectedAccount: return (creditCards ?? []).map(({name}) => ({ value: name, + text: name, keyForList: name, isSelected: isMatchFound && name === selectedAccount, })); diff --git a/src/libs/actions/connections/SageIntacct.ts b/src/libs/actions/connections/SageIntacct.ts new file mode 100644 index 000000000000..e2e7eec41491 --- /dev/null +++ b/src/libs/actions/connections/SageIntacct.ts @@ -0,0 +1,138 @@ +import type {OnyxUpdate} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import type {ValueOf} from 'type-fest'; +import * as API from '@libs/API'; +import {WRITE_COMMANDS} from '@libs/API/types'; +import * as ErrorUtils from '@libs/ErrorUtils'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {ConnectionName, Connections} from '@src/types/onyx/Policy'; + +function prepareOnyxData( + policyID: string, + connectionName: TConnectionName, + settingName: TSettingName, + settingValue: Partial, +) { + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + connections: { + [connectionName]: { + config: { + [settingName]: settingValue ?? null, + pendingFields: { + [settingName]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, + errorFields: { + [settingName]: null, + }, + }, + }, + }, + }, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + connections: { + [connectionName]: { + config: { + [settingName]: settingValue ?? null, + pendingFields: { + [settingName]: null, + }, + errorFields: { + [settingName]: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'), + }, + }, + }, + }, + }, + }, + ]; + + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + connections: { + [connectionName]: { + config: { + [settingName]: settingValue ?? null, + pendingFields: { + [settingName]: null, + }, + errorFields: { + [settingName]: null, + }, + }, + }, + }, + }, + }, + ]; + + return {optimisticData, failureData, successData}; +} + +function prepareOnyxDataForExport(policyID: string, settingValue: Partial) { + return prepareOnyxData(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, settingValue); +} + +function prepareParametersForExport(policyID: string, settingValue: Partial) { + return { + policyID, + connectionName: CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, + settingName: CONST.SAGE_INTACCT_CONFIG.EXPORT, + settingValue: JSON.stringify(settingValue), + idempotencyKey: CONST.SAGE_INTACCT_CONFIG.EXPORT, + }; +} + +function updateSageIntacctExport(policyID: string, settingValue: Partial) { + const {optimisticData, failureData, successData} = prepareOnyxDataForExport(policyID, settingValue); + const parameters = prepareParametersForExport(policyID, settingValue); + + API.write(WRITE_COMMANDS.UPDATE_POLICY_CONNECTION_CONFIG, parameters, {optimisticData, failureData, successData}); +} + +function updateSageIntacctExporter(policyID: string, exporter: string) { + updateSageIntacctExport(policyID, {exporter}); +} + +function updateSageIntacctExportDate(policyID: string, date: ValueOf) { + updateSageIntacctExport(policyID, {exportDate: date}); +} + +function updateSageIntacctExportReimbursableExpense(policyID: string, reimbursable: ValueOf) { + updateSageIntacctExport(policyID, {reimbursable}); +} + +function updateSageIntacctDefaultVendor(policyID: string, settingValue: Partial) { + updateSageIntacctExport(policyID, settingValue); +} + +function updateSageIntacctExportNonReimbursableExpense(policyID: string, nonReimbursable: ValueOf) { + updateSageIntacctExport(policyID, {nonReimbursable}); +} + +function updateSageIntacctExportNonReimbursableAccount(policyID: string, nonReimbursableAccount: string) { + updateSageIntacctExport(policyID, {nonReimbursableAccount}); +} + +export { + updateSageIntacctExporter, + updateSageIntacctExportDate, + updateSageIntacctExportReimbursableExpense, + updateSageIntacctDefaultVendor, + updateSageIntacctExportNonReimbursableExpense, + updateSageIntacctExportNonReimbursableAccount, +}; diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx index 2a0564844073..7af7c46b8c1e 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx @@ -8,10 +8,10 @@ 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 {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import {updateSageIntacctExportDate} from '@userActions/connections/SageIntacct'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -44,7 +44,7 @@ function SageIntacctDatePage({policy}: WithPolicyProps) { const selectExportDate = useCallback( (row: MenuListItem) => { if (row.value !== exportDate) { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, {exportDate: row.value}); + updateSageIntacctExportDate(policyID, row.value); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID)); }, diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx index 581ed20b816d..8bd49e00fbc5 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx @@ -10,11 +10,11 @@ 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 {getSageIntacctNonReimbursableActiveDefaultVendor, getSageIntacctVendors} from '@libs/PolicyUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import variables from '@styles/variables'; +import {updateSageIntacctDefaultVendor} from '@userActions/connections/SageIntacct'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -47,7 +47,7 @@ function SageIntacctDefaultVendorPage({route}: SageIntacctDefaultVendorPageProps {translate('workspace.sageIntacct.defaultVendorDescription', isReimbursable)} ), - [translate, styles.pb2, styles.ph5, styles.pb5, styles.textNormal], + [translate, styles.pb2, styles.ph5, styles.pb5, styles.textNormal, isReimbursable], ); const updateDefaultVendor = useCallback( @@ -65,7 +65,7 @@ function SageIntacctDefaultVendorPage({route}: SageIntacctDefaultVendorPageProps } : {nonReimbursableVendor: value}; } - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, settingValue); + updateSageIntacctDefaultVendor(policyID, settingValue); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID)); }, diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx index a5c03617c792..157dc129094c 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx @@ -8,12 +8,12 @@ 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 {getSageIntacctCreditCards} from '@libs/PolicyUtils'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import variables from '@styles/variables'; +import {updateSageIntacctExportNonReimbursableAccount} from '@userActions/connections/SageIntacct'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -39,9 +39,7 @@ function SageIntacctNonReimbursableCreditCardAccountPage({policy}: WithPolicyCon const updateCreditCardAccount = useCallback( ({value}: SelectorType) => { if (value !== nonReimbursableAccount) { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, { - nonReimbursableAccount: value, - }); + updateSageIntacctExportNonReimbursableAccount(policyID, value); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID)); }, diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx index 26c532aea8af..718870df8d92 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx @@ -10,12 +10,12 @@ 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 {getSageIntacctNonReimbursableActiveDefaultVendor} from '@libs/PolicyUtils'; import Navigation from '@navigation/Navigation'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; +import {updateSageIntacctDefaultVendor, updateSageIntacctExportNonReimbursableExpense} from '@userActions/connections/SageIntacct'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {SageIntacctDataElementWithValue} from '@src/types/onyx/Policy'; @@ -57,7 +57,7 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { if (row.value === config?.export.nonReimbursable) { return; } - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, {nonReimbursable: row.value}); + updateSageIntacctExportNonReimbursableExpense(policyID, row.value); }, [config?.export.nonReimbursable, policyID], ); @@ -131,12 +131,12 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { {creditCardAccount} { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, { + updateSageIntacctDefaultVendor(policyID, { nonReimbursableCreditCardChargeDefaultVendor: null, }); setIsSwitchOn(!isSwitchOn); diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx index 0e8fa0a340f5..3558835b3314 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx @@ -8,11 +8,11 @@ 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, isExpensifyTeam} from '@libs/PolicyUtils'; import Navigation from '@navigation/Navigation'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import {updateSageIntacctExporter} from '@userActions/connections/SageIntacct'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -64,7 +64,7 @@ function SageIntacctPreferredExporterPage({policy}: WithPolicyProps) { const selectExporter = useCallback( (row: CardListItem) => { if (row.value !== exportConfiguration?.exporter) { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, {exporter: row.value}); + updateSageIntacctExporter(policyID, row.value); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID)); }, diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx index 38452f1d75b2..ee5968785bb9 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx @@ -10,11 +10,11 @@ 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 '@navigation/Navigation'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; +import {updateSageIntacctDefaultVendor, updateSageIntacctExportReimbursableExpense} from '@userActions/connections/SageIntacct'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {SageIntacctDataElementWithValue} from '@src/types/onyx/Policy'; @@ -55,7 +55,7 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { const selectExportDate = useCallback( (row: MenuListItem) => { if (row.value !== reimbursable) { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, {reimbursable: row.value}); + updateSageIntacctExportReimbursableExpense(policyID, row.value); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID)); }, @@ -107,14 +107,12 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { { - Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, CONST.SAGE_INTACCT_CONFIG.EXPORT, { - reimbursableExpenseReportDefaultVendor: null, - }); + updateSageIntacctDefaultVendor(policyID, {reimbursableExpenseReportDefaultVendor: null}); setIsSwitchOn(!isSwitchOn); }} wrapperStyle={[styles.ph5, styles.pv3]} From bd51b4dfccad9bef916641b2f7b01ac53a27cdf1 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 24 Jun 2024 17:40:25 +0200 Subject: [PATCH 0180/1260] update es translations --- src/languages/es.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index df2f8653df51..0f3a1c73fa80 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2258,7 +2258,8 @@ export default { creditCardAccount: 'Cuenta de tarjeta de crédito', creditCardAccountDescription: '!!!!!!!!', defaultVendor: 'Proveedor por defecto', - defaultVendorDescription: 'Establezca un proveedor predeterminado que se aplicará a los gastos no reembolsables que no tienen un proveedor coincidente en Sage Intacct.', + defaultVendorDescription: (isReimbursable: boolean): string => + `Establezca un proveedor predeterminado que se aplicará a los gastos ${isReimbursable ? '' : 'no '}reembolsables que no tienen un proveedor coincidente en Sage Intacct.`, exportDescription: 'Configure cómo se exportan los datos de Expensify a Sage Inacct.', exportPreferredExporterNote: 'El exportador preferido puede ser cualquier administrador del área de trabajo, pero también debe ser un administrador del dominio si establece diferentes cuentas de exportación para tarjetas de empresa individuales en Configuración del dominio.', From eb27d1912d5c5b06922059945efc0c40936a890a Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 24 Jun 2024 18:08:17 +0200 Subject: [PATCH 0181/1260] unify `noAccountsFound` translations --- src/languages/en.ts | 32 +++++++++---------- src/languages/es.ts | 32 +++++++++---------- .../export/SageIntacctDefaultVendorPage.tsx | 4 +-- ...ctNonReimbursableCreditCardAccountPage.tsx | 4 +-- .../advanced/QuickbooksAccountSelectPage.tsx | 4 +-- .../QuickbooksInvoiceAccountSelectPage.tsx | 4 +-- ...oksCompanyCardExpenseAccountSelectPage.tsx | 4 +-- ...ickbooksExportInvoiceAccountSelectPage.tsx | 4 +-- ...NonReimbursableDefaultVendorSelectPage.tsx | 4 +-- ...oksOutOfPocketExpenseAccountSelectPage.tsx | 4 +-- .../XeroBillPaymentAccountSelectorPage.tsx | 4 +-- .../XeroInvoiceAccountSelectorPage.tsx | 4 +-- .../xero/export/XeroBankAccountSelectPage.tsx | 4 +-- 13 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 7d4365211927..93a3cb9392f7 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -112,6 +112,19 @@ type States = Record; type AllCountries = Record; +function integrationName(integration: ConnectionName): string { + switch (integration) { + case CONST.POLICY.CONNECTIONS.NAME.QBO: + return 'Quickbooks Online'; + case CONST.POLICY.CONNECTIONS.NAME.XERO: + return 'Xero'; + case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: + return 'Sage Intacct'; + default: + return 'Integration'; + } +} + /* eslint-disable max-len */ export default { common: { @@ -1987,6 +2000,8 @@ export default { welcomeNote: ({workspaceName}: WelcomeNoteParams) => `You have been invited to ${workspaceName || 'a workspace'}! Download the Expensify mobile app at use.expensify.com/download to start tracking your expenses.`, subscription: 'Subscription', + noAccountsFound: 'No accounts found', + noAccountsFoundDescription: (integration: ConnectionName) => `Add the account in ${integrationName(integration)} and sync the connection again.`, }, qbo: { importDescription: 'Choose which coding configurations to import from QuickBooks Online to Expensify.', @@ -2099,8 +2114,6 @@ export default { [`${CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.CHECK}Error`]: 'Checks are unavailable when locations are enabled. Please choose a different export option.', [`${CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY}Error`]: 'Journal entries are unavailable when taxes are enabled. Please choose a different export option.', }, - noAccountsFound: 'No accounts found', - noAccountsFoundDescription: 'Add the account in Quickbooks Online and sync the connection again.', }, xero: { organization: 'Xero organization', @@ -2178,8 +2191,6 @@ export default { exportPreferredExporterNote: 'The preferred exporter can be any workspace admin, but must be a domain admin if you set different export accounts for individual company cards in domain settings.', exportPreferredExporterSubNote: 'Once set, the preferred exporter will see reports for export in their account.', - noAccountsFound: 'No accounts found', - noAccountsFoundDescription: 'Add the account in Xero and sync the connection again.', }, sageIntacct: { preferredExporter: 'Preferred exporter', @@ -2452,18 +2463,7 @@ export default { qbo: 'Quickbooks Online', xero: 'Xero', intacct: 'Sage Intacct', - integrationName: (integration?: ConnectionName): string => { - switch (integration) { - case CONST.POLICY.CONNECTIONS.NAME.QBO: - return 'Quickbooks Online'; - case CONST.POLICY.CONNECTIONS.NAME.XERO: - return 'Xero'; - case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: - return 'Sage Intacct'; - default: - return 'Integration'; - } - }, + integrationName, setup: 'Connect', lastSync: 'Last synced just now', import: 'Import', diff --git a/src/languages/es.ts b/src/languages/es.ts index 0f3a1c73fa80..141a17f26aa7 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -103,6 +103,19 @@ import type { ZipCodeExampleFormatParams, } from './types'; +function integrationName(integration: ConnectionName): string { + switch (integration) { + case CONST.POLICY.CONNECTIONS.NAME.QBO: + return 'Quickbooks Online'; + case CONST.POLICY.CONNECTIONS.NAME.XERO: + return 'Xero'; + case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: + return 'Sage Intacct'; + default: + return 'Integration'; + } +} + /* eslint-disable max-len */ export default { common: { @@ -2012,6 +2025,8 @@ export default { welcomeNote: ({workspaceName}: WelcomeNoteParams) => `¡Has sido invitado a ${workspaceName}! Descargue la aplicación móvil Expensify en use.expensify.com/download para comenzar a rastrear sus gastos.`, subscription: 'Suscripción', + noAccountsFound: 'No se ha encontrado ninguna cuenta', + noAccountsFoundDescription: (integration: ConnectionName) => `Añade la cuenta en ${integrationName(integration)} y sincroniza de nuevo la conexión.`, }, qbo: { importDescription: 'Elige que configuraciónes de codificación son importadas desde QuickBooks Online a Expensify.', @@ -2132,8 +2147,6 @@ export default { [`${CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY}Error`]: 'El asiento de diario no está disponible cuando los impuestos están habilitados. Por favor, selecciona otra opción de exportación diferente.', }, - noAccountsFound: 'No se ha encontrado ninguna cuenta', - noAccountsFoundDescription: 'Añade la cuenta en Quickbooks Online y sincroniza de nuevo la conexión.', }, xero: { organization: 'Organización Xero', @@ -2214,8 +2227,6 @@ export default { exportPreferredExporterNote: 'Puede ser cualquier administrador del espacio de trabajo, pero debe ser un administrador de dominio si configura diferentes cuentas de exportación para tarjetas de empresa individuales en la configuración del dominio.', exportPreferredExporterSubNote: 'Una vez configurado, el exportador preferido verá los informes para exportar en su cuenta.', - noAccountsFound: 'No se ha encontrado ninguna cuenta', - noAccountsFoundDescription: 'Añade la cuenta en Xero y sincroniza de nuevo la conexión.', }, sageIntacct: { preferredExporter: 'Exportador preferido', @@ -2456,18 +2467,7 @@ export default { qbo: 'Quickbooks Online', xero: 'Xero', intacct: 'Sage Intacct', - integrationName: (integration?: ConnectionName): string => { - switch (integration) { - case CONST.POLICY.CONNECTIONS.NAME.QBO: - return 'Quickbooks Online'; - case CONST.POLICY.CONNECTIONS.NAME.XERO: - return 'Xero'; - case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: - return 'Sage Intacct'; - default: - return 'Integration'; - } - }, + integrationName, setup: 'Configurar', lastSync: 'Recién sincronizado', import: 'Importar', diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx index 8bd49e00fbc5..a6d431ee1708 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx @@ -79,8 +79,8 @@ function SageIntacctDefaultVendorPage({route}: SageIntacctDefaultVendorPageProps icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.xero.noAccountsFound')} - subtitle={translate('workspace.xero.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx index 157dc129094c..0037b8f54970 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx @@ -53,8 +53,8 @@ function SageIntacctNonReimbursableCreditCardAccountPage({policy}: WithPolicyCon icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.xero.noAccountsFound')} - subtitle={translate('workspace.xero.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx index 3c93bb683166..c0c360bc13ad 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx @@ -67,8 +67,8 @@ function QuickbooksAccountSelectPage({policy}: WithPolicyConnectionsProps) { icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.qbo.noAccountsFound')} - subtitle={translate('workspace.qbo.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.QBO)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx index 0459f61b88d6..b4425751dc35 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx @@ -68,8 +68,8 @@ function QuickbooksInvoiceAccountSelectPage({policy}: WithPolicyConnectionsProps icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.qbo.noAccountsFound')} - subtitle={translate('workspace.qbo.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.QBO)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx index 013539334681..8ed75a402ba5 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx @@ -71,8 +71,8 @@ function QuickbooksCompanyCardExpenseAccountSelectPage({policy}: WithPolicyConne icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.qbo.noAccountsFound')} - subtitle={translate('workspace.qbo.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.QBO)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx index b95e70fe11dd..a07fe1c6deb9 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx @@ -57,8 +57,8 @@ function QuickbooksExportInvoiceAccountSelectPage({policy}: WithPolicyConnection icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.qbo.noAccountsFound')} - subtitle={translate('workspace.qbo.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.QBO)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx index 55c5cf7e9898..5bcabbfbf2fa 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx @@ -56,8 +56,8 @@ function QuickbooksNonReimbursableDefaultVendorSelectPage({policy}: WithPolicyCo icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.qbo.noAccountsFound')} - subtitle={translate('workspace.qbo.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.QBO)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx index 50b44640642b..12594947619b 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx @@ -95,8 +95,8 @@ function QuickbooksOutOfPocketExpenseAccountSelectPage({policy}: WithPolicyConne icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.qbo.noAccountsFound')} - subtitle={translate('workspace.qbo.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.QBO)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx index 05b7cf877d33..5b5bf3e92baa 100644 --- a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx +++ b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx @@ -53,8 +53,8 @@ function XeroBillPaymentAccountSelectorPage({policy}: WithPolicyConnectionsProps icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.xero.noAccountsFound')} - subtitle={translate('workspace.xero.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.XERO)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx index 49fac2e38a9b..c5ec54bc3859 100644 --- a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx +++ b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx @@ -53,8 +53,8 @@ function XeroInvoiceAccountSelectorPage({policy}: WithPolicyConnectionsProps) { icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.xero.noAccountsFound')} - subtitle={translate('workspace.xero.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.XERO)} containerStyle={styles.pb10} /> ), diff --git a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx index 76a6c9cabed1..ff2a484205a5 100644 --- a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx @@ -55,8 +55,8 @@ function XeroBankAccountSelectPage({policy}: WithPolicyConnectionsProps) { icon={Illustrations.TeleScope} iconWidth={variables.emptyListIconWidth} iconHeight={variables.emptyListIconHeight} - title={translate('workspace.xero.noAccountsFound')} - subtitle={translate('workspace.xero.noAccountsFoundDescription')} + title={translate('workspace.common.noAccountsFound')} + subtitle={translate('workspace.common.noAccountsFoundDescription', CONST.POLICY.CONNECTIONS.NAME.XERO)} containerStyle={styles.pb10} /> ), From a111402c972c887c46fddbb79aadb4a72c1695a9 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Mon, 24 Jun 2024 18:15:31 +0200 Subject: [PATCH 0182/1260] replace hard coded strings with translations --- src/ROUTES.ts | 7 +- src/languages/en.ts | 5 +- src/libs/Navigation/types.ts | 5 +- .../intacct/import/SageIntacctImportPage.tsx | 93 ++++++++----------- .../import/SageIntacctMappingsTypePage.tsx | 2 +- .../import/SageIntacctToggleMappingsPage.tsx | 66 +++++++++---- 6 files changed, 97 insertions(+), 81 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 1052a2e92e27..ce460fd42098 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -3,6 +3,7 @@ import type CONST from './CONST'; import type {IOUAction, IOUType} from './CONST'; import type {IOURequestType} from './libs/actions/IOU'; import type {CentralPaneNavigatorParamList} from './libs/Navigation/types'; +import type {SageIntacctMappingName} from './types/onyx/Policy'; import type {SearchQuery} from './types/onyx/SearchResults'; import type AssertTypesNotEqual from './types/utils/AssertTypesNotEqual'; @@ -914,13 +915,11 @@ const ROUTES = { }, POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS: { route: 'settings/workspaces/:policyID/accounting/sage-intacct/import/toggle-mapping/:mapping', - getRoute: (policyID: string, mapping: ValueOf) => - `settings/workspaces/${policyID}/accounting/sage-intacct/import/toggle-mapping/${mapping}` as const, + getRoute: (policyID: string, mapping: SageIntacctMappingName) => `settings/workspaces/${policyID}/accounting/sage-intacct/import/toggle-mapping/${mapping}` as const, }, POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE: { route: 'settings/workspaces/:policyID/accounting/sage-intacct/import/mapping-type/:mapping', - getRoute: (policyID: string, mapping: ValueOf) => - `settings/workspaces/${policyID}/accounting/sage-intacct/import/mapping-type/${mapping}` as const, + getRoute: (policyID: string, mapping: SageIntacctMappingName) => `settings/workspaces/${policyID}/accounting/sage-intacct/import/mapping-type/${mapping}` as const, }, } as const; diff --git a/src/languages/en.ts b/src/languages/en.ts index 11af0d0422fe..86028e86ccb1 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1997,7 +1997,7 @@ export default { case CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CUSTOMERS: return startsWithBigLetter ? 'Customers' : 'customers'; case CONST.SAGE_INTACCT_CONFIG.MAPPINGS.PROJECTS: - return startsWithBigLetter ? 'Projects' : 'projects'; + return startsWithBigLetter ? 'Projects (jobs)' : 'projects (jobs)'; default: return startsWithBigLetter ? 'Mapping' : 'mapping'; } @@ -2196,6 +2196,9 @@ export default { }, intacct: { employeeDefault: 'Sage Intacct employee default', + employeeDefaultDescription: "The employee's default department will be applied to their expenses in Sage Intacct if one exists.", + displayedAsTagDescription: "Department will be selectable for each individual expense on an employee's report.", + displayedAsReportFieldDescription: "Department selection will apply to all expenses on an employee's report.", toggleImportTitleFirstPart: 'Choose how to handle Sage Intacct ', toggleImportTitleSecondPart: ' in Expensify.', }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index ee0bf2dca5a3..61feb43ed645 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -19,6 +19,7 @@ import type NAVIGATORS from '@src/NAVIGATORS'; import type {HybridAppRoute, Route as Routes} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type EXIT_SURVEY_REASON_FORM_INPUT_IDS from '@src/types/form/ExitSurveyReasonForm'; +import type {SageIntacctMappingName} from '@src/types/onyx/Policy'; type NavigationRef = NavigationContainerRefWithCurrent; @@ -390,11 +391,11 @@ type SettingsNavigatorParamList = { }; [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_TOGGLE_MAPPING]: { policyID: string; - mapping: ValueOf; + mapping: SageIntacctMappingName; }; [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_MAPPING_TYPE]: { policyID: string; - mapping: ValueOf; + mapping: SageIntacctMappingName; }; [SCREENS.GET_ASSISTANCE]: { backTo: Routes; diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx index 9c59868042b3..ef258be867dc 100644 --- a/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx +++ b/src/pages/workspace/accounting/intacct/import/SageIntacctImportPage.tsx @@ -1,5 +1,4 @@ import React, {useMemo} from 'react'; -import {View} from 'react-native'; import ConnectionLayout from '@components/ConnectionLayout'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; @@ -11,70 +10,52 @@ import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; import CONST from '@src/CONST'; +import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; +import type {SageIntacctMappingName, SageIntacctMappingValue} from '@src/types/onyx/Policy'; + +function getDisplayTypeTranslationKey(displayType?: SageIntacctMappingValue): TranslationPaths | undefined { + switch (displayType) { + case CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.DEFAULT: { + return 'workspace.intacct.employeeDefault'; + } + case CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.TAG: { + return 'workspace.accounting.importTypes.TAG'; + } + case CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.REPORT_FIELD: { + return 'workspace.accounting.importTypes.REPORT_FIELD'; + } + case CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.NONE: { + return undefined; + } + default: { + return undefined; + } + } +} function SageIntacctImportPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const policyID = policy?.id ?? '-1'; - const {importCustomers, importTaxRates, importTrackingCategories, pendingFields, errorFields} = policy?.connections?.xero?.config ?? {}; + const sageIntacctConfig = policy?.connections?.intacct?.config; const currentXeroOrganizationName = useMemo(() => getCurrentXeroOrganizationName(policy ?? undefined), [policy]); - const sections = useMemo( - () => [ - { - description: 'Departments', - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.DEPARTMENTS)), - title: 'Sage Intacct employee default', - hasError: !!errorFields?.enableNewCategories, - pendingAction: pendingFields?.enableNewCategories, - }, - { - description: 'Classes', - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CLASSES)), - hasError: !!errorFields?.importTrackingCategories, - pendingAction: pendingFields?.importTrackingCategories, - }, - { - description: 'Locations', - action: () => { - Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.LOCATIONS)); - }, - hasError: !!errorFields?.importCustomers, - title: 'Imported, displayed as tags', - pendingAction: pendingFields?.importCustomers, - }, - { - description: 'Customers', - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.CUSTOMERS)), - hasError: !!errorFields?.importTaxRates, - title: 'Imported, displayed as report fields', - pendingAction: pendingFields?.importTaxRates, - }, - { - description: 'Projects (jobs)', - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.MAPPINGS.PROJECTS)), - hasError: !!errorFields?.importTaxRates, - pendingAction: pendingFields?.importTaxRates, - }, - ], - [ - translate, - errorFields?.enableNewCategories, - errorFields?.importTrackingCategories, - errorFields?.importCustomers, - errorFields?.importTaxRates, - pendingFields?.enableNewCategories, - pendingFields?.importTrackingCategories, - pendingFields?.importCustomers, - pendingFields?.importTaxRates, - importTrackingCategories, - importCustomers, - importTaxRates, - policyID, - ], + const mapingItems = useMemo( + () => + Object.values(CONST.SAGE_INTACCT_CONFIG.MAPPINGS).map((mapping: SageIntacctMappingName) => { + const menuItemTitleKey = getDisplayTypeTranslationKey(sageIntacctConfig?.mappings?.[mapping]); + return { + description: translate('workspace.common.mappingTitle', mapping, true), + action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_TOGGLE_MAPPINGS.getRoute(policyID, mapping)), + title: menuItemTitleKey ? translate(menuItemTitleKey) : undefined, + hasError: !!sageIntacctConfig?.mappings?.errorFields?.[mapping], + pendingAction: sageIntacctConfig?.mappings?.pendingFields?.[mapping], + }; + }), + [policyID, sageIntacctConfig?.mappings, translate], ); return ( @@ -110,7 +91,7 @@ function SageIntacctImportPage({policy}: WithPolicyProps) { onToggle={() => {}} /> - {sections.map((section) => ( + {mapingItems.map((section) => ( ; +type DisplayTypeTranslationKeys = { + titleKey: TranslationPaths; + descriptionKey: TranslationPaths; +}; + +function getDisplayTypeTranslationKeys(displayType?: SageIntacctMappingValue): DisplayTypeTranslationKeys | undefined { + switch (displayType) { + case CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.DEFAULT: { + return {titleKey: 'workspace.intacct.employeeDefault', descriptionKey: 'workspace.intacct.employeeDefaultDescription'}; + } + case CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.TAG: { + return {titleKey: 'workspace.common.tags', descriptionKey: 'workspace.intacct.displayedAsTagDescription'}; + } + case CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.REPORT_FIELD: { + return {titleKey: 'workspace.common.reportFields', descriptionKey: 'workspace.intacct.displayedAsReportFieldDescription'}; + } + case CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.NONE: { + return undefined; + } + default: { + return undefined; + } + } +} + function SageIntacctToggleMappingsPage({route}: SageIntacctToggleMappingsPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -28,6 +55,7 @@ function SageIntacctToggleMappingsPage({route}: SageIntacctToggleMappingsPagePro const policyID = policy?.id ?? '-1'; const mappings = policy?.connections?.intacct?.config?.mappings; + const translationKeys = getDisplayTypeTranslationKeys(mappings?.[mapping]); const [importDepartments, setImportDepartments] = useState(mappings?.[mapping] && mappings?.[mapping] !== CONST.SAGE_INTACCT_CONFIG.MAPPING_VALUE.NONE); const updateFunction = SageIntacctConnection.getUpdateFunctionForMapping(mapping); @@ -67,25 +95,29 @@ function SageIntacctToggleMappingsPage({route}: SageIntacctToggleMappingsPagePro } }} /> - - Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.getRoute(policyID, mapping))} - // brickRoadIndicator={section.hasError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} - /> - - - The employee’s default department will be applied to their expenses in Sage Intacct if one exists. - + {importDepartments && ( + + + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_MAPPINGS_TYPE.getRoute(policyID, mapping))} + brickRoadIndicator={mappings?.errorFields?.[mapping] ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} + /> + + + {translationKeys?.descriptionKey ? translate(translationKeys?.descriptionKey) : undefined} + + + )} ); } -SageIntacctToggleMappingsPage.displayName = 'PolicySageIntacctImportPage'; +SageIntacctToggleMappingsPage.displayName = 'SageIntacctToggleMappingsPage'; export default SageIntacctToggleMappingsPage; From 9dd45824512ec205e8f42762bd73a25329dca592 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 24 Jun 2024 18:18:09 +0200 Subject: [PATCH 0183/1260] test on empty list --- src/languages/en.ts | 1 + .../accounting/intacct/export/SageIntacctDefaultVendorPage.tsx | 1 - .../export/SageIntacctNonReimbursableCreditCardAccountPage.tsx | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 93a3cb9392f7..a4dc962de0c8 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2231,6 +2231,7 @@ export default { }, }, creditCardAccount: 'Credit card account', + // TODO: verify if we need description creditCardAccountDescription: 'We should have some description here, right?', defaultVendor: 'Default vendor', defaultVendorDescription: (isReimbursable: boolean): string => diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx index a6d431ee1708..b42115ae0379 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx @@ -72,7 +72,6 @@ function SageIntacctDefaultVendorPage({route}: SageIntacctDefaultVendorPageProps [defaultVendor, policyID, isReimbursable, policy?.connections?.intacct?.config.export], ); - // TODO: test on empty list const listEmptyContent = useMemo( () => ( ( Date: Mon, 24 Jun 2024 12:52:40 -0700 Subject: [PATCH 0184/1260] remove debug logs --- src/libs/OptionsListUtils.ts | 7 +------ src/libs/ReportUtils.ts | 5 +++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 504c6c8ac8d0..b47583f3469e 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1875,8 +1875,6 @@ function getOptions( }); }); - console.log(">>>> filtered", filteredReportOptions); - // Sorting the reports works like this: // - Order everything by the last message timestamp (descending) // - When searching, self DM is put at the top @@ -1955,7 +1953,7 @@ function getOptions( return option; }); - console.log(">>>> allReportOptions", allReportOptions); + console.log('>>>> allReportOptions', allReportOptions); const havingLoginPersonalDetails = includeP2P ? options.personalDetails.filter((detail) => !!detail?.login && !!detail.accountID && !detail?.isOptimisticPersonalDetail) : []; let allPersonalDetailsOptions = havingLoginPersonalDetails; @@ -2037,7 +2035,6 @@ function getOptions( const isSearchMatch = isSearchStringMatch(searchValue, searchText, participantNames, isChatRoom); if (!isReportIdSearch && !isSearchMatch) { - console.log(">>> filtering out", reportOption); continue; } } @@ -2462,8 +2459,6 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt optionsToExclude.push({login}); }); - console.log(">>>> options", options); - const getParticipantsLoginsArray = (item: ReportUtils.OptionData) => { const keys: string[] = []; const visibleChatMemberAccountIDs = item.participantsList ?? []; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index c17af5cbedb0..b7560a096cf5 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5414,7 +5414,8 @@ function shouldReportBeInOptionList({ // We omit sending back participants for chat rooms when searching for reports since they aren't needed to display the results and can get very large. // So we allow showing rooms with no participants when searching for reports. // In any other circumstances we should never have default rooms with no participants in Onyx. - (!isSearchingForReports && isUnsearchableViaParticipants(report))) + !isSearchingForReports && + isUnsearchableViaParticipants(report)) ) { return false; } @@ -7297,7 +7298,7 @@ export { createDraftWorkspaceAndNavigateToConfirmationScreen, isChatUsedForOnboarding, getChatUsedForOnboarding, - isUnsearchableViaParticipants + isUnsearchableViaParticipants, }; export type { From d0fb81dbf1ed47bbf1788c95f795fc87044a89e9 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 24 Jun 2024 12:53:18 -0700 Subject: [PATCH 0185/1260] remove debug logs --- src/libs/OptionsListUtils.ts | 2 -- src/libs/ReportUtils.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index b47583f3469e..137f01ed1c7d 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1953,8 +1953,6 @@ function getOptions( return option; }); - console.log('>>>> allReportOptions', allReportOptions); - const havingLoginPersonalDetails = includeP2P ? options.personalDetails.filter((detail) => !!detail?.login && !!detail.accountID && !detail?.isOptimisticPersonalDetail) : []; let allPersonalDetailsOptions = havingLoginPersonalDetails; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index b7560a096cf5..b350eaaeb3e8 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -977,7 +977,7 @@ function isChatRoom(report: OnyxEntry): boolean { * Whether the provided report is not searchable via participant */ function isUnsearchableViaParticipants(report: OnyxEntry): boolean { - return isUserCreatedPolicyRoom(report) || isDefaultRoom(report) || isInvoiceRoom(report) || isInvoiceRoom(report) || isTripRoom(report); + return isUserCreatedPolicyRoom(report) || isDefaultRoom(report) || isInvoiceRoom(report) || isTripRoom(report); } /** From 76f675ddcb6e13ce03f495de3327a640344e33cd Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 24 Jun 2024 12:53:47 -0700 Subject: [PATCH 0186/1260] update comment --- src/libs/OptionsListUtils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 137f01ed1c7d..56a892d70020 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -2510,7 +2510,6 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt // We don't want the following to be searchable by participant: // - Default rooms // - Policy rooms - // - Policy expense chats // - Invoice rooms // - Trip rooms if (!item.isUnsearchableViaParticipants) { From d10afcbc59b5d5ecbda2870000b6836266c107eb Mon Sep 17 00:00:00 2001 From: dominictb Date: Tue, 25 Jun 2024 10:02:38 +0700 Subject: [PATCH 0187/1260] fix: do not refresh draft txn after redirect --- src/libs/actions/IOU.ts | 15 +++++++++++++++ src/pages/iou/request/IOURequestStartPage.tsx | 10 +++++++++- .../request/step/IOURequestStepConfirmation.tsx | 3 ++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index bc4569bf4603..77c4378c325f 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -364,6 +364,20 @@ function initMoneyRequest(reportID: string, policy: OnyxEntry, }); } +/** + * + * @param transactionID + * @param reportID + */ +function resetMoneyRequest(transactionID: string, reportID: string, isFromGlobalCreate: boolean) { + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, { + reportID, + participants: [], + participantsAutoAssigned: false, + isFromGlobalCreate, + }); +} + function createDraftTransaction(transaction: OnyxTypes.Transaction) { if (!transaction) { return; @@ -6998,6 +7012,7 @@ export { detachReceipt, editMoneyRequest, initMoneyRequest, + resetMoneyRequest, navigateToStartStepIfScanFileCannotBeRead, payMoneyRequest, payInvoice, diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index 44f3c1b6a1bc..d576f0b5546c 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -96,6 +96,11 @@ function IOURequestStartPage({ if (transaction?.reportID === reportID) { return; } + // if transaction is from global create, reset the reportID & participant + if (transaction?.isFromGlobalCreate && transaction.transactionID) { + IOU.resetMoneyRequest(transaction.transactionID, reportID, isFromGlobalCreate); + return; + } IOU.initMoneyRequest(reportID, policy, isFromGlobalCreate, transactionRequestType.current); }, [transaction, policy, reportID, iouType, isFromGlobalCreate]); @@ -109,9 +114,12 @@ function IOURequestStartPage({ const resetIOUTypeIfChanged = useCallback( (newIOUType: IOURequestType) => { + if (transaction?.iouRequestType === newIOUType) { + return; + } IOU.initMoneyRequest(reportID, policy, isFromGlobalCreate, newIOUType); }, - [policy, reportID, isFromGlobalCreate], + [policy, reportID, isFromGlobalCreate, transaction?.iouRequestType], ); if (!transaction?.transactionID) { diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index ea03c9ae3b06..00f43f0c8a63 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -189,7 +189,8 @@ function IOURequestStepConfirmation({ // If there is not a report attached to the IOU with a reportID, then the participants were manually selected and the user needs taken // back to the participants step if (!transaction?.participantsAutoAssigned) { - Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_PARTICIPANTS.getRoute(iouType, transactionID, reportID, undefined, action)); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_PARTICIPANTS.getRoute(iouType, transactionID, transaction?.reportID || reportID, undefined, action)); return; } IOUUtils.navigateToStartMoneyRequestStep(requestType, iouType, transactionID, reportID, action); From 9c096648ad8ab8e0572cba385c74114a90740f00 Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Tue, 25 Jun 2024 08:25:13 +0200 Subject: [PATCH 0188/1260] Small fixes on search empty page, add new empty component on tags and category pages --- src/components/EmptyStateComponent/index.tsx | 6 +++--- src/components/EmptyStateComponent/types.ts | 4 ++-- src/components/Search.tsx | 16 ++-------------- .../Skeletons/ItemListSkeletonView.tsx | 2 +- src/components/Skeletons/SearchRowSkeleton.tsx | 1 + src/languages/en.ts | 4 ---- src/languages/es.ts | 4 ---- src/pages/Search/EmptySearchView.tsx | 14 ++++++++++---- .../categories/WorkspaceCategoriesPage.tsx | 11 ++++++++--- src/pages/workspace/tags/WorkspaceTagsPage.tsx | 11 ++++++++--- 10 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/components/EmptyStateComponent/index.tsx b/src/components/EmptyStateComponent/index.tsx index a6bd07b94550..24f75fa832f5 100644 --- a/src/components/EmptyStateComponent/index.tsx +++ b/src/components/EmptyStateComponent/index.tsx @@ -20,7 +20,7 @@ type VideoLoadedEventType = { }; }; -function EmptyStateComponent({SkeletonComponent, headerMediaType, headerMedia, buttonText, buttonAction, titleText, subtitleText, headerStyles}: EmptyStateComponentProps) { +function EmptyStateComponent({SkeletonComponent, headerMediaType, headerMedia, buttonText, buttonAction, title, subtitle, headerStyles}: EmptyStateComponentProps) { const styles = useThemeStyles(); const isSmallScreenWidth = getIsSmallScreenWidth(); @@ -85,8 +85,8 @@ function EmptyStateComponent({SkeletonComponent, headerMediaType, headerMedia, b {HeaderComponent} - {titleText} - {subtitleText} + {title} + {subtitle} {buttonText && buttonAction && (