Skip to content

Commit

Permalink
Merge pull request google#10011 from google/issue/9291-refactor-web-d…
Browse files Browse the repository at this point in the history
…ata-stream-not-available-notification-use-notification-api

Issue / 9291 Refactor Web Data Stream Not Available Notification Use Notification API
  • Loading branch information
tofumatt authored Jan 23, 2025
2 parents 9cd506e + 7315849 commit c33c9ba
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 82 deletions.
2 changes: 0 additions & 2 deletions assets/js/components/notifications/BannerNotifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import EnhancedMeasurementActivationBanner from '../../modules/analytics-4/compo
import useViewOnly from '../../hooks/useViewOnly';
import EnableAutoUpdateBannerNotification from './EnableAutoUpdateBannerNotification';
import GoogleTagIDMismatchNotification from './GoogleTagIDMismatchNotification';
import WebDataStreamNotAvailableNotification from './WebDataStreamNotAvailableNotification';
import AdBlockingRecoverySetupSuccessBannerNotification from './AdBlockingRecoverySetupSuccessBannerNotification';
import { CORE_UI } from '../../googlesitekit/datastore/ui/constants';
import { UI_KEY_KEY_METRICS_SETUP_CTA_RENDERED } from '../KeyMetrics/KeyMetricsSetupCTARenderedEffect';
Expand Down Expand Up @@ -129,7 +128,6 @@ export default function BannerNotifications() {
{ hasMismatchedGoogleTagID && (
<GoogleTagIDMismatchNotification />
) }
<WebDataStreamNotAvailableNotification />
</Fragment>
) }
<Notifications areaSlug={ NOTIFICATION_AREAS.BANNERS_ABOVE_NAV } />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,21 @@ import { __, sprintf } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import { ProgressBar } from 'googlesitekit-components';
import { useSelect } from 'googlesitekit-data';
import BannerNotification from './BannerNotification';
import SimpleNotification from '../../googlesitekit/notifications/components/layout/SimpleNotification';
import { MODULES_ANALYTICS_4 } from '../../modules/analytics-4/datastore/constants';
import { CORE_SITE } from '../../googlesitekit/datastore/site/constants';
import { MINUTE_IN_SECONDS } from '../../util';
import { Cell, Grid, Row } from '../../material-components';
import Description from '../../googlesitekit/notifications/components/common/Description';
import ActionsCTALinkDismiss from '../../googlesitekit/notifications/components/common/ActionsCTALinkDismiss';

