Skip to content

Commit

Permalink
Merge pull request #42340 from Expensify/xero-merge-freeze
Browse files Browse the repository at this point in the history
Merge Xero freeze branch #2
  • Loading branch information
lakchote authored May 30, 2024
2 parents dc17b1b + ef55d3a commit c1acc8e
Show file tree
Hide file tree
Showing 52 changed files with 670 additions and 431 deletions.
6 changes: 4 additions & 2 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1305,12 +1305,13 @@ const CONST = {
SYNC: 'sync',
ENABLE_NEW_CATEGORIES: 'enableNewCategories',
EXPORT: 'export',
TENANT_ID: 'tenantID',
IMPORT_CUSTOMERS: 'importCustomers',
IMPORT_TAX_RATES: 'importTaxRates',
INVOICE_STATUS: {
AWAITING_PAYMENT: 'AWT_PAYMENT',
DRAFT: 'DRAFT',
AWAITING_APPROVAL: 'AWT_APPROVAL',
AWAITING_PAYMENT: 'AWT_PAYMENT',
},
IMPORT_TRACKING_CATEGORIES: 'importTrackingCategories',
MAPPINGS: 'mappings',
Expand Down Expand Up @@ -1778,7 +1779,8 @@ const CONST = {
XERO: 'xero',
},
SYNC_STAGE_NAME: {
STARTING_IMPORT: 'startingImport',
STARTING_IMPORT_QBO: 'startingImportQBO',
STARTING_IMPORT_XERO: 'startingImportXero',
QBO_IMPORT_MAIN: 'quickbooksOnlineImportMain',
QBO_IMPORT_CUSTOMERS: 'quickbooksOnlineImportCustomers',
QBO_IMPORT_EMPLOYEES: 'quickbooksOnlineImportEmployees',
Expand Down
31 changes: 16 additions & 15 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -689,12 +689,12 @@ const ROUTES = {
getRoute: (policyID: string, orderWeight: number) => `settings/workspaces/${policyID}/tags/${orderWeight}/edit` as const,
},
WORKSPACE_TAG_EDIT: {
route: 'settings/workspace/:policyID/tag/:tagName/edit',
getRoute: (policyID: string, tagName: string) => `settings/workspace/${policyID}/tag/${encodeURIComponent(tagName)}/edit` as const,
route: 'settings/workspaces/:policyID/tag/:orderWeight/:tagName/edit',
getRoute: (policyID: string, orderWeight: number, tagName: string) => `settings/workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}/edit` as const,
},
WORKSPACE_TAG_SETTINGS: {
route: 'settings/workspaces/:policyID/tag/:tagName',
getRoute: (policyID: string, tagName: string) => `settings/workspaces/${policyID}/tag/${encodeURIComponent(tagName)}` as const,
route: 'settings/workspaces/:policyID/tag/:orderWeight/:tagName',
getRoute: (policyID: string, orderWeight: number, tagName: string) => `settings/workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}` as const,
},
WORKSPACE_TAG_LIST_VIEW: {
route: 'settings/workspaces/:policyID/tag-list/:orderWeight',
Expand Down Expand Up @@ -812,17 +812,14 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/accounting/xero/import/tracking-categories',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories` as const,
},
POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP_COST_CENTERS: {
route: 'settings/workspaces/:policyID/accounting/xero/import/tracking-categories/cost-centers',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories/cost-centers` as const,
},
POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP_REGION: {
route: 'settings/workspaces/:policyID/accounting/xero/import/tracking-categories/region',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/tracking-categories/region` as const,
POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP: {
route: 'settings/workspaces/:policyID/accounting/xero/import/tracking-categories/mapping/:categoryId/:categoryName',
getRoute: (policyID: string, categoryId: string, categoryName: string) =>
`settings/workspaces/${policyID}/accounting/xero/import/tracking-categories/mapping/${categoryId}/${encodeURIComponent(categoryName)}` as const,
},
POLICY_ACCOUNTING_XERO_CUSTOMER: {
route: '/settings/workspaces/:policyID/accounting/xero/import/customers',
getRoute: (policyID: string) => `/settings/workspaces/${policyID}/accounting/xero/import/customers` as const,
route: 'settings/workspaces/:policyID/accounting/xero/import/customers',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/customers` as const,
},
POLICY_ACCOUNTING_XERO_TAXES: {
route: 'settings/workspaces/:policyID/accounting/xero/import/taxes',
Expand All @@ -833,8 +830,8 @@ const ROUTES = {
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/export` as const,
},
POLICY_ACCOUNTING_XERO_PREFERRED_EXPORTER_SELECT: {
route: '/settings/workspaces/:policyID/connections/xero/export/preferred-exporter/select',
getRoute: (policyID: string) => `/settings/workspaces/${policyID}/connections/xero/export/preferred-exporter/select` as const,
route: 'settings/workspaces/:policyID/connections/xero/export/preferred-exporter/select',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/xero/export/preferred-exporter/select` as const,
},
POLICY_ACCOUNTING_XERO_EXPORT_PURCHASE_BILL_DATE_SELECT: {
route: 'settings/workspaces/:policyID/accounting/xero/export/purchase-bill-date-select',
Expand All @@ -848,6 +845,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/accounting/xero/advanced',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/advanced` as const,
},
POLICY_ACCOUNTING_XERO_BILL_STATUS_SELECTOR: {
route: 'settings/workspaces/:policyID/accounting/xero/export/purchase-bill-status-selector',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/export/purchase-bill-status-selector` as const,
},
POLICY_ACCOUNTING_XERO_INVOICE_SELECTOR: {
route: 'settings/workspaces/:policyID/accounting/xero/advanced/invoice-account-selector',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/advanced/invoice-account-selector` as const,
Expand Down
4 changes: 2 additions & 2 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,11 @@ const SCREENS = {
XERO_CUSTOMER: 'Policy_Acounting_Xero_Import_Customer',
XERO_TAXES: 'Policy_Accounting_Xero_Taxes',
XERO_TRACKING_CATEGORIES: 'Policy_Accounting_Xero_Tracking_Categories',
XERO_MAP_COST_CENTERS: 'Policy_Accounting_Xero_Map_Cost_Centers',
XERO_MAP_REGION: 'Policy_Accounting_Xero_Map_Region',
XERO_MAP_TRACKING_CATEGORY: 'Policy_Accounting_Xero_Map_Tracking_Category',
XERO_EXPORT: 'Policy_Accounting_Xero_Export',
XERO_EXPORT_PURCHASE_BILL_DATE_SELECT: 'Policy_Accounting_Xero_Export_Purchase_Bill_Date_Select',
XERO_ADVANCED: 'Policy_Accounting_Xero_Advanced',
XERO_BILL_STATUS_SELECTOR: 'Policy_Accounting_Xero_Export_Bill_Status_Selector',
XERO_INVOICE_ACCOUNT_SELECTOR: 'Policy_Accounting_Xero_Invoice_Account_Selector',
XERO_EXPORT_PREFERRED_EXPORTER_SELECT: 'Workspace_Accounting_Xero_Export_Preferred_Exporter_Select',
XERO_BILL_PAYMENT_ACCOUNT_SELECTOR: 'Policy_Accounting_Xero_Bill_Payment_Account_Selector',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import {removePolicyConnection} from '@libs/actions/connections';
import {getQuickBooksOnlineSetupLink} from '@libs/actions/connections/QuickBooksOnline';
import getQuickBooksOnlineSetupLink from '@libs/actions/connections/QuickBooksOnline';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Session} from '@src/types/onyx';
Expand Down
5 changes: 4 additions & 1 deletion src/components/ConnectToQuickbooksOnlineButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import {removePolicyConnection} from '@libs/actions/connections';
import {getQuickBooksOnlineSetupLink} from '@libs/actions/connections/QuickBooksOnline';
import getQuickBooksOnlineSetupLink from '@libs/actions/connections/QuickBooksOnline';
import * as Link from '@userActions/Link';
import * as PolicyAction from '@userActions/Policy/Policy';
import CONST from '@src/CONST';
import type {ConnectToQuickbooksOnlineButtonProps} from './types';

Expand All @@ -27,6 +28,8 @@ function ConnectToQuickbooksOnlineButton({policyID, shouldDisconnectIntegrationB
setIsDisconnectModalOpen(true);
return;
}
// Since QBO doesn't support Taxes, we should disable them from the LHN when connecting to QBO
PolicyAction.enablePolicyTaxes(policyID, false);
Link.openLink(getQuickBooksOnlineSetupLink(policyID), environmentURL);
}}
isDisabled={isOffline}
Expand Down
43 changes: 33 additions & 10 deletions src/components/ConnectionLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {isEmpty} from 'lodash';
import React, {useMemo} from 'react';
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
import type {AccessVariant} from '@pages/workspace/AccessOrNotFoundWrapper';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import type {TranslationPaths} from '@src/languages/types';
import type {PolicyFeatureName} from '@src/types/onyx/Policy';
import type {ConnectionName, PolicyFeatureName} from '@src/types/onyx/Policy';
import HeaderWithBackButton from './HeaderWithBackButton';
import ScreenWrapper from './ScreenWrapper';
import ScrollView from './ScrollView';
Expand All @@ -17,16 +19,16 @@ type ConnectionLayoutProps = {
/** Used to set the testID for tests */
displayName: string;

/** Header title for the connection */
headerTitle: TranslationPaths;
/** Header title to be translated for the connection component */
headerTitle?: TranslationPaths;

/** The subtitle to show in the header */
headerSubtitle?: string;

/** React nodes that will be shown */
children?: React.ReactNode;

/** Title of the connection component */
/** Title to be translated for the connection component */
title?: TranslationPaths;

/** The current policyID */
Expand All @@ -44,18 +46,30 @@ type ConnectionLayoutProps = {
/** Style of the title text */
titleStyle?: StyleProp<TextStyle> | undefined;

/** Whether to include safe area padding bottom or not */
shouldIncludeSafeAreaPaddingBottom?: boolean;

/** Whether to use ScrollView or not */
shouldUseScrollView?: boolean;

/** Used for dynamic header title translation with parameters */
headerTitleAlreadyTranslated?: string;

/** Used for dynamic title translation with parameters */
titleAlreadyTranslated?: string;

/** Name of the current connection */
connectionName: ConnectionName;
};

type ConnectionLayoutContentProps = Pick<ConnectionLayoutProps, 'title' | 'titleStyle' | 'children'>;
type ConnectionLayoutContentProps = Pick<ConnectionLayoutProps, 'title' | 'titleStyle' | 'children' | 'titleAlreadyTranslated'>;

function ConnectionLayoutContent({title, titleStyle, children}: ConnectionLayoutContentProps) {
function ConnectionLayoutContent({title, titleStyle, children, titleAlreadyTranslated}: ConnectionLayoutContentProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
return (
<>
{title && <Text style={[styles.pb5, titleStyle]}>{translate(title)}</Text>}
{title && <Text style={[styles.pb5, titleStyle]}>{titleAlreadyTranslated ?? translate(title)}</Text>}
{children}
</>
);
Expand All @@ -72,35 +86,44 @@ function ConnectionLayout({
featureName,
contentContainerStyle,
titleStyle,
shouldIncludeSafeAreaPaddingBottom,
connectionName,
shouldUseScrollView = true,
headerTitleAlreadyTranslated,
titleAlreadyTranslated,
}: ConnectionLayoutProps) {
const {translate} = useLocalize();

const policy = PolicyUtils.getPolicy(policyID ?? '');
const isConnectionEmpty = isEmpty(policy.connections?.[connectionName]);

const renderSelectionContent = useMemo(
() => (
<ConnectionLayoutContent
title={title}
titleStyle={titleStyle}
titleAlreadyTranslated={titleAlreadyTranslated}
>
{children}
</ConnectionLayoutContent>
),
[title, titleStyle, children],
[title, titleStyle, children, titleAlreadyTranslated],
);

return (
<AccessOrNotFoundWrapper
policyID={policyID}
accessVariants={accessVariants}
featureName={featureName}
shouldBeBlocked={isConnectionEmpty}
>
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
includeSafeAreaPaddingBottom={!!shouldIncludeSafeAreaPaddingBottom}
shouldEnableMaxHeight
testID={displayName}
>
<HeaderWithBackButton
title={translate(headerTitle)}
title={headerTitleAlreadyTranslated ?? (headerTitle ? translate(headerTitle as TranslationPaths) : '')}
subtitle={headerSubtitle}
onBackButtonPress={() => Navigation.goBack()}
/>
Expand Down
12 changes: 10 additions & 2 deletions src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,15 @@ type MenuItemBaseProps = {
/** Error to display at the bottom of the component */
errorText?: MaybePhraseKey;

/** Any additional styles to pass to error text. */
errorTextStyle?: StyleProp<ViewStyle>;

/** Hint to display at the bottom of the component */
hintText?: MaybePhraseKey;

/** Should the error text red dot indicator be shown */
shouldShowRedDotIndicator?: boolean;

/** A boolean flag that gives the icon a green fill if true */
success?: boolean;

Expand Down Expand Up @@ -308,6 +314,8 @@ function MenuItem(
helperText,
helperTextStyle,
errorText,
errorTextStyle,
shouldShowRedDotIndicator,
hintText,
success = false,
focused = false,
Expand Down Expand Up @@ -684,9 +692,9 @@ function MenuItem(
{!!errorText && (
<FormHelpMessage
isError
shouldShowRedDotIndicator={false}
shouldShowRedDotIndicator={!!shouldShowRedDotIndicator}
message={errorText}
style={styles.menuItemError}
style={[styles.menuItemError, errorTextStyle]}
/>
)}
{!!hintText && (
Expand Down
14 changes: 12 additions & 2 deletions src/components/SelectionScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {isEmpty} from 'lodash';
import React from 'react';
import useLocalize from '@hooks/useLocalize';
import * as PolicyUtils from '@libs/PolicyUtils';
import type {AccessVariant} from '@pages/workspace/AccessOrNotFoundWrapper';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import type {TranslationPaths} from '@src/languages/types';
import type {PolicyFeatureName} from '@src/types/onyx/Policy';
import type {ConnectionName, PolicyFeatureName} from '@src/types/onyx/Policy';
import HeaderWithBackButton from './HeaderWithBackButton';
import ScreenWrapper from './ScreenWrapper';
import SelectionList from './SelectionList';
Expand Down Expand Up @@ -52,6 +54,9 @@ type SelectionScreenProps = {

/** Whether or not to block user from accessing the page */
shouldBeBlocked?: boolean;

/** Name of the current connection */
connectionName: ConnectionName;
};

function SelectionScreen({
Expand All @@ -67,14 +72,19 @@ function SelectionScreen({
accessVariants,
featureName,
shouldBeBlocked,
connectionName,
}: SelectionScreenProps) {
const {translate} = useLocalize();

const policy = PolicyUtils.getPolicy(policyID ?? '');
const isConnectionEmpty = isEmpty(policy.connections?.[connectionName]);

return (
<AccessOrNotFoundWrapper
policyID={policyID}
accessVariants={accessVariants}
featureName={featureName}
shouldBeBlocked={shouldBeBlocked}
shouldBeBlocked={isConnectionEmpty || shouldBeBlocked}
>
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
Expand Down
7 changes: 5 additions & 2 deletions src/components/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ type SwitchProps = {

/** Whether the switch is disabled */
disabled?: boolean;

/** Whether to show the lock icon even if the switch is enabled */
showLockIcon?: boolean;
};

const OFFSET_X = {
OFF: 0,
ON: 20,
};

function Switch({isOn, onToggle, accessibilityLabel, disabled}: SwitchProps) {
function Switch({isOn, onToggle, accessibilityLabel, disabled, showLockIcon}: SwitchProps) {
const styles = useThemeStyles();
const offsetX = useRef(new Animated.Value(isOn ? OFFSET_X.ON : OFFSET_X.OFF));
const theme = useTheme();
Expand Down Expand Up @@ -60,7 +63,7 @@ function Switch({isOn, onToggle, accessibilityLabel, disabled}: SwitchProps) {
pressDimmingValue={0.8}
>
<Animated.View style={[styles.switchThumb, styles.switchThumbTransformation(offsetX.current)]}>
{disabled && (
{(Boolean(disabled) || Boolean(showLockIcon)) && (
<Icon
src={Expensicons.Lock}
fill={isOn ? theme.text : theme.icon}
Expand Down
Loading

0 comments on commit c1acc8e

Please sign in to comment.