Back

0% Statements 0/29
0% Branches 0/8
0% Functions 0/7
0% Lines 0/25

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                                                                                                                                                             
import { useAiFeature } from '@automattic/jetpack-ai-client';
import { useDispatch, useSelect } from '@wordpress/data';
import { useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { VALID_SECTIONS } from '../constants';
import { suggestGuidelines } from '../lib/api';
import { areAllSectionDraftsEmpty, readAllSectionDrafts } from '../lib/drafts';
import { recordGuidelinesEvent } from '../lib/tracks';
import { AI_STORE_NAME } from '../store';
 
/**
 * Hook that returns a callback to generate suggestions for all sections.
 *
 * @return {{ generate: Function, loading: boolean }} Generate callback and loading state.
 */
export default function useGenerateAll() {
	const { createErrorNotice } = useDispatch( noticesStore );
	const { startLoading, stopLoading, setSuggestion, showUpgradeNotice } =
		useDispatch( AI_STORE_NAME );
	const loading = useSelect( select => select( AI_STORE_NAME ).isLoading(), [] );
	const { hasFeature } = useAiFeature();
 
	const generate = useCallback( async () => {
		if ( ! hasFeature ) {
			// No AI plan: surface the upgrade notice instead of generating. The
			// click is a fresh intent signal, so the notice reappears even after
			// a persisted dismissal.
			recordGuidelinesEvent( 'upgrade_notice', { trigger: 'generate_all' } );
			showUpgradeNotice();
			return;
		}
 
		// Snapshot the drafts at click time — they live in the page's DOM
		// textareas, not in a store (see lib/drafts.js).
		const allGuidelines = readAllSectionDrafts();
		const allEmpty = areAllSectionDraftsEmpty();
		recordGuidelinesEvent( 'generate_all', {
			action: allEmpty ? 'generate' : 'improve',
		} );
 
		startLoading();
		try {
			const existingContent = Object.fromEntries(
				VALID_SECTIONS.filter( slug => allGuidelines[ slug ] ).map( slug => [
					slug,
					allGuidelines[ slug ],
				] )
			);
 
			const response = await suggestGuidelines( VALID_SECTIONS, existingContent );
			const suggestions = response?.suggestions || {};
			const appliedSlugs = VALID_SECTIONS.filter( slug => suggestions[ slug ] );
 
			// No usable suggestions came back — surface it like any other failure.
			if ( appliedSlugs.length === 0 ) {
				throw new Error( 'No suggestions returned.' );
			}
 
			appliedSlugs.forEach( slug => setSuggestion( slug, suggestions[ slug ] ) );
		} catch {
			createErrorNotice( __( 'Failed to generate guidelines. Please try again.', 'jetpack' ), {
				type: 'snackbar',
			} );
		} finally {
			stopLoading();
		}
	}, [
		hasFeature,
		startLoading,
		stopLoading,
		setSuggestion,
		showUpgradeNotice,
		createErrorNotice,
	] );
 
	return { generate, loading, hasFeature };
}