From b6e964d834f34721eff372e970dd7a2bae13d43a Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 1 May 2024 11:15:29 +0700 Subject: [PATCH 1/8] xero import customer --- src/ROUTES.ts | 4 + src/SCREENS.ts | 1 + .../ModalStackNavigators/index.tsx | 44 +++------- .../FULL_SCREEN_TO_RHP_MAPPING.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 1 + src/libs/Navigation/types.ts | 3 + .../accounting/xero/XeroImportPage.tsx | 6 +- .../import/XeroCustomerConfigurationPage.tsx | 81 +++++++++++++++++++ src/types/onyx/Policy.ts | 1 + 9 files changed, 106 insertions(+), 36 deletions(-) create mode 100644 src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index bbcc5d937ba3..5a5c6a3590a2 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -769,6 +769,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/xero/organization/:currentOrganizationID', getRoute: (policyID: string, currentOrganizationID: string) => `settings/workspaces/${policyID}/accounting/xero/organization/${currentOrganizationID}` as const, }, + POLICY_ACCOUNTING_XERO_CUSTOMER: { + route: '/settings/workspaces/:policyID/accounting/xero/import/customers', + getRoute: (policyID: string) => `/settings/workspaces/${policyID}/accounting/xero/import/customers` as const, + }, POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_IMPORT: { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index cf97c0ea2c0d..ccb83af5c65a 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -235,6 +235,7 @@ const SCREENS = { QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR: 'Policy_Accounting_Quickbooks_Online_Invoice_Account_Selector', XERO_IMPORT: 'Policy_Accounting_Xero_Import', XERO_ORGANIZATION: 'Policy_Accounting_Xero_Customers', + XERO_CUSTOMER: 'Policy_Acounting_Xero_Import_Customer' }, 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 2ae41e493a8f..457a3ca38f37 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1,42 +1,15 @@ -import type {ParamListBase} from '@react-navigation/routers'; -import type {StackNavigationOptions} from '@react-navigation/stack'; -import {createStackNavigator} from '@react-navigation/stack'; +import type { ParamListBase } from '@react-navigation/routers'; +import type { StackNavigationOptions } from '@react-navigation/stack'; +import { createStackNavigator } from '@react-navigation/stack'; import React from 'react'; -import type { - AddPersonalBankAccountNavigatorParamList, - ChatFinderNavigatorParamList, - DetailsNavigatorParamList, - EditRequestNavigatorParamList, - EnablePaymentsNavigatorParamList, - FlagCommentNavigatorParamList, - MoneyRequestNavigatorParamList, - NewChatNavigatorParamList, - NewTaskNavigatorParamList, - ParticipantsNavigatorParamList, - PrivateNotesNavigatorParamList, - ProfileNavigatorParamList, - ReferralDetailsNavigatorParamList, - ReimbursementAccountNavigatorParamList, - ReportDescriptionNavigatorParamList, - ReportDetailsNavigatorParamList, - ReportSettingsNavigatorParamList, - RoomInviteNavigatorParamList, - RoomMembersNavigatorParamList, - SearchReportParamList, - SettingsNavigatorParamList, - SignInNavigatorParamList, - SplitDetailsNavigatorParamList, - TaskDetailsNavigatorParamList, - TeachersUniteNavigatorParamList, - WalletStatementNavigatorParamList, - WorkspaceSwitcherNavigatorParamList, -} from '@navigation/types'; -import type {ThemeStyles} from '@styles/index'; -import type {Screen} from '@src/SCREENS'; +import type { AddPersonalBankAccountNavigatorParamList, ChatFinderNavigatorParamList, DetailsNavigatorParamList, EditRequestNavigatorParamList, EnablePaymentsNavigatorParamList, FlagCommentNavigatorParamList, MoneyRequestNavigatorParamList, NewChatNavigatorParamList, NewTaskNavigatorParamList, ParticipantsNavigatorParamList, PrivateNotesNavigatorParamList, ProfileNavigatorParamList, ReferralDetailsNavigatorParamList, ReimbursementAccountNavigatorParamList, ReportDescriptionNavigatorParamList, ReportDetailsNavigatorParamList, ReportSettingsNavigatorParamList, RoomInviteNavigatorParamList, RoomMembersNavigatorParamList, SearchReportParamList, SettingsNavigatorParamList, SignInNavigatorParamList, SplitDetailsNavigatorParamList, TaskDetailsNavigatorParamList, TeachersUniteNavigatorParamList, WalletStatementNavigatorParamList, WorkspaceSwitcherNavigatorParamList } from '@navigation/types'; +import type { ThemeStyles } from '@styles/index'; +import type { Screen } from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; import useModalScreenOptions from './useModalScreenOptions'; import WorkspaceSettingsModalStackNavigator from './WorkspaceSettingsModalStackNavigator'; + type Screens = Partial React.ComponentType>>; /** @@ -294,6 +267,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/accounting/xero/XeroImportPage').default as React.ComponentType, [SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: () => require('../../../../pages/workspace/accounting/xero/XeroOrganizationConfigurationPage').default as React.ComponentType, + [SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: () => require('../../../../pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage').default as React.ComponentType, [SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY]: () => require('../../../../pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage').default as React.ComponentType, [SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET]: () => require('../../../../pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage').default as React.ComponentType, @@ -378,4 +352,4 @@ export { ProcessMoneyRequestHoldStackNavigator, WorkspaceSettingsModalStackNavigator, SearchReportModalStackNavigator, -}; +}; \ No newline at end of file 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 a4c3a399f869..0e22a34f0b3e 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -41,6 +41,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR, SCREENS.WORKSPACE.ACCOUNTING.XERO_IMPORT, SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION, + SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER, ], [SCREENS.WORKSPACE.TAXES]: [ SCREENS.WORKSPACE.TAXES_SETTINGS, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 1e2075b53acc..c7a6c3cd4d47 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -322,6 +322,7 @@ const config: LinkingOptions['config'] = { }, [SCREENS.WORKSPACE.ACCOUNTING.XERO_IMPORT]: {path: ROUTES.POLICY_ACCOUNTING_XERO_IMPORT.route}, [SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: {path: ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.route}, + [SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: {path: ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.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 e8a1c2c69c33..f7e61ff3a060 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -310,6 +310,9 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.XERO_IMPORT]: { policyID: string; }; + [SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: { + policyID: string; + }; [SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: { policyID: string; organizationID: string; diff --git a/src/pages/workspace/accounting/xero/XeroImportPage.tsx b/src/pages/workspace/accounting/xero/XeroImportPage.tsx index 3c1455e9ee65..8735841cddd9 100644 --- a/src/pages/workspace/accounting/xero/XeroImportPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroImportPage.tsx @@ -12,6 +12,8 @@ import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import CONST from '@src/CONST'; import type {Tenant} from '@src/types/onyx/Policy'; +import Navigation from '@libs/Navigation/Navigation'; +import ROUTES from '@src/ROUTES'; function XeroImportPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); @@ -41,7 +43,9 @@ function XeroImportPage({policy}: WithPolicyProps) { }, { description: translate('workspace.xero.customers'), - action: () => {}, + action: () => { + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.getRoute(policyID)) + }, hasError: !!policy?.errors?.importCustomers, title: importCustomers ? translate('workspace.accounting.importedAsTags') : '', pendingAction: pendingFields?.importCustomers, diff --git a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx new file mode 100644 index 000000000000..00aa67bc3c86 --- /dev/null +++ b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx @@ -0,0 +1,81 @@ +import React from 'react'; +import { View } from 'react-native'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import ScreenWrapper from '@components/ScreenWrapper'; +import ScrollView from '@components/ScrollView'; +import Switch from '@components/Switch'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as Connections from '@libs/actions/connections'; +import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; +import type { WithPolicyProps } from '@pages/workspace/withPolicy'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; + + +function XeroCustomerConfigurationPage({policy}: WithPolicyProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const policyID = policy?.id ?? ''; + const {syncCustomers, pendingFields} = policy?.connections?.xero?.config ?? {}; + + const isSwitchOn = Boolean(syncCustomers && syncCustomers !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE); + const isReportFieldsSelected = syncCustomers === CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD; + return ( + + + + + {translate('workspace.qbo.customersDescription')} + + + {translate('workspace.accounting.import')} + + + + + Connections.updatePolicyConnectionConfig( + policyID, + CONST.POLICY.CONNECTIONS.NAME.XERO, + CONST.QUICK_BOOKS_CONFIG.SYNC_CUSTOMERS, + isSwitchOn ? CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE : CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + ) + } + /> + + + + {isSwitchOn && ( + + + + )} + + + + ); +} + +XeroCustomerConfigurationPage.displayName = 'XeroCustomerConfigurationPage'; + +export default withPolicyConnections(XeroCustomerConfigurationPage); \ No newline at end of file diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 54d6198f4078..8e2a66f0aee1 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -235,6 +235,7 @@ type XeroConnectionConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{ importCustomers: boolean; importTaxRates: boolean; importTrackingCategories: boolean; + syncCustomers: IntegrationEntityMap; isConfigured: boolean; mappings: { customer: string; From 3f7639fa7e6d0ee2a18683172f9901ef2117d457 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 1 May 2024 13:42:05 +0700 Subject: [PATCH 2/8] add connection layout --- src/SCREENS.ts | 2 +- src/components/ConnectionLayout.tsx | 64 ++++++++++++++ .../ModalStackNavigators/index.tsx | 43 +++++++-- .../workspace/AccessOrNotFoundWrapper.tsx | 2 + .../accounting/xero/XeroImportPage.tsx | 6 +- .../import/XeroCustomerConfigurationPage.tsx | 87 +++++++++---------- 6 files changed, 146 insertions(+), 58 deletions(-) create mode 100644 src/components/ConnectionLayout.tsx diff --git a/src/SCREENS.ts b/src/SCREENS.ts index ccb83af5c65a..a81e48161694 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -235,7 +235,7 @@ const SCREENS = { QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR: 'Policy_Accounting_Quickbooks_Online_Invoice_Account_Selector', XERO_IMPORT: 'Policy_Accounting_Xero_Import', XERO_ORGANIZATION: 'Policy_Accounting_Xero_Customers', - XERO_CUSTOMER: 'Policy_Acounting_Xero_Import_Customer' + XERO_CUSTOMER: 'Policy_Acounting_Xero_Import_Customer', }, INITIAL: 'Workspace_Initial', PROFILE: 'Workspace_Profile', diff --git a/src/components/ConnectionLayout.tsx b/src/components/ConnectionLayout.tsx new file mode 100644 index 000000000000..911d73f0032b --- /dev/null +++ b/src/components/ConnectionLayout.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import {View} from 'react-native'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@libs/Navigation/Navigation'; +import type {PolicyAccessVariant} from '@pages/workspace/AccessOrNotFoundWrapper'; +import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; +import type {TranslationPaths} from '@src/languages/types'; +import type {PolicyFeatureName} from '@src/types/onyx/Policy'; +import HeaderWithBackButton from './HeaderWithBackButton'; +import ScreenWrapper from './ScreenWrapper'; +import ScrollView from './ScrollView'; +import Text from './Text'; + +type ConnectionLayoutProps = { + /** Used to set the testID for tests */ + displayName: string; + /** Header title for the connection */ + headerTitle: TranslationPaths; + /** React nodes that will be shown */ + children?: React.ReactNode; + /** Title of the connection component */ + title?: TranslationPaths; + /** Subtitle of the connection */ + subtitle?: TranslationPaths; + /** The current policyID */ + policyID: string; + /** Defines which types of access should be verified */ + accessVariants?: PolicyAccessVariant[]; + /** The current feature name that the user tries to get access to */ + featureName?: PolicyFeatureName; +}; + +function ConnectionLayout({displayName, headerTitle, children, title, subtitle, policyID, accessVariants, featureName}: ConnectionLayoutProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + return ( + + + Navigation.goBack()} + /> + + {title && {translate(title)}} + {subtitle && {translate(subtitle)}} + {children} + + + + ); +} + +ConnectionLayout.displayName = 'ConnectionLayout'; +export default ConnectionLayout; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 457a3ca38f37..ce7981f7b702 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1,15 +1,42 @@ -import type { ParamListBase } from '@react-navigation/routers'; -import type { StackNavigationOptions } from '@react-navigation/stack'; -import { createStackNavigator } from '@react-navigation/stack'; +import type {ParamListBase} from '@react-navigation/routers'; +import type {StackNavigationOptions} from '@react-navigation/stack'; +import {createStackNavigator} from '@react-navigation/stack'; import React from 'react'; -import type { AddPersonalBankAccountNavigatorParamList, ChatFinderNavigatorParamList, DetailsNavigatorParamList, EditRequestNavigatorParamList, EnablePaymentsNavigatorParamList, FlagCommentNavigatorParamList, MoneyRequestNavigatorParamList, NewChatNavigatorParamList, NewTaskNavigatorParamList, ParticipantsNavigatorParamList, PrivateNotesNavigatorParamList, ProfileNavigatorParamList, ReferralDetailsNavigatorParamList, ReimbursementAccountNavigatorParamList, ReportDescriptionNavigatorParamList, ReportDetailsNavigatorParamList, ReportSettingsNavigatorParamList, RoomInviteNavigatorParamList, RoomMembersNavigatorParamList, SearchReportParamList, SettingsNavigatorParamList, SignInNavigatorParamList, SplitDetailsNavigatorParamList, TaskDetailsNavigatorParamList, TeachersUniteNavigatorParamList, WalletStatementNavigatorParamList, WorkspaceSwitcherNavigatorParamList } from '@navigation/types'; -import type { ThemeStyles } from '@styles/index'; -import type { Screen } from '@src/SCREENS'; +import type { + AddPersonalBankAccountNavigatorParamList, + ChatFinderNavigatorParamList, + DetailsNavigatorParamList, + EditRequestNavigatorParamList, + EnablePaymentsNavigatorParamList, + FlagCommentNavigatorParamList, + MoneyRequestNavigatorParamList, + NewChatNavigatorParamList, + NewTaskNavigatorParamList, + ParticipantsNavigatorParamList, + PrivateNotesNavigatorParamList, + ProfileNavigatorParamList, + ReferralDetailsNavigatorParamList, + ReimbursementAccountNavigatorParamList, + ReportDescriptionNavigatorParamList, + ReportDetailsNavigatorParamList, + ReportSettingsNavigatorParamList, + RoomInviteNavigatorParamList, + RoomMembersNavigatorParamList, + SearchReportParamList, + SettingsNavigatorParamList, + SignInNavigatorParamList, + SplitDetailsNavigatorParamList, + TaskDetailsNavigatorParamList, + TeachersUniteNavigatorParamList, + WalletStatementNavigatorParamList, + WorkspaceSwitcherNavigatorParamList, +} from '@navigation/types'; +import type {ThemeStyles} from '@styles/index'; +import type {Screen} from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; import useModalScreenOptions from './useModalScreenOptions'; import WorkspaceSettingsModalStackNavigator from './WorkspaceSettingsModalStackNavigator'; - type Screens = Partial React.ComponentType>>; /** @@ -352,4 +379,4 @@ export { ProcessMoneyRequestHoldStackNavigator, WorkspaceSettingsModalStackNavigator, SearchReportModalStackNavigator, -}; \ No newline at end of file +}; diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index b6b641979319..16e81ea747c6 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -111,6 +111,8 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps return callOrReturn(props.children, props); } +export type {PolicyAccessVariant}; + export default withOnyx({ policy: { key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID ?? ''}`, diff --git a/src/pages/workspace/accounting/xero/XeroImportPage.tsx b/src/pages/workspace/accounting/xero/XeroImportPage.tsx index 8735841cddd9..0dd49a38646b 100644 --- a/src/pages/workspace/accounting/xero/XeroImportPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroImportPage.tsx @@ -7,13 +7,13 @@ import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@libs/Navigation/Navigation'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import CONST from '@src/CONST'; -import type {Tenant} from '@src/types/onyx/Policy'; -import Navigation from '@libs/Navigation/Navigation'; import ROUTES from '@src/ROUTES'; +import type {Tenant} from '@src/types/onyx/Policy'; function XeroImportPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); @@ -44,7 +44,7 @@ function XeroImportPage({policy}: WithPolicyProps) { { description: translate('workspace.xero.customers'), action: () => { - Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.getRoute(policyID)) + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.getRoute(policyID)); }, hasError: !!policy?.errors?.importCustomers, title: importCustomers ? translate('workspace.accounting.importedAsTags') : '', diff --git a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx index 00aa67bc3c86..a6b30aac4f9a 100644 --- a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx +++ b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx @@ -1,5 +1,6 @@ import React from 'react'; -import { View } from 'react-native'; +import {View} from 'react-native'; +import ConnectionLayout from '@components/ConnectionLayout'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; @@ -11,71 +12,65 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Connections from '@libs/actions/connections'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; -import type { WithPolicyProps } from '@pages/workspace/withPolicy'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import variables from '@styles/variables'; import CONST from '@src/CONST'; - function XeroCustomerConfigurationPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const policyID = policy?.id ?? ''; const {syncCustomers, pendingFields} = policy?.connections?.xero?.config ?? {}; - + const isSwitchOn = Boolean(syncCustomers && syncCustomers !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE); const isReportFieldsSelected = syncCustomers === CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD; return ( - - - - - {translate('workspace.qbo.customersDescription')} - - - {translate('workspace.accounting.import')} - - - - - Connections.updatePolicyConnectionConfig( - policyID, - CONST.POLICY.CONNECTIONS.NAME.XERO, - CONST.QUICK_BOOKS_CONFIG.SYNC_CUSTOMERS, - isSwitchOn ? CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE : CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, - ) - } - /> - - + + + + {translate('workspace.accounting.import')} - {isSwitchOn && ( - - + + + Connections.updatePolicyConnectionConfig( + policyID, + CONST.POLICY.CONNECTIONS.NAME.XERO, + CONST.QUICK_BOOKS_CONFIG.SYNC_CUSTOMERS, + isSwitchOn ? CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE : CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + ) + } /> - - )} - - - + + + + {isSwitchOn && ( + + + + )} + + ); } XeroCustomerConfigurationPage.displayName = 'XeroCustomerConfigurationPage'; -export default withPolicyConnections(XeroCustomerConfigurationPage); \ No newline at end of file +export default withPolicyConnections(XeroCustomerConfigurationPage); From 5b7c0372febc0c50581d8ea0b0c6a0d4528a86e3 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 1 May 2024 14:26:49 +0700 Subject: [PATCH 3/8] fix linting --- src/components/ConnectionLayout.tsx | 2 +- src/languages/en.ts | 1 + src/languages/es.ts | 2 ++ .../xero/import/XeroCustomerConfigurationPage.tsx | 10 +++------- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/ConnectionLayout.tsx b/src/components/ConnectionLayout.tsx index 911d73f0032b..83119dce2913 100644 --- a/src/components/ConnectionLayout.tsx +++ b/src/components/ConnectionLayout.tsx @@ -51,7 +51,7 @@ function ConnectionLayout({displayName, headerTitle, children, title, subtitle, onBackButtonPress={() => Navigation.goBack()} /> - {title && {translate(title)}} + {title && {translate(title)}} {subtitle && {translate(subtitle)}} {children} diff --git a/src/languages/en.ts b/src/languages/en.ts index 656d6cbd31c3..5dbe6dd64477 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1993,6 +1993,7 @@ export default { importDescription: 'Choose which coding configurations are imported from Xero to Expensify.', trackingCategories: 'Tracking categories', customers: 'Re-bill customers', + customersDescription: 'Import customer contacts. Billable expenses need tags for export. Expenses will carry the customer information to Xero for sales invoices.', }, type: { free: 'Free', diff --git a/src/languages/es.ts b/src/languages/es.ts index aaab540d1659..7e54d1e58962 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2020,6 +2020,8 @@ export default { importDescription: 'Elija qué configuraciones de codificación se importan de Xero a Expensify.', trackingCategories: 'Categorías de seguimiento', customers: 'Volver a facturar a los clientes', + customersDescription: + 'Importar contactos de clientes. Los gastos facturables necesitan etiquetas para la exportación. Los gastos llevarán la información del cliente a Xero para las facturas de ventas.', }, type: { free: 'Gratis', diff --git a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx index a6b30aac4f9a..47dbb4c9ad36 100644 --- a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx +++ b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx @@ -1,17 +1,13 @@ import React from 'react'; import {View} from 'react-native'; import ConnectionLayout from '@components/ConnectionLayout'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; -import ScreenWrapper from '@components/ScreenWrapper'; -import ScrollView from '@components/ScrollView'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Connections from '@libs/actions/connections'; -import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import variables from '@styles/variables'; @@ -28,8 +24,8 @@ function XeroCustomerConfigurationPage({policy}: WithPolicyProps) { return ( Connections.updatePolicyConnectionConfig( From f021eff7a13a9faeec3d28bc51233663545075b8 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 1 May 2024 15:18:27 +0700 Subject: [PATCH 4/8] add pending field for switch --- .../accounting/xero/import/XeroCustomerConfigurationPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx index 47dbb4c9ad36..ad78b0aed85d 100644 --- a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx +++ b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx @@ -53,7 +53,7 @@ function XeroCustomerConfigurationPage({policy}: WithPolicyProps) { {isSwitchOn && ( - + Date: Wed, 1 May 2024 16:51:55 +0700 Subject: [PATCH 5/8] fix linting --- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 1 + src/pages/workspace/accounting/xero/XeroImportPage.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index 48888c054813..e72215e50ad1 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -124,6 +124,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting } return policy?.connections?.xero?.data?.tenants ?? []; }, [policy]); + const currentXeroOrganization = tenants.find((tenant) => tenant.id === policy?.connections?.xero.config.tenantID); const overflowMenu: ThreeDotsMenuProps['menuItems'] = useMemo( diff --git a/src/pages/workspace/accounting/xero/XeroImportPage.tsx b/src/pages/workspace/accounting/xero/XeroImportPage.tsx index 0dd49a38646b..9806f1e25750 100644 --- a/src/pages/workspace/accounting/xero/XeroImportPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroImportPage.tsx @@ -71,6 +71,7 @@ function XeroImportPage({policy}: WithPolicyProps) { policy?.errors?.importCustomers, policy?.errors?.importTaxes, translate, + policyID, ], ); From b459314ef12f41cb633204a383912801e871f087 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 1 May 2024 20:36:01 +0700 Subject: [PATCH 6/8] update to use importCustomers --- src/CONST.ts | 1 + .../import/XeroCustomerConfigurationPage.tsx | 21 +++++++------------ src/types/onyx/Policy.ts | 1 - 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 9d3042b64f80..1f4c4d1ac049 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1267,6 +1267,7 @@ const CONST = { }, XERO_CONFIG: { + IMPORT_CUSTOMERS: 'importCustomers', IMPORT_TAX_RATES: 'importTaxRates', }, diff --git a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx index ad78b0aed85d..45d0a2a4ad1e 100644 --- a/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx +++ b/src/pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage.tsx @@ -17,10 +17,10 @@ function XeroCustomerConfigurationPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const policyID = policy?.id ?? ''; - const {syncCustomers, pendingFields} = policy?.connections?.xero?.config ?? {}; + const {importCustomers, pendingFields} = policy?.connections?.xero?.config ?? {}; + + const isSwitchOn = Boolean(importCustomers); - const isSwitchOn = Boolean(syncCustomers && syncCustomers !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE); - const isReportFieldsSelected = syncCustomers === CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD; return ( {translate('workspace.accounting.import')} - + - Connections.updatePolicyConnectionConfig( - policyID, - CONST.POLICY.CONNECTIONS.NAME.XERO, - CONST.QUICK_BOOKS_CONFIG.SYNC_CUSTOMERS, - isSwitchOn ? CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE : CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, - ) - } + onToggle={() => Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.IMPORT_CUSTOMERS, !importCustomers)} /> {isSwitchOn && ( - + diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 58191c319485..2e4c37d4c082 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -244,7 +244,6 @@ type XeroConnectionConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{ importCustomers: boolean; importTaxRates: boolean; importTrackingCategories: boolean; - syncCustomers: IntegrationEntityMap; isConfigured: boolean; mappings: { customer: string; From a937e6e793a3911e0ced33d909d53157a9b11986 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 1 May 2024 21:07:13 +0700 Subject: [PATCH 7/8] remove unused spacing Co-authored-by: Rushat Gabhane --- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index e72215e50ad1..456e0d7a85fe 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -124,7 +124,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting } return policy?.connections?.xero?.data?.tenants ?? []; }, [policy]); - +please remove as this is unnecessary const currentXeroOrganization = tenants.find((tenant) => tenant.id === policy?.connections?.xero.config.tenantID); const overflowMenu: ThreeDotsMenuProps['menuItems'] = useMemo( From bad19d0aab95c1184a823ed74d9bfcfc6d937146 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 1 May 2024 21:16:07 +0700 Subject: [PATCH 8/8] Update src/pages/workspace/accounting/PolicyAccountingPage.tsx --- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index 456e0d7a85fe..48888c054813 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -124,7 +124,6 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting } return policy?.connections?.xero?.data?.tenants ?? []; }, [policy]); -please remove as this is unnecessary const currentXeroOrganization = tenants.find((tenant) => tenant.id === policy?.connections?.xero.config.tenantID); const overflowMenu: ThreeDotsMenuProps['menuItems'] = useMemo(