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

Enhancement/9344 acrsubtlenotification component #9547

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
86 changes: 86 additions & 0 deletions assets/js/components/KeyMetrics/ACRSubtleNotification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* ACRSubtleNotification component.
*
* Site Kit by Google, Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState, useCallback } from '@wordpress/element';

/**
* Internal dependencies
*/
import { useSelect, useDispatch } from 'googlesitekit-data';
import { Button, SpinnerButton } from 'googlesitekit-components';
import StarFill from '../../../svg/icons/star-fill.svg';
import SubtleNotification from '../../googlesitekit/notifications/components/layout/SubtleNotification';
import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { ACR_SUBTLE_NOTIFICATION_SLUG } from './constants';
import { CORE_SITE } from '../../googlesitekit/datastore/site/constants';

export default function ACRSubtleNotification() {
const [ isNavigating, setIsNavigating ] = useState( false );

const { dismissItem } = useDispatch( CORE_USER );

const isDismissed = useSelect( ( select ) =>
select( CORE_USER ).isItemDismissed( ACR_SUBTLE_NOTIFICATION_SLUG )
);

const onDismiss = useCallback( async () => {
await dismissItem( ACR_SUBTLE_NOTIFICATION_SLUG );
}, [ dismissItem ] );

const userInputURL = useSelect( ( select ) =>
select( CORE_SITE ).getAdminURL( 'googlesitekit-user-input' )
);

const handleCTAClick = useCallback( () => {
setIsNavigating( true );
}, [ setIsNavigating ] );

if ( isDismissed ) {
return null;
}

return (
<SubtleNotification
className="googlesitekit-acr-subtle-notification"
title={ __( 'Personalize your metrics', 'google-site-kit' ) }
description={ __(
'Set up your goals by answering 3 quick questions to help us show the most relevant data for your site',
'google-site-kit'
) }
dismissCTA={
<Button tertiary onClick={ onDismiss }>
{ __( 'Maybe later', 'google-site-kit' ) }
</Button>
}
additionalCTA={
<SpinnerButton
onClick={ handleCTAClick }
href={ userInputURL }
isSaving={ isNavigating }
>
{ __( 'Get tailored metrics', 'google-site-kit' ) }
</SpinnerButton>
}
icon={ <StarFill width={ 24 } height={ 24 } /> }
/>
);
}
84 changes: 84 additions & 0 deletions assets/js/components/KeyMetrics/ACRSubtleNotification.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Key Metrics ACRSubtleNotification component tests.
*
* Site Kit by Google, Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {
act,
createTestRegistry,
fireEvent,
provideSiteInfo,
render,
} from '../../../../tests/js/test-utils';
import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
import ACRSubtleNotification from './ACRSubtleNotification';
import { ACR_SUBTLE_NOTIFICATION_SLUG } from './constants';

describe( 'ACRSubtleNotification', () => {
let registry;

beforeEach( () => {
registry = createTestRegistry();
registry.dispatch( CORE_USER ).receiveGetDismissedItems( [] );
provideSiteInfo( registry );
} );

it( 'should render "Get tailored metrics" CTA', async () => {
const { queryByText, getByRole, waitForRegistry } = render(
<ACRSubtleNotification />,
{
registry,
}
);

await waitForRegistry();

expect( queryByText( /get tailored metrics/i ) ).toBeInTheDocument();
const button = getByRole( 'button', { name: /get tailored metrics/i } );

expect( button ).toHaveAttribute(
'href',
'http://example.com/wp-admin/admin.php?page=googlesitekit-user-input'
);
} );

it( 'should render "Maybe later" CTA', () => {
const { queryByText } = render( <ACRSubtleNotification />, {
registry,
} );

expect( queryByText( /maybe later/i ) ).toBeInTheDocument();
} );

it( 'does not render when dismissed', async () => {
fetchMock.postOnce(
RegExp( '^/google-site-kit/v1/core/user/data/dismiss-item' ),
{
body: JSON.stringify( [ ACR_SUBTLE_NOTIFICATION_SLUG ] ),
status: 200,
}
);

const { getByRole } = render( <ACRSubtleNotification />, {
registry,
} );

// eslint-disable-next-line require-await
await act( async () => {
fireEvent.click( getByRole( 'button', { name: 'Maybe later' } ) );
} );
} );
} );
3 changes: 3 additions & 0 deletions assets/js/components/KeyMetrics/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
*/

export const KEY_METRICS_SETUP_CTA_WIDGET_SLUG = 'key-metrics-setup-cta-widget';
export const ACR_SUBTLE_NOTIFICATION_SLUG =
'key-metrics-acr-subtle-notification';

