diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index e6ab9a9f1c1c..3d9b586b8b91 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -20,6 +20,9 @@ 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 = { @@ -27,7 +30,7 @@ const OFFSET_X = { 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(); @@ -60,7 +63,7 @@ function Switch({isOn, onToggle, accessibilityLabel, disabled}: SwitchProps) { pressDimmingValue={0.8} > - {disabled && ( + {(Boolean(disabled) || Boolean(showLockIcon)) && ( ; type Item = { @@ -53,6 +62,9 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro const {canUseAccountingIntegrations} = usePermissions(); const hasAccountingConnection = !!policy?.areConnectionsEnabled && !isEmptyObject(policy?.connections); const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config.syncTax || !!policy?.connections?.xero?.config.importTaxRates; + const policyID = policy?.id ?? ''; + + const [connectionWarningModalState, setConnectionWarningModalState] = useState({isOpen: false}); const spendItems: Item[] = [ { @@ -86,6 +98,13 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro disabled: hasAccountingConnection, pendingAction: policy?.pendingFields?.areCategoriesEnabled, action: (isEnabled: boolean) => { + if (hasAccountingConnection) { + setConnectionWarningModalState({ + isOpen: true, + itemType: 'organize', + }); + return; + } Policy.enablePolicyCategories(policy?.id ?? '', isEnabled); }, }, @@ -97,6 +116,13 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro disabled: hasAccountingConnection, pendingAction: policy?.pendingFields?.areTagsEnabled, action: (isEnabled: boolean) => { + if (hasAccountingConnection) { + setConnectionWarningModalState({ + isOpen: true, + itemType: 'organize', + }); + return; + } Policy.enablePolicyTags(policy?.id ?? '', isEnabled); }, }, @@ -108,6 +134,13 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro disabled: hasAccountingConnection, pendingAction: policy?.pendingFields?.tax, action: (isEnabled: boolean) => { + if (hasAccountingConnection) { + setConnectionWarningModalState({ + isOpen: true, + itemType: 'organize', + }); + return; + } Policy.enablePolicyTaxes(policy?.id ?? '', isEnabled); }, }, @@ -121,6 +154,13 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro isActive: !!policy?.areConnectionsEnabled, pendingAction: policy?.pendingFields?.areConnectionsEnabled, action: (isEnabled: boolean) => { + if (hasAccountingConnection) { + setConnectionWarningModalState({ + isOpen: true, + itemType: 'integrate', + }); + return; + } Policy.enablePolicyConnections(policy?.id ?? '', isEnabled); }, disabled: hasAccountingConnection, @@ -165,7 +205,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro isActive={item.isActive} pendingAction={item.pendingAction} onToggle={item.action} - disabled={item.disabled} + showLockIcon={item.disabled} errors={item.errors} onCloseError={item.onCloseError} /> @@ -206,6 +246,17 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro }, [fetchFeatures]), ); + const getConnectionWarningPrompt = useCallback(() => { + switch (connectionWarningModalState.itemType) { + case 'organize': + return translate('workspace.moreFeatures.connectionsWarningModal.featureEnabledText'); + case 'integrate': + return translate('workspace.moreFeatures.connectionsWarningModal.disconnectText'); + default: + return undefined; + } + }, [connectionWarningModalState.itemType, translate]); + return ( {sections.map(renderSection)} + + { + setConnectionWarningModalState({ + isOpen: false, + itemType: undefined, + }); + Navigation.navigate(ROUTES.POLICY_ACCOUNTING.getRoute(policyID)); + }} + onCancel={() => + setConnectionWarningModalState({ + isOpen: false, + itemType: undefined, + }) + } + isVisible={connectionWarningModalState.isOpen} + prompt={getConnectionWarningPrompt()} + confirmText={translate('workspace.moreFeatures.connectionsWarningModal.manageSettings')} + cancelText={translate('common.cancel')} + /> ); diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index d2aea2a2f987..f40f721bf4c6 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -38,6 +38,9 @@ type ToggleSettingOptionRowProps = { onCloseError?: () => void; /** Whether the toggle should be disabled */ disabled?: boolean; + + /** Whether to show the lock icon even if the switch is enabled */ + showLockIcon?: boolean; }; const ICON_SIZE = 48; @@ -56,6 +59,7 @@ function ToggleSettingOptionRow({ errors, onCloseError, disabled = false, + showLockIcon = false, }: ToggleSettingOptionRowProps) { const styles = useThemeStyles(); @@ -93,6 +97,7 @@ function ToggleSettingOptionRow({ onToggle={onToggle} isOn={isActive} disabled={disabled} + showLockIcon={showLockIcon} /> {shouldPlaceSubtitleBelowSwitch && subtitle && subTitleView}