From 87669b4700fa61a08f7e9677ef95e3325429f2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20P=C3=A9rez=20Pellicer?= <5908855+puntope@users.noreply.github.com> Date: Thu, 2 Jan 2025 21:34:01 +0100 Subject: [PATCH] Show leaving confirmation in Edit Ads Campaign if the form was modified. --- js/src/pages/edit-paid-ads-campaign/index.js | 46 ++++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/js/src/pages/edit-paid-ads-campaign/index.js b/js/src/pages/edit-paid-ads-campaign/index.js index 7f76203aa3..5990141378 100644 --- a/js/src/pages/edit-paid-ads-campaign/index.js +++ b/js/src/pages/edit-paid-ads-campaign/index.js @@ -4,8 +4,8 @@ import { __, sprintf } from '@wordpress/i18n'; import { Stepper } from '@woocommerce/components'; import { getQuery, getHistory, getNewPath } from '@woocommerce/navigation'; -import { useEffect } from '@wordpress/element'; - +import { useEffect, useState } from '@wordpress/element'; +import { isEqual } from 'lodash'; /** * Internal dependencies */ @@ -14,7 +14,9 @@ import useAdsCampaigns from '~/hooks/useAdsCampaigns'; import useAppSelectDispatch from '~/hooks/useAppSelectDispatch'; import { useAppDispatch } from '~/data'; import { getDashboardUrl } from '~/utils/urls'; -import convertToAssetGroupUpdateBody from '~/components/paid-ads/convertToAssetGroupUpdateBody'; +import convertToAssetGroupUpdateBody, { + diffAssetOperations, +} from '~/components/paid-ads/convertToAssetGroupUpdateBody'; import TopBar from '~/components/stepper/top-bar'; import HelpIconButton from '~/components/help-icon-button'; import CampaignAssetsForm from '~/components/paid-ads/campaign-assets-form'; @@ -34,6 +36,7 @@ import { recordStepContinueEvent, } from '~/utils/tracks'; import useBudgetRecommendation from '~/hooks/useBudgetRecommendation'; +import useNavigateAwayPromptEffect from '~/hooks/useNavigateAwayPromptEffect'; const eventName = 'gla_paid_campaign_step'; const eventContext = 'edit-ads'; @@ -48,6 +51,15 @@ function getCurrentStep() { return STEP.CAMPAIGN; } +function isNotOurStep( location ) { + const allowList = new Set( [ + getNewPath( { step: STEP.CAMPAIGN } ), + getNewPath( { step: STEP.ASSET_GROUP } ), + ] ); + const destination = location.pathname + location.search; + return ! allowList.has( destination ); +} + /** * Renders the campaign editing page. * @@ -56,6 +68,8 @@ function getCurrentStep() { */ const EditPaidAdsCampaign = () => { useLayout( 'full-content' ); + const [ didChange, setDidChange ] = useState( false ); + const [ isSubmit, setIsSubmit ] = useState( false ); const { updateAdsCampaign, @@ -81,6 +95,16 @@ const EditPaidAdsCampaign = () => { }, [ campaign ] ); const step = getCurrentStep(); + + useNavigateAwayPromptEffect( + __( + 'You have unsaved campaign data. Are you sure you want to leave?', + 'google-listings-and-ads' + ), + didChange && ! isSubmit, + isNotOurStep + ); + const setStep = ( nextStep ) => { const url = getNewPath( { ...getQuery(), step: nextStep } ); getHistory().push( url ); @@ -140,10 +164,22 @@ const EditPaidAdsCampaign = () => { setStep( nextStep ); }; + const handleOnChange = ( value, allValues ) => { + const hasChange = + allValues.amount !== campaign.amount || + ! isEqual( + assetEntityGroup.display_url_path, + allValues.display_url_path + ) || + diffAssetOperations( assetEntityGroup, allValues ).length > 0; + + setDidChange( hasChange ); + }; + const handleSubmit = async ( values, enhancer ) => { const { action } = enhancer.submitter.dataset; const { amount } = values; - + setIsSubmit( true ); try { await updateAdsCampaign( campaign.id, { amount } ); @@ -165,6 +201,7 @@ const EditPaidAdsCampaign = () => { invalidateResolvedAssetEntityGroups(); } } catch ( e ) { + setIsSubmit( false ); enhancer.signalFailedSubmission(); return; } @@ -190,6 +227,7 @@ const EditPaidAdsCampaign = () => { recommendedDailyBudget={ highestDailyBudget } assetEntityGroup={ assetEntityGroup } onSubmit={ handleSubmit } + onChange={ handleOnChange } >