Back

0% Statements 0/20
0% Branches 0/20
0% Functions 0/4
0% Lines 0/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121                                                                                                                                                                                                                                                 
import { useGlobalNotices } from '@automattic/jetpack-components';
import { store as modulesStore } from '@automattic/jetpack-shared-stores';
import { FormToggle } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { __, sprintf } from '@wordpress/i18n';
import { useCallback } from 'react';
import { MyJetpackModule } from '../../types';
import { isProductsOnlyMode } from '../../utils/is-products-only-mode';
import { getModuleActivationMessage } from '../../utils/module-benefit-messages';
import { useProductFiltersContext } from '../my-jetpack-tab-panel/products/products-tracking-context';
import type { ChangeEvent } from 'react';
 
export type ModuleToggleProps = {
	module: MyJetpackModule;
	describedby?: string;
};
 
/**
 * Renders a toggle for a Jetpack module.
 *
 * @param {ModuleToggleProps} props - The component props.
 *
 * @return The rendered component.
 */
export function ModuleToggle( { module: $module, describedby }: ModuleToggleProps ) {
	const { updateJetpackModuleStatus: toggleModule } = useDispatch( modulesStore );
	const { createSuccessNotice, createErrorNotice } = useGlobalNotices();
	const { trackProductAction } = useProductFiltersContext() || {};
 
	const isUpdating = useSelect(
		select => select( modulesStore ).isModuleUpdating( $module.module ),
		[ $module.module ]
	);
 
	const showToggleNotice = useCallback(
		async ( {
			noticeType,
			action,
		}: {
			noticeType: 'success' | 'error';
			action: 'activation' | 'deactivation';
		} ) => {
			if ( noticeType === 'success' ) {
				const message =
					action === 'activation'
						? getModuleActivationMessage( $module.module, $module.name )
						: sprintf(
								/* translators: %s is the module name */
								__( '%s has been deactivated.', 'jetpack-my-jetpack' ),
								$module.name
						  );
				createSuccessNotice( message );
			} else {
				const message =
					action === 'activation'
						? sprintf(
								/* translators: %s is the module name */
								__( 'Failed to activate %s.', 'jetpack-my-jetpack' ),
								$module.name
						  )
						: sprintf(
								/* translators: %s is the module name */
								__( 'Failed to deactivate %s.', 'jetpack-my-jetpack' ),
								$module.name
						  );
 
				createErrorNotice( message );
			}
		},
		[ $module.module, $module.name, createErrorNotice, createSuccessNotice ]
	);
 
	const onChange = useCallback(
		async ( event: ChangeEvent< HTMLInputElement > ) => {
			const active = event.target.checked;
 
			// Track module activation/deactivation if we're in the Products tab context
			if ( trackProductAction ) {
				trackProductAction( {
					action: active ? 'activate' : 'deactivate',
					productSlug: $module.module,
					productType: 'module',
					productStatus: $module.activated ? 'active' : 'inactive',
					productData: $module,
				} );
			}
 
			const success = await toggleModule( {
				name: $module.module,
				active,
			} );
 
			await showToggleNotice( {
				noticeType: success ? 'success' : 'error',
				action: active ? 'activation' : 'deactivation',
			} );
		},
		[ toggleModule, $module, showToggleNotice, trackProductAction ]
	);
 
	// In products-only mode the site can't manage modules, so render no toggle at all.
	// Placed after all hooks to respect the rules of hooks.
	if ( isProductsOnlyMode() ) {
		return null;
	}
 
	return (
		<FormToggle
			disabled={ isUpdating }
			checked={ $module.activated }
			onChange={ onChange }
			aria-label={ sprintf(
				/* translators: %s is the module name */
				__( 'Toggle %s module', 'jetpack-my-jetpack' ),
				$module.name
			) }
			aria-describedby={ describedby }
		/>
	);
}