From 89f9373ed4ca2dd6c374049c84e866ebfc0da87c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 1 May 2024 16:04:43 +0200 Subject: [PATCH 1/4] create xero utils functions --- src/libs/PolicyUtils.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 0919a93f91bb..4836c42c7302 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -6,7 +6,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, PolicyCategories, PolicyEmployeeList, PolicyTagList, PolicyTags, TaxRate} from '@src/types/onyx'; -import type {PolicyFeatureName, Rate} from '@src/types/onyx/Policy'; +import type {PolicyFeatureName, Rate, Tenant} from '@src/types/onyx/Policy'; import type PolicyEmployee from '@src/types/onyx/PolicyEmployee'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -390,6 +390,20 @@ function canSendInvoice(policies: OnyxCollection): boolean { return getActiveAdminWorkspaces(policies).length > 0; } +/** Get the Xero organizations connected to the policy */ +function getXeroTenants(policy: Policy | undefined): Tenant[] { + // Due to the way optional chain is being handled in this useMemo we are forced to use this approach to properly handle undefined values + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain + if (!policy || !policy.connections || !policy.connections.xero || !policy.connections.xero.data) { + return []; + } + return policy.connections.xero.data.tenants ?? []; +}; + +function findCurrentXeroOrganization(tenants: Tenant[] | undefined, organizationID: string | undefined): Tenant | undefined { + return tenants?.find((tenant) => tenant.id === organizationID); +} + export { getActivePolicies, hasAccountingConnections, @@ -435,6 +449,8 @@ export { getPolicy, getActiveAdminWorkspaces, canSendInvoice, + getXeroTenants, + findCurrentXeroOrganization, }; export type {MemberEmailsToAccountIDs}; From 5f33ba7a453204232b7ff3a9fdcf34188d4a3863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 1 May 2024 16:05:07 +0200 Subject: [PATCH 2/4] use xero utils functions --- .../workspace/accounting/PolicyAccountingPage.tsx | 15 +++++---------- .../workspace/accounting/xero/XeroImportPage.tsx | 4 ++-- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index 48888c054813..8fb3fd57d6e7 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -33,9 +33,10 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, PolicyConnectionSyncProgress} from '@src/types/onyx'; -import type {PolicyConnectionName, Tenant} from '@src/types/onyx/Policy'; +import type {PolicyConnectionName} from '@src/types/onyx/Policy'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; +import { findCurrentXeroOrganization, getXeroTenants } from '@libs/PolicyUtils'; type PolicyAccountingPageOnyxProps = { connectionSyncProgress: OnyxEntry; @@ -116,15 +117,9 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting const policyConnectedToXero = connectedIntegration === CONST.POLICY.CONNECTIONS.NAME.XERO; - const tenants = useMemo(() => { - // Due to the way optional chain is being handled in this useMemo we are forced to use this approach to properly handle undefined values - // eslint-disable-next-line @typescript-eslint/prefer-optional-chain - if (!policy || !policy.connections || !policy.connections.xero || !policy.connections.xero.data) { - return []; - } - return policy?.connections?.xero?.data?.tenants ?? []; - }, [policy]); - const currentXeroOrganization = tenants.find((tenant) => tenant.id === policy?.connections?.xero.config.tenantID); + const tenants = useMemo(() => getXeroTenants(policy), [policy]); + + const currentXeroOrganization = findCurrentXeroOrganization(tenants, 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 af36bfcc42cd..0c842d70c93a 100644 --- a/src/pages/workspace/accounting/xero/XeroImportPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroImportPage.tsx @@ -13,7 +13,7 @@ import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; -import type {Tenant} from '@src/types/onyx/Policy'; +import { getXeroTenants } from '@libs/PolicyUtils'; function XeroImportPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); @@ -22,7 +22,7 @@ function XeroImportPage({policy}: WithPolicyProps) { const policyID = policy?.id ?? ''; const {importCustomers, importTaxRates, importTrackingCategories, pendingFields} = policy?.connections?.xero?.config ?? {}; - const tenants = useMemo(() => policy?.connections?.xero?.data?.tenants ?? [], [policy?.connections?.xero.data.tenants]); + const tenants = useMemo(() => getXeroTenants(policy ?? undefined), [policy]); const currentXeroOrganization = tenants.find((tenant) => tenant.id === policy?.connections?.xero.config.tenantID); const sections = useMemo( From 3943778e9ce275269d35b80fdc58f6058febde61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 1 May 2024 16:05:51 +0200 Subject: [PATCH 3/4] close rhp on select and highlight current xero org chosen --- .../xero/XeroOrganizationConfigurationPage.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx index 3411f524b7d4..98d9f680b32f 100644 --- a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React from 'react'; +import React, { useMemo } from 'react'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; @@ -16,6 +16,9 @@ import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; +import ROUTES from '@src/ROUTES'; +import { findCurrentXeroOrganization, getXeroTenants } from '@libs/PolicyUtils'; +import Navigation from '@libs/Navigation/Navigation'; type XeroOrganizationConfigurationPageProps = WithPolicyProps & StackScreenProps; function XeroOrganizationConfigurationPage({ @@ -26,6 +29,8 @@ function XeroOrganizationConfigurationPage({ }: XeroOrganizationConfigurationPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); + const tenants = useMemo(() => getXeroTenants(policy ?? undefined), [policy]); + const currentXeroOrganization = findCurrentXeroOrganization(tenants, policy?.connections?.xero?.config?.tenantID); const policyID = policy?.id ?? ''; @@ -42,6 +47,7 @@ function XeroOrganizationConfigurationPage({ } updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, 'tenantID', keyForList); + Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING.getRoute(policyID)); }; return ( @@ -62,7 +68,7 @@ function XeroOrganizationConfigurationPage({ ListItem={RadioListItem} onSelectRow={saveSelection} sections={[{data: sections}]} - initiallyFocusedOptionKey={organizationID} + initiallyFocusedOptionKey={currentXeroOrganization?.id} /> From 22d282d4afba66a9557207ca0d4464b8ec9a857e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 1 May 2024 17:02:29 +0200 Subject: [PATCH 4/4] fix style --- src/libs/PolicyUtils.ts | 4 ++-- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 2 +- src/pages/workspace/accounting/xero/XeroImportPage.tsx | 2 +- .../accounting/xero/XeroOrganizationConfigurationPage.tsx | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 4836c42c7302..d24b249df086 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -393,12 +393,12 @@ function canSendInvoice(policies: OnyxCollection): boolean { /** Get the Xero organizations connected to the policy */ function getXeroTenants(policy: Policy | undefined): Tenant[] { // Due to the way optional chain is being handled in this useMemo we are forced to use this approach to properly handle undefined values - // eslint-disable-next-line @typescript-eslint/prefer-optional-chain + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain if (!policy || !policy.connections || !policy.connections.xero || !policy.connections.xero.data) { return []; } return policy.connections.xero.data.tenants ?? []; -}; +} function findCurrentXeroOrganization(tenants: Tenant[] | undefined, organizationID: string | undefined): Tenant | undefined { return tenants?.find((tenant) => tenant.id === organizationID); diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index 8fb3fd57d6e7..aa69b92f86de 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -24,6 +24,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import {removePolicyConnection} from '@libs/actions/connections'; import {syncConnection} from '@libs/actions/connections/QuickBooksOnline'; +import {findCurrentXeroOrganization, getXeroTenants} from '@libs/PolicyUtils'; import Navigation from '@navigation/Navigation'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; @@ -36,7 +37,6 @@ import type {Policy, PolicyConnectionSyncProgress} from '@src/types/onyx'; import type {PolicyConnectionName} from '@src/types/onyx/Policy'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; -import { findCurrentXeroOrganization, getXeroTenants } from '@libs/PolicyUtils'; type PolicyAccountingPageOnyxProps = { connectionSyncProgress: OnyxEntry; diff --git a/src/pages/workspace/accounting/xero/XeroImportPage.tsx b/src/pages/workspace/accounting/xero/XeroImportPage.tsx index 0c842d70c93a..0f2855bdb2c5 100644 --- a/src/pages/workspace/accounting/xero/XeroImportPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroImportPage.tsx @@ -8,12 +8,12 @@ import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; +import {getXeroTenants} from '@libs/PolicyUtils'; 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 ROUTES from '@src/ROUTES'; -import { getXeroTenants } from '@libs/PolicyUtils'; function XeroImportPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); diff --git a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx index 98d9f680b32f..475bbe87e688 100644 --- a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, { useMemo } from 'react'; +import React, {useMemo} from 'react'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; @@ -10,15 +10,15 @@ import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import {updatePolicyConnectionConfig} from '@libs/actions/connections'; +import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; +import {findCurrentXeroOrganization, getXeroTenants} from '@libs/PolicyUtils'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import CONST from '@src/CONST'; -import type SCREENS from '@src/SCREENS'; import ROUTES from '@src/ROUTES'; -import { findCurrentXeroOrganization, getXeroTenants } from '@libs/PolicyUtils'; -import Navigation from '@libs/Navigation/Navigation'; +import type SCREENS from '@src/SCREENS'; type XeroOrganizationConfigurationPageProps = WithPolicyProps & StackScreenProps; function XeroOrganizationConfigurationPage({