Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add error message in case of integration sync failure #42307

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 @@ -683,9 +691,9 @@ function MenuItem(
{!!errorText && (
<FormHelpMessage
isError
shouldShowRedDotIndicator={false}
shouldShowRedDotIndicator={!!shouldShowRedDotIndicator}
message={errorText}
style={styles.menuItemError}
style={[styles.menuItemError, errorTextStyle]}
/>
)}
{!!hintText && (
Expand Down
11 changes: 11 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2341,6 +2341,17 @@ export default {
}
}
},
syncError: (integration?: ConnectionName): string => {
switch (integration) {
case CONST.POLICY.CONNECTIONS.NAME.QBO:
return "Couldn't connect to QuickBooks Online.";
case CONST.POLICY.CONNECTIONS.NAME.XERO:
return "Couldn't connect to Xero.";
default: {
return "Couldn't connect to integration.";
}
}
},
accounts: 'Chart of accounts',
taxes: 'Taxes',
imported: 'Imported',
Expand Down
11 changes: 11 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2345,6 +2345,17 @@ export default {
}
}
},
syncError: (integration?: ConnectionName): string => {
switch (integration) {
case CONST.POLICY.CONNECTIONS.NAME.QBO:
return 'No se puede conectar a QuickBooks Online.';
case CONST.POLICY.CONNECTIONS.NAME.XERO:
return 'No se puede conectar a Xero';
default: {
return 'No se ha podido conectar a la integración.';
}
}
},
accounts: 'Plan de cuentas',
taxes: 'Impuestos',
imported: 'Importado',
Expand Down
9 changes: 7 additions & 2 deletions src/libs/actions/connections/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {OnyxUpdate} from 'react-native-onyx';
import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
import type {
Expand All @@ -13,6 +13,7 @@ import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {ConnectionName, Connections, PolicyConnectionName} from '@src/types/onyx/Policy';
import type Policy from '@src/types/onyx/Policy';

function removePolicyConnection(policyID: string, connectionName: PolicyConnectionName) {
const optimisticData: OnyxUpdate[] = [
Expand Down Expand Up @@ -231,4 +232,8 @@ function updateManyPolicyConnectionConfigs<TConnectionName extends ConnectionNam
API.write(WRITE_COMMANDS.UPDATE_MANY_POLICY_CONNECTION_CONFIGS, parameters, {optimisticData, failureData, successData});
}

export {removePolicyConnection, updatePolicyConnectionConfig, updateManyPolicyConnectionConfigs, syncConnection};
function hasSynchronizationError(policy: OnyxEntry<Policy>, connectionName: PolicyConnectionName): boolean {
return policy?.connections?.[connectionName]?.lastSync?.isSuccessful === false;
}

export {removePolicyConnection, updatePolicyConnectionConfig, updateManyPolicyConnectionConfigs, hasSynchronizationError, syncConnection};
39 changes: 23 additions & 16 deletions src/pages/workspace/accounting/PolicyAccountingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import usePermissions from '@hooks/usePermissions';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import {removePolicyConnection, syncConnection} from '@libs/actions/connections';
import {hasSynchronizationError, removePolicyConnection, syncConnection} from '@libs/actions/connections';
import {findCurrentXeroOrganization, getCurrentXeroOrganizationName, getXeroTenants} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
Expand All @@ -41,7 +41,7 @@ import type {PolicyConnectionName} from '@src/types/onyx/Policy';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type IconAsset from '@src/types/utils/IconAsset';

type MenuItemData = MenuItemProps & {pendingAction?: OfflineWithFeedbackProps['pendingAction']};
type MenuItemData = MenuItemProps & {pendingAction?: OfflineWithFeedbackProps['pendingAction']; errors?: OfflineWithFeedbackProps['errors']};

type PolicyAccountingPageOnyxProps = {
connectionSyncProgress: OnyxEntry<PolicyConnectionSyncProgress>;
Expand Down Expand Up @@ -163,16 +163,19 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
if (!connectedIntegration) {
return [];
}
const shouldShowSynchronizationError = hasSynchronizationError(policy, connectedIntegration);
const integrationData = accountingIntegrationData(connectedIntegration, policyID, translate);
const iconProps = integrationData?.icon ? {icon: integrationData.icon, iconType: CONST.ICON_TYPE_AVATAR} : {};
return [
{
...iconProps,
interactive: false,
wrapperStyle: [styles.sectionMenuItemTopDescription],
wrapperStyle: [styles.sectionMenuItemTopDescription, shouldShowSynchronizationError && styles.pb0],
shouldShowRightComponent: true,
title: integrationData?.title,

errorText: shouldShowSynchronizationError ? translate('workspace.accounting.syncError', connectedIntegration) : undefined,
errorTextStyle: [styles.mt5],
shouldShowRedDotIndicator: true,
description: isSyncInProgress
? translate('workspace.accounting.connections.syncStageName', connectionSyncProgress.stageInProgress)
: translate('workspace.accounting.lastSync'),
Expand All @@ -199,7 +202,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
</View>
),
},
...(policyConnectedToXero
...(policyConnectedToXero && !shouldShowSynchronizationError
? [
{
description: translate('workspace.xero.organization'),
Expand All @@ -220,7 +223,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
},
]
: []),
...(isEmptyObject(policy?.connections)
...(isEmptyObject(policy?.connections) || shouldShowSynchronizationError
? []
: [
{
Expand Down Expand Up @@ -250,21 +253,25 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
]),
];
}, [
connectedIntegration,
connectionSyncProgress?.stageInProgress,
currentXeroOrganization,
currentXeroOrganizationName,
tenants,
policy,
isSyncInProgress,
overflowMenu,
policy?.connections,
policyConnectedToXero,
connectedIntegration,
policyID,
styles,
translate,
styles.sectionMenuItemTopDescription,
styles.pb0,
styles.mt5,
styles.popoverMenuIcon,
styles.fontWeightNormal,
connectionSyncProgress?.stageInProgress,
theme.spinner,
overflowMenu,
threeDotsMenuPosition,
translate,
policyConnectedToXero,
currentXeroOrganizationName,
tenants.length,
accountingIntegrations,
currentXeroOrganization?.id,
]);

const otherIntegrationsItems = useMemo(() => {
Expand Down
Loading