export const KEY_METRICS_SELECTION_PANEL_OPENED_KEY =
'googlesitekit-key-metrics-selection-panel-opened';
export const KEY_METRICS_SELECTION_FORM = 'key-metrics-selection-form';
Expand Down
108 changes: 65 additions & 43 deletions assets/js/components/settings/SettingsCardKeyMetrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import { __ } from '@wordpress/i18n';
import { useSelect } from 'googlesitekit-data';
import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { CORE_SITE } from '../../googlesitekit/datastore/site/constants';
import { ACR_SUBTLE_NOTIFICATION_SLUG } from '../KeyMetrics/constants';
import { WEEK_IN_SECONDS, trackEvent } from '../../util';
import useViewContext from '../../hooks/useViewContext';
import { useInView } from '../../hooks/useInView';
import ACRSubtleNotification from '../KeyMetrics/ACRSubtleNotification';
import SettingsKeyMetrics from './SettingsKeyMetrics';
import UserInputPreview from '../user-input/UserInputPreview';
import Layout from '../layout/Layout';
Expand All @@ -39,10 +39,14 @@ import Link from '../Link';
import LoadingWrapper from '../LoadingWrapper';
import SurveyViewTrigger from '../surveys/SurveyViewTrigger';
import PreviewBlock from '../PreviewBlock';
import { useInView } from '../../hooks/useInView';
import { useFeature } from '../../hooks/useFeature';
import useViewContext from '../../hooks/useViewContext';

export default function SettingsCardKeyMetrics() {
const viewContext = useViewContext();
const inView = useInView();
const conversionReportingEnabled = useFeature( 'conversionReporting' );

const isUserInputCompleted = useSelect( ( select ) =>
select( CORE_USER ).isUserInputCompleted()
Expand All @@ -61,6 +65,12 @@ export default function SettingsCardKeyMetrics() {
const hasUserPickedMetrics = useSelect( ( select ) =>
select( CORE_USER ).getUserPickedMetrics()
);
const isACRNotificationDismissed = useSelect( ( select ) =>
select( CORE_USER ).isItemDismissed( ACR_SUBTLE_NOTIFICATION_SLUG )
);
const showACRNotification =
conversionReportingEnabled && ! isACRNotificationDismissed;

const isUserInputCompletedLoading = useSelect(
( select ) =>
! select( CORE_USER ).hasFinishedResolution(
Expand Down Expand Up @@ -115,53 +125,65 @@ export default function SettingsCardKeyMetrics() {
{ isUserInputCompleted === false && (
<Fragment>
<SettingsKeyMetrics />

<Grid>
<Row>
<Cell
className="googlesitekit-user-input__notification googlesitekit-overflow-hidden"
size={ 12 }
>
<LoadingWrapper
loading={
isGetUserInputSettingsLoading
}
className="googlesitekit-user-input__notification-text-loading"
width="500px"
height="20.5px"
smallWidth="500px"
smallHeight="41px"
>
<p>
<span>
{ __(
'Answer 3 quick questions to help us show the most relevant data for your site',
'google-site-kit'
) }
</span>
</p>
</LoadingWrapper>

<LoadingWrapper
loading={
isGetUserInputSettingsLoading
}
width="200px"
height="20.5px"
>
<Link href={ userInputURL }>
{ ctaLabel }
</Link>
</LoadingWrapper>
</Cell>
{ showACRNotification && (
<Fragment>
<ACRSubtleNotification />
{ inView && (
<SurveyViewTrigger
triggerID="view_kmw_setup_cta"
ttl={ WEEK_IN_SECONDS }
/>
) }
</Row>
</Grid>
</Fragment>
) }
{ ! showACRNotification && (
<Grid>
<Row>
<Cell
className="googlesitekit-user-input__notification googlesitekit-overflow-hidden"
size={ 12 }
>
<LoadingWrapper
loading={
isGetUserInputSettingsLoading
}
className="googlesitekit-user-input__notification-text-loading"
width="500px"
height="20.5px"
smallWidth="500px"
smallHeight="41px"
>
<p>
<span>
{ __(
'Answer 3 quick questions to help us show the most relevant data for your site',
'google-site-kit'
) }
</span>
</p>
</LoadingWrapper>

<LoadingWrapper
loading={
isGetUserInputSettingsLoading
}
width="200px"
height="20.5px"
>
<Link href={ userInputURL }>
{ ctaLabel }
</Link>
</LoadingWrapper>
</Cell>
{ inView && (
<SurveyViewTrigger
triggerID="view_kmw_setup_cta"
ttl={ WEEK_IN_SECONDS }
/>
) }
</Row>
</Grid>
) }
</Fragment>
) }
</div>
Expand Down
Loading
Loading