export default function WebDataStreamNotAvailableNotification() {
const isWebDataStreamAvailable = useSelect( ( select ) =>
select( MODULES_ANALYTICS_4 ).isWebDataStreamAvailable()
);
export const WEB_DATA_STREAM_NOT_AVAILABLE_NOTIFICATION =
'web-data-stream-not-available-notification';

export default function WebDataStreamNotAvailableNotification( {
id,
Notification,
} ) {
const measurementID = useSelect( ( select ) =>
select( MODULES_ANALYTICS_4 ).getMeasurementID()
);
Expand All @@ -45,48 +47,38 @@ export default function WebDataStreamNotAvailableNotification() {
select( CORE_SITE ).getAdminURL( 'googlesitekit-settings' )
);

// If the data stream is available, we don't have to show a warning to the user.
if ( isWebDataStreamAvailable ) {
return null;
}

if ( measurementID === undefined ) {
// Wrap in the googlesitekit-publisher-win class to ensure the output is treated in the same way as BannerNotification,
// with only one instance visible on the screen at a time.
return (
<div className="googlesitekit-publisher-win">
<Grid>
<Row>
<Cell size={ 12 }>
<ProgressBar />
</Cell>
</Row>
</Grid>
</div>
);
}

return (
<BannerNotification
id="web-data-stream-not-available"
title={ __(
'Your Analytics configuration has changed',
'google-site-kit'
) }
description={ sprintf(
/* translators: 1: Google Analytics Measurement ID. */
__(
'The previously selected web data stream with measurement ID %1$s is no longer available. Please select a new web data stream to continue collecting data with Google Analytics.',
<Notification className="googlesitekit-publisher-win googlesitekit-publisher-win--win-error">
<SimpleNotification
title={ __(
'Your Analytics configuration has changed',
'google-site-kit'
),
measurementID
) }
ctaLink={ `${ settingsURL }#connected-services/analytics-4/edit` }
ctaLabel={ __( 'Update Analytics settings', 'google-site-kit' ) }
dismiss={ __( 'Maybe later', 'google-site-kit' ) }
// This is arbitrarily set to 55 minutes to ensure that the notification
// will become ready to be displayed again in an hour.
dismissExpires={ MINUTE_IN_SECONDS * 55 }
/>
) }
description={
<Description
text={ sprintf(
/* translators: %1$s: Google Analytics Measurement ID. */
__(
'The previously selected web data stream with measurement ID %1$s is no longer available. Please select a new web data stream to continue collecting data with Google Analytics.',
'google-site-kit'
),
measurementID
) }
/>
}
actions={
<ActionsCTALinkDismiss
id={ id }
ctaLabel={ __(
'Update Analytics settings',
'google-site-kit'
) }
ctaLink={ `${ settingsURL }#connected-services/analytics-4/edit` }
dismissLabel={ __( 'Maybe later', 'google-site-kit' ) }
dismissExpires={ MINUTE_IN_SECONDS * 55 }
/>
}
/>
</Notification>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,48 +20,38 @@
* Internal dependencies
*/
import WithRegistrySetup from '../../../../tests/js/WithRegistrySetup';
import { MODULES_ANALYTICS_4 } from '../../modules/analytics-4/datastore/constants';
import WebDataStreamNotAvailableNotification from './WebDataStreamNotAvailableNotification';
import { withNotificationComponentProps } from '../../googlesitekit/notifications/util/component-props';
import { MODULES_ANALYTICS_4 } from '../../modules/analytics-4/datastore/constants';

function Template( { ...args } ) {
return <WebDataStreamNotAvailableNotification { ...args } />;
}
const NotificationWithComponentProps = withNotificationComponentProps(
'web-data-stream-not-available-notification'
)( WebDataStreamNotAvailableNotification );

export const Loading = Template.bind( {} );
Loading.storyName = 'Loading';
function Template() {
return <NotificationWithComponentProps />;
}

export const Default = Template.bind( {} );
Default.storyName = 'Default';
Default.decorators = [
( Story ) => {
const setupRegistry = ( registry ) => {
registry
.dispatch( MODULES_ANALYTICS_4 )
.setMeasurementID( 'G-2B7M8YQ1K6' );
};

return (
<WithRegistrySetup func={ setupRegistry }>
<Story />
</WithRegistrySetup>
);
},
];
Default.scenario = {
label: 'Global/WebDataStreamNotAvailableNotification/Default',
};
Default.storyName = 'WebDataStreamNotAvailableNotification';

export default {
title: 'Components/WebDataStreamNotAvailableNotification',
component: WebDataStreamNotAvailableNotification,
title: 'Components/Notifications/Banners',
decorators: [
( Story ) => {
const setupRegistry = ( registry ) => {
const currentAnalyticsSettingsMock = {
ownerID: 0,
propertyID: '1000',
webDataStreamID: '2000',
measurementID: 'G-2B7M8YQ1K6',
googleTagID: 'GT-12345',
googleTagLastSyncedAtMs: 0,
};

registry
.dispatch( MODULES_ANALYTICS_4 )
.setIsWebDataStreamAvailable( false );

registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( {} );
.setSettings( currentAnalyticsSettingsMock );
};

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Site Kit by Google, Copyright 2025 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.
*/

/**
* Internal dependencies
*/
import { Cell, Grid, Row } from '../../../../material-components';
import Title from '../common/Title';

export default function SimpleNotification( { actions, description, title } ) {
return (
<Grid>
<Row>
<Cell
smSize={ 3 }
mdSize={ 7 }
lgSize={ 11 }
className="googlesitekit-publisher-win__content"
>
<Title title={ title }></Title>
{ description }
{ actions }
</Cell>
</Row>
</Grid>
);
}
2 changes: 1 addition & 1 deletion assets/js/modules/analytics-4/datastore/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ const baseActions = {
) || []; // Fallback used in the event of an error.

const googleTagContainerDestinationIDs =
googleTagContainerDestinations.map(
googleTagContainerDestinations?.map(
// eslint-disable-next-line sitekit/acronym-case
( { destinationId } ) => destinationId
);
Expand Down
58 changes: 57 additions & 1 deletion assets/js/modules/analytics-4/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
TopPagesDrivingLeadsWidget,
} from './components/widgets';
import AnalyticsIcon from '../../../svg/graphics/analytics.svg';
import { MODULES_ANALYTICS_4 } from './datastore/constants';
import { GTM_SCOPE, MODULES_ANALYTICS_4 } from './datastore/constants';
import {
AREA_MAIN_DASHBOARD_CONTENT_PRIMARY,
AREA_MAIN_DASHBOARD_TRAFFIC_PRIMARY,
Expand Down Expand Up @@ -112,6 +112,9 @@ import AudienceSegmentationSetupSuccessSubtleNotification, {
import { NOTIFICATION_AREAS } from '../../googlesitekit/notifications/datastore/constants';
import { VIEW_CONTEXT_MAIN_DASHBOARD } from '../../googlesitekit/constants';
import { isFeatureEnabled } from '../../features';
import WebDataStreamNotAvailableNotification, {
WEB_DATA_STREAM_NOT_AVAILABLE_NOTIFICATION,
} from '../../components/notifications/WebDataStreamNotAvailableNotification';

export { registerStore } from './datastore';

Expand Down Expand Up @@ -719,4 +722,57 @@ export const registerNotifications = ( notifications ) => {
}
);
}

notifications.registerNotification(
WEB_DATA_STREAM_NOT_AVAILABLE_NOTIFICATION,
{
Component: WebDataStreamNotAvailableNotification,
priority: 290,
areaSlug: NOTIFICATION_AREAS.BANNERS_ABOVE_NAV,
viewContexts: [ VIEW_CONTEXT_MAIN_DASHBOARD ],
isDismissible: true,
checkRequirements: async ( {
select,
resolveSelect,
dispatch,
} ) => {
await Promise.all( [
// The hasScope() selector relies on the resolution of
// the getAuthentication() resolver.
resolveSelect( CORE_USER ).getAuthentication(),
// The isModuleConnected() selector relies on the resolution
// of the getModules() resolver.
resolveSelect( CORE_MODULES ).getModules(),
// The getID() selector relies on the resolution
// of the getUser() resolver.
resolveSelect( CORE_USER ).getUser(),
// The getOwnerID() selector relies on the resolution
// of the getSettings() resolver.
resolveSelect( MODULES_ANALYTICS_4 ).getSettings(),
// The isWebDataStreamAvailable property is set within the
// syncGoogleTagSettings() action.
dispatch( MODULES_ANALYTICS_4 ).syncGoogleTagSettings(),
] );

const ga4ModuleConnected =
select( CORE_MODULES ).isModuleConnected( 'analytics-4' );
const hasGTMScope = select( CORE_USER ).hasScope( GTM_SCOPE );

const loggedInUserID = select( CORE_USER ).getID();
const ga4OwnerID = select( MODULES_ANALYTICS_4 ).getOwnerID();
const isGA4ModuleOwner =
ga4ModuleConnected && ga4OwnerID === loggedInUserID;

const isWebDataStreamAvailable =
select( MODULES_ANALYTICS_4 ).isWebDataStreamAvailable();

return (
ga4ModuleConnected &&
hasGTMScope &&
isGA4ModuleOwner &&
! isWebDataStreamAvailable
);
},
}
);
};

0 comments on commit c33c9ba

Please sign in to comment.