diff --git a/assets/js/components/KeyMetrics/MetricTileError/GetHelpLink.js b/assets/js/components/KeyMetrics/GetHelpLink.js similarity index 97% rename from assets/js/components/KeyMetrics/MetricTileError/GetHelpLink.js rename to assets/js/components/KeyMetrics/GetHelpLink.js index 51a10381a9c..b4fcd8d9737 100644 --- a/assets/js/components/KeyMetrics/MetricTileError/GetHelpLink.js +++ b/assets/js/components/KeyMetrics/GetHelpLink.js @@ -30,7 +30,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import Link from '../../Link'; +import Link from '../Link'; export default function GetHelpLink( { linkURL } ) { return createInterpolateElement( diff --git a/assets/js/components/KeyMetrics/InfoTooltip.js b/assets/js/components/KeyMetrics/InfoTooltip.js new file mode 100644 index 00000000000..fc802f1c40c --- /dev/null +++ b/assets/js/components/KeyMetrics/InfoTooltip.js @@ -0,0 +1,53 @@ +/** + * InfoTooltip component. + * + * Site Kit by Google, Copyright 2023 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. + */ + +/** + * External dependencies + */ +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import { Tooltip } from 'googlesitekit-components'; +import InfoIcon from '../../../svg/icons/info-green.svg'; + +export default function InfoTooltip( { title } ) { + if ( ! title ) { + return null; + } + + return ( + + + + + + ); +} + +InfoTooltip.propTypes = { + title: PropTypes.string, +}; diff --git a/assets/js/components/KeyMetrics/MetricTileError/index.js b/assets/js/components/KeyMetrics/MetricTileError.js similarity index 51% rename from assets/js/components/KeyMetrics/MetricTileError/index.js rename to assets/js/components/KeyMetrics/MetricTileError.js index 0524f3bbb3b..31ca183c6e4 100644 --- a/assets/js/components/KeyMetrics/MetricTileError/index.js +++ b/assets/js/components/KeyMetrics/MetricTileError.js @@ -16,51 +16,27 @@ * limitations under the License. */ -/** - * External dependencies - */ -import { castArray } from 'lodash'; - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - /** * Internal dependencies */ -import CTA from '../../notifications/CTA'; -import ReportErrorActions from '../../ReportErrorActions'; -import GetHelpLink from './GetHelpLink'; -import { isInsufficientPermissionsError } from '../../../util/errors'; +import CTA from '../notifications/CTA'; +import InfoTooltip from './InfoTooltip'; export default function MetricTileError( props ) { - const { error, headerText, moduleSlug } = props; - const hasInsufficientPermissionsError = castArray( error ).some( - isInsufficientPermissionsError - ); + const { children, headerText, infoTooltip, title } = props; return (
+ } description="" error > - + { children }
); diff --git a/assets/js/components/KeyMetrics/MetricTileHeader.js b/assets/js/components/KeyMetrics/MetricTileHeader.js index 9601a9feb4a..3e0ab9b496d 100644 --- a/assets/js/components/KeyMetrics/MetricTileHeader.js +++ b/assets/js/components/KeyMetrics/MetricTileHeader.js @@ -24,27 +24,13 @@ import PropTypes from 'prop-types'; /** * Internal dependencies */ -import { Tooltip } from 'googlesitekit-components'; -import InfoIcon from '../../../svg/icons/info-green.svg'; +import InfoTooltip from './InfoTooltip'; export default function MetricTileHeader( { title, infoTooltip } ) { return (

{ title }

- { infoTooltip && ( - - - - - - ) } +
); } diff --git a/assets/js/components/KeyMetrics/MetricTileNumeric.js b/assets/js/components/KeyMetrics/MetricTileNumeric.js index 6eaf044ef4f..c2d9fd77a67 100644 --- a/assets/js/components/KeyMetrics/MetricTileNumeric.js +++ b/assets/js/components/KeyMetrics/MetricTileNumeric.js @@ -21,82 +21,44 @@ */ import PropTypes from 'prop-types'; -/** - * WordPress dependencies - */ -import { Fragment } from '@wordpress/element'; - /** * Internal dependencies */ import { numFmt, expandNumFmtOptions } from '../../util'; import ChangeBadge from '../ChangeBadge'; -import MetricTileError from './MetricTileError'; -import MetricTileLoader from './MetricTileLoader'; -import MetricTileHeader from './MetricTileHeader'; - -export default function MetricTileNumeric( props ) { - const { - Widget, - loading, - title, - metricValue, - metricValueFormat, - subText, - previousValue, - currentValue, - error, - moduleSlug, - infoTooltip, - } = props; +import MetricTileWrapper from './MetricTileWrapper'; +export default function MetricTileNumeric( { + metricValue, + metricValueFormat, + subText, + previousValue, + currentValue, + ...props +} ) { const formatOptions = expandNumFmtOptions( metricValueFormat ); - if ( error ) { - return ( - - ); - } - return ( - -
- -
- { loading && } - { ! loading && ( - -
-
- { numFmt( metricValue, formatOptions ) } -
- -
-

- { subText } -

-
- ) } + +
+
+ { numFmt( metricValue, formatOptions ) }
+
- +

{ subText }

+
); } MetricTileNumeric.propTypes = { - Widget: PropTypes.elementType.isRequired, - loading: PropTypes.bool, - title: PropTypes.string, metricValue: PropTypes.oneOfType( [ PropTypes.string, PropTypes.number ] ), metricValueFormat: PropTypes.oneOfType( [ PropTypes.string, @@ -105,10 +67,4 @@ MetricTileNumeric.propTypes = { subtext: PropTypes.string, previousValue: PropTypes.number, currentValue: PropTypes.number, - error: PropTypes.oneOfType( [ - PropTypes.arrayOf( PropTypes.object ), - PropTypes.object, - ] ), - moduleSlug: PropTypes.string.isRequired, - infoTooltip: PropTypes.oneOfType( [ PropTypes.string, PropTypes.element ] ), }; diff --git a/assets/js/components/KeyMetrics/MetricTileTable.js b/assets/js/components/KeyMetrics/MetricTileTable.js index 1ca75fa2e0e..48534302150 100644 --- a/assets/js/components/KeyMetrics/MetricTileTable.js +++ b/assets/js/components/KeyMetrics/MetricTileTable.js @@ -24,34 +24,15 @@ import classnames from 'classnames'; /** * Internal dependencies */ -import MetricTileError from './MetricTileError'; -import MetricTileLoader from './MetricTileLoader'; -import MetricTileHeader from './MetricTileHeader'; - -export default function MetricTileTable( props ) { - const { - Widget, - loading, - title, - rows = [], - columns = [], - limit, - infoTooltip, - ZeroState, - error, - moduleSlug, - } = props; - - if ( error ) { - return ( - - ); - } +import MetricTileWrapper from './MetricTileWrapper'; +export default function MetricTileTable( { + rows = [], + columns = [], + limit, + ZeroState, + ...props +} ) { let tileBody = null; if ( rows?.length > 0 ) { @@ -98,34 +79,20 @@ export default function MetricTileTable( props ) { } return ( - -
- -
- { loading && } - { ! loading && ( -
- { tileBody } -
- ) } -
+ +
+ { tileBody }
- +
); } MetricTileTable.propTypes = { - Widget: PropTypes.elementType.isRequired, - loading: PropTypes.bool, - title: PropTypes.string, rows: PropTypes.array, columns: PropTypes.array, limit: PropTypes.number, - infoTooltip: PropTypes.oneOfType( [ PropTypes.string, PropTypes.element ] ), ZeroState: PropTypes.elementType, - error: PropTypes.oneOfType( [ - PropTypes.arrayOf( PropTypes.object ), - PropTypes.object, - ] ), - moduleSlug: PropTypes.string.isRequired, }; diff --git a/assets/js/components/KeyMetrics/MetricTileText.js b/assets/js/components/KeyMetrics/MetricTileText.js index cab08ab137c..1270e869f81 100644 --- a/assets/js/components/KeyMetrics/MetricTileText.js +++ b/assets/js/components/KeyMetrics/MetricTileText.js @@ -26,79 +26,41 @@ import PropTypes from 'prop-types'; */ import ChangeBadge from '../ChangeBadge'; import { expandNumFmtOptions } from '../../util'; -import { Fragment } from 'react'; -import MetricTileError from './MetricTileError'; -import MetricTileLoader from './MetricTileLoader'; -import MetricTileHeader from './MetricTileHeader'; +import MetricTileWrapper from './MetricTileWrapper'; export default function MetricTileText( { - Widget, - loading, - title, metricValue, metricValueFormat, subText, previousValue, currentValue, - error, - moduleSlug, - infoTooltip, + ...props } ) { const formatOptions = expandNumFmtOptions( metricValueFormat ); - if ( error ) { - return ( - - ); - } - return ( - -
- -
- { loading && } - { ! loading && ( - -
- { metricValue } -
-

- { subText } -

-
- -
-
- ) } -
+ +
+ { metricValue } +
+

{ subText }

+
+
- +
); } MetricTileText.propTypes = { - Widget: PropTypes.elementType.isRequired, - loading: PropTypes.bool, - title: PropTypes.string, metricValue: PropTypes.oneOfType( [ PropTypes.string, PropTypes.number ] ), subtext: PropTypes.string, previousValue: PropTypes.number, currentValue: PropTypes.number, - error: PropTypes.oneOfType( [ - PropTypes.arrayOf( PropTypes.object ), - PropTypes.object, - ] ), - moduleSlug: PropTypes.string.isRequired, - infoTooltip: PropTypes.oneOfType( [ PropTypes.string, PropTypes.element ] ), }; diff --git a/assets/js/components/KeyMetrics/MetricTileWrapper.js b/assets/js/components/KeyMetrics/MetricTileWrapper.js new file mode 100644 index 00000000000..e385876add8 --- /dev/null +++ b/assets/js/components/KeyMetrics/MetricTileWrapper.js @@ -0,0 +1,106 @@ +/** + * MetricTileWrapper component. + * + * Site Kit by Google, Copyright 2023 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. + */ + +/** + * External dependencies + */ +import classnames from 'classnames'; +import { castArray } from 'lodash'; +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { KEY_METRICS_WIDGETS } from './key-metrics-widgets'; +import GetHelpLink from './GetHelpLink'; +import MetricTileLoader from './MetricTileLoader'; +import MetricTileError from './MetricTileError'; +import MetricTileHeader from './MetricTileHeader'; +import ReportErrorActions from '../ReportErrorActions'; +import { isInsufficientPermissionsError } from '../../util/errors'; + +export default function MetricTileWrapper( { + className, + children, + error, + loading, + moduleSlug, + Widget, + widgetSlug, + title = KEY_METRICS_WIDGETS[ widgetSlug ]?.title, + infoTooltip = KEY_METRICS_WIDGETS[ widgetSlug ]?.infoTooltip || + KEY_METRICS_WIDGETS[ widgetSlug ]?.description, +} ) { + if ( error ) { + const hasInsufficientPermissionsReportError = castArray( error ).some( + isInsufficientPermissionsError + ); + + return ( + + + + ); + } + + return ( + +
+ +
+ { loading && } + { ! loading && children } +
+
+
+ ); +} + +MetricTileWrapper.propTypes = { + Widget: PropTypes.elementType.isRequired, + loading: PropTypes.bool, + title: PropTypes.string, + infoTooltip: PropTypes.oneOfType( [ PropTypes.string, PropTypes.element ] ), + moduleSlug: PropTypes.string.isRequired, +}; diff --git a/assets/js/components/KeyMetrics/MetricsSelectionPanel/index.test.js b/assets/js/components/KeyMetrics/MetricsSelectionPanel/index.test.js index 1ba1e10b06c..7ccbd76547a 100644 --- a/assets/js/components/KeyMetrics/MetricsSelectionPanel/index.test.js +++ b/assets/js/components/KeyMetrics/MetricsSelectionPanel/index.test.js @@ -32,11 +32,11 @@ import { CORE_UI } from '../../../googlesitekit/datastore/ui/constants'; import { CORE_USER, KM_ANALYTICS_ENGAGED_TRAFFIC_SOURCE, - KM_ANALYTICS_LEAST_ENGAGING_PAGES, KM_ANALYTICS_LOYAL_VISITORS, KM_ANALYTICS_NEW_VISITORS, KM_ANALYTICS_POPULAR_CONTENT, KM_ANALYTICS_TOP_CONVERTING_TRAFFIC_SOURCE, + KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES, KM_ANALYTICS_TOP_TRAFFIC_SOURCE, KM_SEARCH_CONSOLE_POPULAR_KEYWORDS, } from '../../../googlesitekit/datastore/user/constants'; @@ -368,7 +368,7 @@ describe( 'MetricsSelectionPanel', () => { [ KM_ANALYTICS_LOYAL_VISITORS ]: { modules: [ 'analytics-4' ], }, - [ KM_ANALYTICS_LEAST_ENGAGING_PAGES ]: { + [ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ]: { modules: [ 'analytics-4' ], }, } ); @@ -384,7 +384,7 @@ describe( 'MetricsSelectionPanel', () => { ).toBeDisabled(); } ); - it( 'should display sppropriate message when a metric requires custom dimensions and does not have edit scope', async () => { + it( 'should display appropriate message when a metric requires custom dimensions and does not have edit scope', async () => { provideKeyMetrics( registry, { widgetSlugs: [ KM_SEARCH_CONSOLE_POPULAR_KEYWORDS, @@ -409,7 +409,9 @@ describe( 'MetricsSelectionPanel', () => { 'The metrics you selected require more data tracking. You will be directed to update your Analytics property after saving your selection.' ); - const checkbox = await findByLabelText( 'Least engaging pages' ); + const checkbox = await findByLabelText( + 'Top recent trending pages' + ); fireEvent.click( checkbox ); expect( @@ -419,7 +421,7 @@ describe( 'MetricsSelectionPanel', () => { ).toBeInTheDocument(); } ); - it( 'should display sppropriate message when a metric requires custom dimensions and have edit scope', async () => { + it( 'should display appropriate message when a metric requires custom dimensions and has edit scope', async () => { provideKeyMetrics( registry, { widgetSlugs: [ KM_SEARCH_CONSOLE_POPULAR_KEYWORDS, @@ -448,7 +450,9 @@ describe( 'MetricsSelectionPanel', () => { 'The metrics you selected require more data tracking. We will update your Analytics property after saving your selection.' ); - const checkbox = await findByLabelText( 'Least engaging pages' ); + const checkbox = await findByLabelText( + 'Top recent trending pages' + ); fireEvent.click( checkbox ); expect( diff --git a/assets/js/components/KeyMetrics/key-metrics-widgets.js b/assets/js/components/KeyMetrics/key-metrics-widgets.js index 5b3385e12fa..a5ccd117aba 100644 --- a/assets/js/components/KeyMetrics/key-metrics-widgets.js +++ b/assets/js/components/KeyMetrics/key-metrics-widgets.js @@ -42,6 +42,9 @@ import { KM_ANALYTICS_VISIT_LENGTH, KM_ANALYTICS_MOST_ENGAGING_PAGES, CORE_USER, + KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES, + KM_ANALYTICS_TOP_CATEGORIES, + KM_ANALYTICS_POPULAR_AUTHORS, } from '../../googlesitekit/datastore/user/constants'; import { CORE_SITE } from '../../googlesitekit/datastore/site/constants'; import { isFeatureEnabled } from '../../features'; @@ -171,12 +174,7 @@ const KEY_METRICS_WIDGETS = { 'Pages with the highest bounce rate (visitors who left without any meaningful engagement with your site)', 'google-site-kit' ), - // TODO: Remove this once we have the correct custom dimensions. - requiredCustomDimensions: [ - 'googlesitekit_post_author', - 'googlesitekit_post_categories', - ], - displayInList: shouldDisplayWidgetWithCustomDimensions, + displayInList: () => isFeatureEnabled( 'newsKeyMetrics' ), }, [ KM_ANALYTICS_PAGES_PER_VISIT ]: { title: __( 'Pages per visit', 'google-site-kit' ), @@ -184,12 +182,7 @@ const KEY_METRICS_WIDGETS = { 'Number of pages visitors viewed per session on average', 'google-site-kit' ), - // TODO: Remove this once we have the correct custom dimensions. - requiredCustomDimensions: [ - 'googlesitekit_post_author', - 'googlesitekit_post_categories', - ], - displayInList: shouldDisplayWidgetWithCustomDimensions, + displayInList: () => isFeatureEnabled( 'newsKeyMetrics' ), }, [ KM_ANALYTICS_VISIT_LENGTH ]: { title: __( 'Visit length', 'google-site-kit' ), @@ -215,6 +208,33 @@ const KEY_METRICS_WIDGETS = { ), displayInList: () => isFeatureEnabled( 'newsKeyMetrics' ), }, + [ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ]: { + title: __( 'Top recent trending pages', 'google-site-kit' ), + description: __( + 'Pages with the most pageviews published in the last 3 days', + 'google-site-kit' + ), + requiredCustomDimensions: [ 'googlesitekit_post_date' ], + displayInList: shouldDisplayWidgetWithCustomDimensions, + }, + [ KM_ANALYTICS_TOP_CATEGORIES ]: { + title: __( 'Top categories by pageviews', 'google-site-kit' ), + description: __( + 'Categories that your site visitors viewed the most', + 'google-site-kit' + ), + requiredCustomDimensions: [ 'googlesitekit_post_categories' ], + displayInList: shouldDisplayWidgetWithCustomDimensions, + }, + [ KM_ANALYTICS_POPULAR_AUTHORS ]: { + title: __( 'Most popular authors by pageviews', 'google-site-kit' ), + description: __( + 'Authors whose posts got the most visits', + 'google-site-kit' + ), + requiredCustomDimensions: [ 'googlesitekit_post_author' ], + displayInList: shouldDisplayWidgetWithCustomDimensions, + }, }; export { KEY_METRICS_WIDGETS }; diff --git a/assets/js/components/notifications/CTA.js b/assets/js/components/notifications/CTA.js index 1127dfa0951..404c8a784a5 100644 --- a/assets/js/components/notifications/CTA.js +++ b/assets/js/components/notifications/CTA.js @@ -31,6 +31,7 @@ import Link from '../Link'; const CTA = ( { title, headerText, + headerContent, description, ctaLink, ctaLabel, @@ -46,8 +47,15 @@ const CTA = ( { 'googlesitekit-cta--error': error, } ) } > - { headerText && ( -

{ headerText }

+ { ( headerText || headerContent ) && ( +
+ { headerText && ( +

+ { headerText } +

+ ) } + { headerContent } +
) } { title &&

{ title }

} { description && typeof description === 'string' && ( @@ -95,11 +103,13 @@ CTA.propTypes = { error: PropTypes.bool, onClick: PropTypes.func, children: PropTypes.node, + headerContent: PropTypes.node, }; CTA.defaultProps = { title: '', headerText: '', + headerContent: '', description: '', ctaLink: '', ctaLabel: '', diff --git a/assets/js/googlesitekit/datastore/user/constants.js b/assets/js/googlesitekit/datastore/user/constants.js index 2177d6e4a6a..a19b582496f 100644 --- a/assets/js/googlesitekit/datastore/user/constants.js +++ b/assets/js/googlesitekit/datastore/user/constants.js @@ -51,12 +51,16 @@ export const KM_ANALYTICS_LEAST_ENGAGING_PAGES = 'kmAnalyticsLeastEngagingPages'; export const KM_ANALYTICS_LOYAL_VISITORS = 'kmAnalyticsLoyalVisitors'; export const KM_ANALYTICS_NEW_VISITORS = 'kmAnalyticsNewVisitors'; +export const KM_ANALYTICS_POPULAR_AUTHORS = 'kmAnalyticsPopularAuthors'; export const KM_ANALYTICS_POPULAR_CONTENT = 'kmAnalyticsPopularContent'; export const KM_ANALYTICS_POPULAR_PRODUCTS = 'kmAnalyticsPopularProducts'; +export const KM_ANALYTICS_TOP_CATEGORIES = 'kmAnalyticsTopCategories'; export const KM_ANALYTICS_TOP_CITIES = 'kmAnalyticsTopCities'; export const KM_ANALYTICS_TOP_CONVERTING_TRAFFIC_SOURCE = 'kmAnalyticsTopConvertingTrafficSource'; export const KM_ANALYTICS_TOP_COUNTRIES = 'kmAnalyticsTopCountries'; +export const KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES = + 'kmAnalyticsTopRecentTrendingPages'; export const KM_ANALYTICS_TOP_TRAFFIC_SOURCE = 'kmAnalyticsTopTrafficSource'; export const KM_ANALYTICS_PAGES_PER_VISIT = 'kmAnalyticsPagesPerVisit'; export const KM_ANALYTICS_VISIT_LENGTH = 'kmAnalyticsVisitLength'; @@ -73,11 +77,14 @@ export const keyMetricsGA4Widgets = [ KM_ANALYTICS_LEAST_ENGAGING_PAGES, KM_ANALYTICS_LOYAL_VISITORS, KM_ANALYTICS_NEW_VISITORS, + KM_ANALYTICS_POPULAR_AUTHORS, KM_ANALYTICS_POPULAR_CONTENT, KM_ANALYTICS_POPULAR_PRODUCTS, + KM_ANALYTICS_TOP_CATEGORIES, KM_ANALYTICS_TOP_CITIES, KM_ANALYTICS_TOP_CONVERTING_TRAFFIC_SOURCE, KM_ANALYTICS_TOP_COUNTRIES, + KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES, KM_ANALYTICS_TOP_TRAFFIC_SOURCE, KM_ANALYTICS_PAGES_PER_VISIT, KM_ANALYTICS_VISIT_LENGTH, diff --git a/assets/js/modules/analytics-4/components/widgets/PopularAuthorsWidget.js b/assets/js/modules/analytics-4/components/widgets/PopularAuthorsWidget.js new file mode 100644 index 00000000000..a82d5814800 --- /dev/null +++ b/assets/js/modules/analytics-4/components/widgets/PopularAuthorsWidget.js @@ -0,0 +1,60 @@ +/** + * PopularAuthorsWidget component. + * + * Site Kit by Google, Copyright 2023 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. + */ + +/** + * External dependencies + */ +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { compose } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import { KM_ANALYTICS_POPULAR_AUTHORS } from '../../../../googlesitekit/datastore/user/constants'; +import { MetricTileTable } from '../../../../components/KeyMetrics'; +import { ZeroDataMessage } from '../../../analytics/components/common'; +import whenActive from '../../../../util/when-active'; +import withCustomDimensions from '../../utils/withCustomDimensions'; +import ConnectGA4CTATileWidget from './ConnectGA4CTATileWidget'; + +function PopularAuthorsWidget( { Widget } ) { + return ( + + ); +} + +PopularAuthorsWidget.propTypes = { + Widget: PropTypes.elementType.isRequired, +}; + +export default compose( + whenActive( { + moduleName: 'analytics-4', + FallbackComponent: ConnectGA4CTATileWidget, + } ), + withCustomDimensions() +)( PopularAuthorsWidget ); diff --git a/assets/js/modules/analytics-4/components/widgets/PopularAuthorsWidget.stories.js b/assets/js/modules/analytics-4/components/widgets/PopularAuthorsWidget.stories.js new file mode 100644 index 00000000000..d71677e4d4c --- /dev/null +++ b/assets/js/modules/analytics-4/components/widgets/PopularAuthorsWidget.stories.js @@ -0,0 +1,147 @@ +/** + * PopularAuthorsWidget Component Stories. + * + * Site Kit by Google, Copyright 2023 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 { ERROR_REASON_INSUFFICIENT_PERMISSIONS } from '../../../../util/errors'; +import { MODULES_ANALYTICS_4 } from '../../datastore/constants'; +import { KEY_METRICS_WIDGETS } from '../../../../components/KeyMetrics/key-metrics-widgets'; +import { KM_ANALYTICS_POPULAR_AUTHORS } from '../../../../googlesitekit/datastore/user/constants'; +import { provideModules } from '../../../../../../tests/js/utils'; +import { provideCustomDimensionError } from '../../utils/custom-dimensions'; +import { withWidgetComponentProps } from '../../../../googlesitekit/widgets/util'; +import WithRegistrySetup from '../../../../../../tests/js/WithRegistrySetup'; +import PopularAuthorsWidget from './PopularAuthorsWidget'; + +const WidgetWithComponentProps = withWidgetComponentProps( + KM_ANALYTICS_POPULAR_AUTHORS +)( PopularAuthorsWidget ); + +const Template = ( { setupRegistry, ...args } ) => ( + + + +); + +export const Ready = Template.bind( {} ); +Ready.storyName = 'Ready'; +Ready.args = { + setupRegistry: ( registry ) => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID: '123456789', + availableCustomDimensions: [ + KEY_METRICS_WIDGETS[ KM_ANALYTICS_POPULAR_AUTHORS ] + .requiredCustomDimensions?.[ 0 ], + ], + } ); + }, +}; +Ready.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorMissingCustomDimensions = Template.bind( {} ); +ErrorMissingCustomDimensions.storyName = 'Error - Missing custom dimensions'; +ErrorMissingCustomDimensions.args = { + setupRegistry: () => {}, +}; +ErrorMissingCustomDimensions.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorCustomDimensionsInsufficientPermissions = Template.bind( {} ); +ErrorCustomDimensionsInsufficientPermissions.storyName = + 'Error - Custom dimensions creation - Insufficient Permissions'; +ErrorCustomDimensionsInsufficientPermissions.args = { + setupRegistry: ( registry ) => { + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: ERROR_REASON_INSUFFICIENT_PERMISSIONS, + }, + }; + + registry.dispatch( MODULES_ANALYTICS_4 ).setPropertyID( '123456789' ); + + provideCustomDimensionError( registry, { + customDimension: + KEY_METRICS_WIDGETS[ KM_ANALYTICS_POPULAR_AUTHORS ] + .requiredCustomDimensions?.[ 0 ], + error, + } ); + }, +}; +ErrorCustomDimensionsInsufficientPermissions.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorCustomDimensionsGeneric = Template.bind( {} ); +ErrorCustomDimensionsGeneric.storyName = + 'Error - Custom dimensions creation - Generic'; +ErrorCustomDimensionsGeneric.args = { + setupRegistry: ( registry ) => { + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: 'test-error-reason', + }, + }; + + registry.dispatch( MODULES_ANALYTICS_4 ).setPropertyID( '123456789' ); + + provideCustomDimensionError( registry, { + customDimension: + KEY_METRICS_WIDGETS[ KM_ANALYTICS_POPULAR_AUTHORS ] + .requiredCustomDimensions?.[ 0 ], + error, + } ); + }, +}; +ErrorCustomDimensionsGeneric.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export default { + title: 'Key Metrics/PopularAuthorsWidget', + component: PopularAuthorsWidget, + decorators: [ + ( Story, { args } ) => { + const setupRegistry = ( registry ) => { + provideModules( registry, [ + { + slug: 'analytics-4', + active: true, + connected: true, + }, + ] ); + + // Call story-specific setup. + args.setupRegistry( registry ); + }; + + return ( + + + + ); + }, + ], +}; diff --git a/assets/js/modules/analytics-4/components/widgets/TopCategoriesWidget.js b/assets/js/modules/analytics-4/components/widgets/TopCategoriesWidget.js new file mode 100644 index 00000000000..99b6cb902a8 --- /dev/null +++ b/assets/js/modules/analytics-4/components/widgets/TopCategoriesWidget.js @@ -0,0 +1,60 @@ +/** + * TopCategoriesWidget component. + * + * Site Kit by Google, Copyright 2023 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. + */ + +/** + * External dependencies + */ +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { compose } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import { KM_ANALYTICS_TOP_CATEGORIES } from '../../../../googlesitekit/datastore/user/constants'; +import { MetricTileTable } from '../../../../components/KeyMetrics'; +import { ZeroDataMessage } from '../../../analytics/components/common'; +import whenActive from '../../../../util/when-active'; +import withCustomDimensions from '../../utils/withCustomDimensions'; +import ConnectGA4CTATileWidget from './ConnectGA4CTATileWidget'; + +function TopCategoriesWidget( { Widget } ) { + return ( + + ); +} + +TopCategoriesWidget.propTypes = { + Widget: PropTypes.elementType.isRequired, +}; + +export default compose( + whenActive( { + moduleName: 'analytics-4', + FallbackComponent: ConnectGA4CTATileWidget, + } ), + withCustomDimensions() +)( TopCategoriesWidget ); diff --git a/assets/js/modules/analytics-4/components/widgets/TopCategoriesWidget.stories.js b/assets/js/modules/analytics-4/components/widgets/TopCategoriesWidget.stories.js new file mode 100644 index 00000000000..51e4f0d0f1c --- /dev/null +++ b/assets/js/modules/analytics-4/components/widgets/TopCategoriesWidget.stories.js @@ -0,0 +1,147 @@ +/** + * TopCategoriesWidget Component Stories. + * + * Site Kit by Google, Copyright 2023 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 { ERROR_REASON_INSUFFICIENT_PERMISSIONS } from '../../../../util/errors'; +import { MODULES_ANALYTICS_4 } from '../../datastore/constants'; +import { KEY_METRICS_WIDGETS } from '../../../../components/KeyMetrics/key-metrics-widgets'; +import { KM_ANALYTICS_TOP_CATEGORIES } from '../../../../googlesitekit/datastore/user/constants'; +import { provideModules } from '../../../../../../tests/js/utils'; +import { withWidgetComponentProps } from '../../../../googlesitekit/widgets/util'; +import WithRegistrySetup from '../../../../../../tests/js/WithRegistrySetup'; +import TopCategoriesWidget from './TopCategoriesWidget'; +import { provideCustomDimensionError } from '../../utils/custom-dimensions'; + +const WidgetWithComponentProps = withWidgetComponentProps( + KM_ANALYTICS_TOP_CATEGORIES +)( TopCategoriesWidget ); + +const Template = ( { setupRegistry, ...args } ) => ( + + + +); + +export const Ready = Template.bind( {} ); +Ready.storyName = 'Ready'; +Ready.args = { + setupRegistry: ( registry ) => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID: '123456789', + availableCustomDimensions: [ + KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_CATEGORIES ] + .requiredCustomDimensions?.[ 0 ], + ], + } ); + }, +}; +Ready.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorMissingCustomDimensions = Template.bind( {} ); +ErrorMissingCustomDimensions.storyName = 'Error - Missing custom dimensions'; +ErrorMissingCustomDimensions.args = { + setupRegistry: () => {}, +}; +ErrorMissingCustomDimensions.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorCustomDimensionsInsufficientPermissions = Template.bind( {} ); +ErrorCustomDimensionsInsufficientPermissions.storyName = + 'Error - Custom dimensions creation - Insufficient Permissions'; +ErrorCustomDimensionsInsufficientPermissions.args = { + setupRegistry: ( registry ) => { + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: ERROR_REASON_INSUFFICIENT_PERMISSIONS, + }, + }; + + registry.dispatch( MODULES_ANALYTICS_4 ).setPropertyID( '123456789' ); + + provideCustomDimensionError( registry, { + customDimension: + KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_CATEGORIES ] + .requiredCustomDimensions?.[ 0 ], + error, + } ); + }, +}; +ErrorCustomDimensionsInsufficientPermissions.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorCustomDimensionsGeneric = Template.bind( {} ); +ErrorCustomDimensionsGeneric.storyName = + 'Error - Custom dimensions creation - Generic'; +ErrorCustomDimensionsGeneric.args = { + setupRegistry: ( registry ) => { + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: 'test-error-reason', + }, + }; + + registry.dispatch( MODULES_ANALYTICS_4 ).setPropertyID( '123456789' ); + + provideCustomDimensionError( registry, { + customDimension: + KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_CATEGORIES ] + .requiredCustomDimensions?.[ 0 ], + error, + } ); + }, +}; +ErrorCustomDimensionsGeneric.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export default { + title: 'Key Metrics/TopCategoriesWidget', + component: TopCategoriesWidget, + decorators: [ + ( Story, { args } ) => { + const setupRegistry = ( registry ) => { + provideModules( registry, [ + { + slug: 'analytics-4', + active: true, + connected: true, + }, + ] ); + + // Call story-specific setup. + args.setupRegistry( registry ); + }; + + return ( + + + + ); + }, + ], +}; diff --git a/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPages.stories.js b/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPages.stories.js new file mode 100644 index 00000000000..55255ba2648 --- /dev/null +++ b/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPages.stories.js @@ -0,0 +1,147 @@ +/** + * TopRecentTrendingPagesWidget Component Stories. + * + * Site Kit by Google, Copyright 2023 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 { ERROR_REASON_INSUFFICIENT_PERMISSIONS } from '../../../../util/errors'; +import { MODULES_ANALYTICS_4 } from '../../datastore/constants'; +import { KEY_METRICS_WIDGETS } from '../../../../components/KeyMetrics/key-metrics-widgets'; +import { KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES } from '../../../../googlesitekit/datastore/user/constants'; +import { provideModules } from '../../../../../../tests/js/utils'; +import { withWidgetComponentProps } from '../../../../googlesitekit/widgets/util'; +import WithRegistrySetup from '../../../../../../tests/js/WithRegistrySetup'; +import TopRecentTrendingPagesWidget from './TopRecentTrendingPagesWidget'; +import { provideCustomDimensionError } from '../../utils/custom-dimensions'; + +const WidgetWithComponentProps = withWidgetComponentProps( + KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES +)( TopRecentTrendingPagesWidget ); + +const Template = ( { setupRegistry, ...args } ) => ( + + + +); + +export const Ready = Template.bind( {} ); +Ready.storyName = 'Ready'; +Ready.args = { + setupRegistry: ( registry ) => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID: '123456789', + availableCustomDimensions: [ + KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ] + .requiredCustomDimensions?.[ 0 ], + ], + } ); + }, +}; +Ready.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorMissingCustomDimensions = Template.bind( {} ); +ErrorMissingCustomDimensions.storyName = 'Error - Missing custom dimensions'; +ErrorMissingCustomDimensions.args = { + setupRegistry: () => {}, +}; +ErrorMissingCustomDimensions.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorCustomDimensionsInsufficientPermissions = Template.bind( {} ); +ErrorCustomDimensionsInsufficientPermissions.storyName = + 'Error - Custom dimensions creation - Insufficient Permissions'; +ErrorCustomDimensionsInsufficientPermissions.args = { + setupRegistry: ( registry ) => { + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: ERROR_REASON_INSUFFICIENT_PERMISSIONS, + }, + }; + + registry.dispatch( MODULES_ANALYTICS_4 ).setPropertyID( '123456789' ); + + provideCustomDimensionError( registry, { + customDimension: + KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ] + .requiredCustomDimensions?.[ 0 ], + error, + } ); + }, +}; +ErrorCustomDimensionsInsufficientPermissions.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export const ErrorCustomDimensionsGeneric = Template.bind( {} ); +ErrorCustomDimensionsGeneric.storyName = + 'Error - Custom dimensions creation - Generic'; +ErrorCustomDimensionsGeneric.args = { + setupRegistry: ( registry ) => { + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: 'test-error-reason', + }, + }; + + registry.dispatch( MODULES_ANALYTICS_4 ).setPropertyID( '123456789' ); + + provideCustomDimensionError( registry, { + customDimension: + KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ] + .requiredCustomDimensions?.[ 0 ], + error, + } ); + }, +}; +ErrorCustomDimensionsGeneric.parameters = { + features: [ 'newsKeyMetrics' ], +}; + +export default { + title: 'Key Metrics/TopRecentTrendingPagesWidget', + component: TopRecentTrendingPagesWidget, + decorators: [ + ( Story, { args } ) => { + const setupRegistry = ( registry ) => { + provideModules( registry, [ + { + slug: 'analytics-4', + active: true, + connected: true, + }, + ] ); + + // Call story-specific setup. + args.setupRegistry( registry ); + }; + + return ( + + + + ); + }, + ], +}; diff --git a/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.js b/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.js new file mode 100644 index 00000000000..d7b1fecc068 --- /dev/null +++ b/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.js @@ -0,0 +1,60 @@ +/** + * TopRecentTrendingPagesWidget component. + * + * Site Kit by Google, Copyright 2023 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. + */ + +/** + * External dependencies + */ +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { compose } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import { KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES } from '../../../../googlesitekit/datastore/user/constants'; +import { MetricTileTable } from '../../../../components/KeyMetrics'; +import { ZeroDataMessage } from '../../../analytics/components/common'; +import whenActive from '../../../../util/when-active'; +import withCustomDimensions from '../../utils/withCustomDimensions'; +import ConnectGA4CTATileWidget from './ConnectGA4CTATileWidget'; + +function TopRecentTrendingPagesWidget( { Widget } ) { + return ( + + ); +} + +TopRecentTrendingPagesWidget.propTypes = { + Widget: PropTypes.elementType.isRequired, +}; + +export default compose( + whenActive( { + moduleName: 'analytics-4', + FallbackComponent: ConnectGA4CTATileWidget, + } ), + withCustomDimensions() +)( TopRecentTrendingPagesWidget ); diff --git a/assets/js/modules/analytics-4/components/widgets/__snapshots__/TopTrafficSourceWidget.test.js.snap b/assets/js/modules/analytics-4/components/widgets/__snapshots__/TopTrafficSourceWidget.test.js.snap index 6cf1ffc5337..bcc311eac85 100644 --- a/assets/js/modules/analytics-4/components/widgets/__snapshots__/TopTrafficSourceWidget.test.js.snap +++ b/assets/js/modules/analytics-4/components/widgets/__snapshots__/TopTrafficSourceWidget.test.js.snap @@ -63,11 +63,21 @@ exports[`TopTrafficSourceWidget retries both reports when an error is encountere
-

- Top traffic source -

+

+ Top traffic source +

+ + + +

diff --git a/assets/js/modules/analytics-4/components/widgets/index.js b/assets/js/modules/analytics-4/components/widgets/index.js index 4bf83cef36a..86e42ae1d3f 100644 --- a/assets/js/modules/analytics-4/components/widgets/index.js +++ b/assets/js/modules/analytics-4/components/widgets/index.js @@ -33,3 +33,6 @@ export { default as PagesPerVisitWidget } from './PagesPerVisitWidget'; export { default as VisitLengthWidget } from './VisitLengthWidget'; export { default as TopReturningVisitorPages } from './TopReturningVisitorPages'; export { default as VisitsPerVisitorWidget } from './VisitsPerVisitorWidget'; +export { default as TopRecentTrendingPagesWidget } from './TopRecentTrendingPagesWidget'; +export { default as TopCategoriesWidget } from './TopCategoriesWidget'; +export { default as PopularAuthorsWidget } from './PopularAuthorsWidget'; diff --git a/assets/js/modules/analytics-4/datastore/custom-dimensions.js b/assets/js/modules/analytics-4/datastore/custom-dimensions.js index 80d62d72ae6..90c68643d8a 100644 --- a/assets/js/modules/analytics-4/datastore/custom-dimensions.js +++ b/assets/js/modules/analytics-4/datastore/custom-dimensions.js @@ -34,7 +34,6 @@ import API from 'googlesitekit-api'; import Data from 'googlesitekit-data'; import { createFetchStore } from '../../../googlesitekit/data/create-fetch-store'; import { isValidPropertyID } from '../utils/validation'; -import { createValidatedAction } from '../../../googlesitekit/data/utils'; import { MODULES_ANALYTICS_4 } from './constants'; import { CORE_USER, @@ -44,7 +43,7 @@ import { KEY_METRICS_WIDGETS } from '../../../components/KeyMetrics/key-metrics- const { createRegistrySelector } = Data; -const possibleCustomDimensions = { +export const possibleCustomDimensions = { googlesitekit_post_date: { parameterName: 'googlesitekit_post_date', displayName: __( 'WordPress Post Creation Date', 'google-site-kit' ), @@ -119,23 +118,26 @@ const fetchCreateCustomDimensionStore = createFetchStore( { const fetchSyncAvailableCustomDimensionsStore = createFetchStore( { baseName: 'syncAvailableCustomDimensions', - controlCallback: ( { propertyID } ) => { - return API.set( 'modules', 'analytics-4', 'sync-custom-dimensions', { - propertyID, - } ); - }, - argsToParams: ( propertyID ) => ( { - propertyID, - } ), - validateParams: ( { propertyID } ) => { - invariant( - isValidPropertyID( propertyID ), - 'A valid GA4 propertyID is required.' - ); + controlCallback: () => + API.set( 'modules', 'analytics-4', 'sync-custom-dimensions' ), + reducerCallback: ( state, dimensions ) => { + return { + ...state, + settings: { + ...state.settings, + availableCustomDimensions: [ ...dimensions ], + }, + }; }, } ); -const baseInitialState = {}; +const baseInitialState = { + customDimensionsBeingCreated: [], +}; + +// Actions +const SET_CUSTOM_DIMENSIONS_BEING_CREATED = + 'SET_CUSTOM_DIMENSIONS_BEING_CREATED'; const baseActions = { /** @@ -187,6 +189,16 @@ const baseActions = { ( dimension ) => ! availableCustomDimensions?.includes( dimension ) ); + // If there are no missing custom dimensions, bail. + if ( ! missingCustomDimensions.length ) { + return; + } + + yield { + type: SET_CUSTOM_DIMENSIONS_BEING_CREATED, + payload: { customDimensions: missingCustomDimensions }, + }; + const propertyID = registry .select( MODULES_ANALYTICS_4 ) .getPropertyID(); @@ -204,42 +216,28 @@ const baseActions = { // Sync available custom dimensions. if ( missingCustomDimensions.length > 0 ) { - yield baseActions.syncAvailableCustomDimensions( propertyID ); + yield fetchSyncAvailableCustomDimensionsStore.actions.fetchSyncAvailableCustomDimensions(); } - }, - /** - * Syncs available custom dimensions in the settings. - * - * @since n.e.x.t - * - * @param {string} propertyID GA4 property ID. - * @return {Array} Available custom dimensions. - */ - syncAvailableCustomDimensions: createValidatedAction( - ( propertyID ) => { - invariant( - isValidPropertyID( propertyID ), - 'A valid GA4 propertyID is required.' - ); - }, - function* ( propertyID ) { - const registry = yield Data.commonActions.getRegistry(); - - const { response, error } = - yield fetchSyncAvailableCustomDimensionsStore.actions.fetchSyncAvailableCustomDimensions( - propertyID - ); - - if ( response ) { - registry - .dispatch( MODULES_ANALYTICS_4 ) - .setAvailableCustomDimensions( response ); - } + yield { + type: SET_CUSTOM_DIMENSIONS_BEING_CREATED, + payload: { customDimensions: [] }, + }; + }, +}; - return { response, error }; +export const baseReducer = ( state, { type, payload } ) => { + switch ( type ) { + case SET_CUSTOM_DIMENSIONS_BEING_CREATED: { + return { + ...state, + customDimensionsBeingCreated: payload.customDimensions, + }; } - ), + default: { + return state; + } + } }; const baseResolvers = { @@ -268,15 +266,7 @@ const baseResolvers = { return; } - const propertyID = registry - .select( MODULES_ANALYTICS_4 ) - .getPropertyID(); - - yield Data.commonActions.await( - registry - .dispatch( MODULES_ANALYTICS_4 ) - .syncAvailableCustomDimensions( propertyID ) - ); + yield fetchSyncAvailableCustomDimensionsStore.actions.fetchSyncAvailableCustomDimensions(); }, }; @@ -309,6 +299,57 @@ const baseSelectors = { ); } ), + + /** + * Checks whether the provided custom dimension is being created. + * + * @since n.e.x.t + * + * @param {Object} state Data store's state. + * @param {string} customDimension Custom dimensions to check. + * @return {boolean} True the provided custom dimension is being created, otherwise false. + */ + isCreatingCustomDimension( state, customDimension ) { + return !! state?.customDimensionsBeingCreated.includes( + customDimension + ); + }, + + /** + * Returns the error if encountered while creating the provided custom dimension. + * + * @since n.e.x.t + * + * @param {Object} state Data store's state. + * @param {string} customDimension Custom dimension to obtain creation error for. + * @return {(Object|undefined)} Error object if exists, otherwise undefined. + */ + getCreateCustomDimensionError: createRegistrySelector( + ( select ) => ( state, customDimension ) => { + const propertyID = select( MODULES_ANALYTICS_4 ).getPropertyID(); + + return select( MODULES_ANALYTICS_4 ).getErrorForAction( + 'createCustomDimension', + [ propertyID, possibleCustomDimensions[ customDimension ] ] + ); + } + ), + + /** + * Determines whether the available custom dimensions are being synced. + * + * @since n.e.x.t + * + * @param {Object} state Data store's state. + * @return {boolean} TRUE if the available custom dimensions are being synced, otherwise FALSE. + */ + isSyncingAvailableCustomDimensions: createRegistrySelector( + ( select ) => () => { + return select( + MODULES_ANALYTICS_4 + ).isFetchingSyncAvailableCustomDimensions(); + } + ), }; const store = Data.combineStores( @@ -318,6 +359,7 @@ const store = Data.combineStores( initialState: baseInitialState, actions: baseActions, resolvers: baseResolvers, + reducer: baseReducer, selectors: baseSelectors, } ); diff --git a/assets/js/modules/analytics-4/datastore/custom-dimensions.test.js b/assets/js/modules/analytics-4/datastore/custom-dimensions.test.js index a26947d5c8d..f23a2aa9d39 100644 --- a/assets/js/modules/analytics-4/datastore/custom-dimensions.test.js +++ b/assets/js/modules/analytics-4/datastore/custom-dimensions.test.js @@ -29,10 +29,11 @@ import { } from '../../../../../tests/js/utils'; import { CORE_USER, - KM_ANALYTICS_LEAST_ENGAGING_PAGES, - KM_ANALYTICS_PAGES_PER_VISIT, + KM_ANALYTICS_POPULAR_AUTHORS, + KM_ANALYTICS_TOP_CATEGORIES, } from '../../../googlesitekit/datastore/user/constants'; import { enabledFeatures } from '../../../features'; +import { provideCustomDimensionError } from '../utils/custom-dimensions'; describe( 'modules/analytics-4 custom-dimensions', () => { let registry; @@ -132,24 +133,12 @@ describe( 'modules/analytics-4 custom-dimensions', () => { } ); } ); - describe( 'syncAvailableCustomDimensions', () => { - it( 'requires a valid propertyID to be passed', () => { - expect( () => { - registry - .dispatch( MODULES_ANALYTICS_4 ) - .syncAvailableCustomDimensions(); - } ).toThrow( 'A valid GA4 propertyID is required.' ); - - expect( () => { - registry - .dispatch( MODULES_ANALYTICS_4 ) - .syncAvailableCustomDimensions( - 'not-valid-property-id' - ); - } ).toThrow( 'A valid GA4 propertyID is required.' ); - } ); + describe( 'fetchSyncAvailableCustomDimensions', () => { + it( 'fetches and returns custom dimensions', async () => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID, + } ); - it( 'fetches and returns custom dimensions for a valid propertyID', async () => { fetchMock.postOnce( new RegExp( '^/google-site-kit/v1/modules/analytics-4/data/sync-custom-dimensions' @@ -162,20 +151,13 @@ describe( 'modules/analytics-4 custom-dimensions', () => { const { response } = await registry .dispatch( MODULES_ANALYTICS_4 ) - .syncAvailableCustomDimensions( propertyID ); + .fetchSyncAvailableCustomDimensions(); expect( fetchMock ).toHaveFetchedTimes( 1 ); expect( fetchMock ).toHaveFetched( new RegExp( '^/google-site-kit/v1/modules/analytics-4/data/sync-custom-dimensions' - ), - { - body: { - data: { - propertyID, - }, - }, - } + ) ); expect( response ).toEqual( customDimensionNames ); } ); @@ -188,8 +170,8 @@ describe( 'modules/analytics-4 custom-dimensions', () => { const keyMetricsSettings = { widgetSlugs: [ - KM_ANALYTICS_LEAST_ENGAGING_PAGES, - KM_ANALYTICS_PAGES_PER_VISIT, + KM_ANALYTICS_POPULAR_AUTHORS, + KM_ANALYTICS_TOP_CATEGORIES, ], isWidgetHidden: false, }; @@ -419,5 +401,34 @@ describe( 'modules/analytics-4 custom-dimensions', () => { expect( hasCustomDimensions ).toBe( false ); } ); } ); + + describe( 'getCustomDimensionCreationError', () => { + it( 'gets error set in the datastore for the provided custom dimension', () => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID, + } ); + + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: 'test-error-reason', + }, + }; + + provideCustomDimensionError( registry, { + customDimension: 'googlesitekit_post_categories', + error, + } ); + + expect( + registry + .select( MODULES_ANALYTICS_4 ) + .getCreateCustomDimensionError( + 'googlesitekit_post_categories' + ) + ).toEqual( error ); + } ); + } ); } ); } ); diff --git a/assets/js/modules/analytics-4/index.js b/assets/js/modules/analytics-4/index.js index 05d44b16e12..3c4f082d3b3 100644 --- a/assets/js/modules/analytics-4/index.js +++ b/assets/js/modules/analytics-4/index.js @@ -35,6 +35,9 @@ import { VisitLengthWidget, TopReturningVisitorPages, VisitsPerVisitorWidget, + TopRecentTrendingPagesWidget, + TopCategoriesWidget, + PopularAuthorsWidget, } from './components/widgets'; import AnalyticsIcon from '../../../svg/graphics/analytics.svg'; import { MODULES_ANALYTICS_4 } from './datastore/constants'; @@ -47,11 +50,14 @@ import { KM_ANALYTICS_MOST_ENGAGING_PAGES, KM_ANALYTICS_NEW_VISITORS, KM_ANALYTICS_PAGES_PER_VISIT, + KM_ANALYTICS_POPULAR_AUTHORS, KM_ANALYTICS_POPULAR_CONTENT, KM_ANALYTICS_POPULAR_PRODUCTS, + KM_ANALYTICS_TOP_CATEGORIES, KM_ANALYTICS_TOP_CITIES, KM_ANALYTICS_TOP_CONVERTING_TRAFFIC_SOURCE, KM_ANALYTICS_TOP_COUNTRIES, + KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES, KM_ANALYTICS_TOP_RETURNING_VISITOR_PAGES, KM_ANALYTICS_TOP_TRAFFIC_SOURCE, KM_ANALYTICS_VISIT_LENGTH, @@ -319,5 +325,53 @@ export const registerWidgets = ( widgets ) => { }, [ AREA_MAIN_DASHBOARD_KEY_METRICS_PRIMARY ] ); + + widgets.registerWidget( + KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES, + { + Component: TopRecentTrendingPagesWidget, + width: widgets.WIDGET_WIDTHS.QUARTER, + priority: 1, + wrapWidget: false, + modules: [ 'analytics-4' ], + isActive: ( select ) => + select( CORE_USER ).isKeyMetricActive( + KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES + ), + }, + [ AREA_MAIN_DASHBOARD_KEY_METRICS_PRIMARY ] + ); + + widgets.registerWidget( + KM_ANALYTICS_TOP_CATEGORIES, + { + Component: TopCategoriesWidget, + width: widgets.WIDGET_WIDTHS.QUARTER, + priority: 1, + wrapWidget: false, + modules: [ 'analytics-4' ], + isActive: ( select ) => + select( CORE_USER ).isKeyMetricActive( + KM_ANALYTICS_TOP_CATEGORIES + ), + }, + [ AREA_MAIN_DASHBOARD_KEY_METRICS_PRIMARY ] + ); + + widgets.registerWidget( + KM_ANALYTICS_POPULAR_AUTHORS, + { + Component: PopularAuthorsWidget, + width: widgets.WIDGET_WIDTHS.QUARTER, + priority: 1, + wrapWidget: false, + modules: [ 'analytics-4' ], + isActive: ( select ) => + select( CORE_USER ).isKeyMetricActive( + KM_ANALYTICS_POPULAR_AUTHORS + ), + }, + [ AREA_MAIN_DASHBOARD_KEY_METRICS_PRIMARY ] + ); } }; diff --git a/assets/js/modules/analytics-4/utils/custom-dimensions.js b/assets/js/modules/analytics-4/utils/custom-dimensions.js new file mode 100644 index 00000000000..0b1edb8f923 --- /dev/null +++ b/assets/js/modules/analytics-4/utils/custom-dimensions.js @@ -0,0 +1,44 @@ +/** + * Site Kit by Google, Copyright 2023 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 { MODULES_ANALYTICS_4 } from '../datastore/constants'; +import { possibleCustomDimensions } from '../datastore/custom-dimensions'; + +/** + * Provides custom dimension error data to the given registry. + * + * @since n.e.x.t + * + * @param {Object} registry The registry to set up. + * @param {Object} options Error options. + * @param {string} options.customDimension The custom dimension slug. + * @param {Object} options.error The error object. + */ +export const provideCustomDimensionError = ( + registry, + { customDimension, error } +) => { + const propertyID = registry.select( MODULES_ANALYTICS_4 ).getPropertyID(); + + const options = [ propertyID, possibleCustomDimensions[ customDimension ] ]; + + registry + .dispatch( MODULES_ANALYTICS_4 ) + .receiveError( error, 'createCustomDimension', options ); +}; diff --git a/assets/js/modules/analytics-4/utils/withCustomDimensions.js b/assets/js/modules/analytics-4/utils/withCustomDimensions.js new file mode 100644 index 00000000000..5b2c214e97c --- /dev/null +++ b/assets/js/modules/analytics-4/utils/withCustomDimensions.js @@ -0,0 +1,383 @@ +/** + * `withCustomDimensions` HOC. + * + * Site Kit by Google, Copyright 2023 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. + */ + +/** + * External dependencies + */ +import { isFunction } from 'lodash'; + +/** + * WordPress dependencies + */ +import { + createInterpolateElement, + useCallback, + useEffect, + useMemo, +} from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { Button } from 'googlesitekit-components'; +import Data from 'googlesitekit-data'; +import { CORE_FORMS } from '../../../googlesitekit/datastore/forms/constants'; +import { CORE_LOCATION } from '../../../googlesitekit/datastore/location/constants'; +import { CORE_SITE } from '../../../googlesitekit/datastore/site/constants'; +import { CORE_USER } from '../../../googlesitekit/datastore/user/constants'; +import { EDIT_SCOPE as ANALYTICS_EDIT_SCOPE } from '../../analytics/datastore/constants'; +import { + FORM_CUSTOM_DIMENSIONS_CREATE, + MODULES_ANALYTICS_4, +} from '../datastore/constants'; +import { KEY_METRICS_WIDGETS } from '../../../components/KeyMetrics/key-metrics-widgets'; +import Link from '../../../components/Link'; +import MetricTileError from '../../../components/KeyMetrics/MetricTileError'; +import MetricTileWrapper from '../../../components/KeyMetrics/MetricTileWrapper'; +import { + ERROR_CODE_MISSING_REQUIRED_SCOPE, + ERROR_REASON_BAD_REQUEST, + isInsufficientPermissionsError, +} from '../../../util/errors'; +const { useSelect, useDispatch } = Data; + +export default function withCustomDimensions( options = {} ) { + const { dimensions, infoTooltip, reportOptions, title } = options; + + return ( WrappedComponent ) => { + const WithCustomDimensionsComponent = ( props ) => { + const { Widget, widgetSlug } = props; + const { + description, + infoTooltip: definedInfoTooltip, + requiredCustomDimensions, + title: definedTitle, + } = KEY_METRICS_WIDGETS[ widgetSlug ] || {}; + + const tileTitle = title || definedTitle; + const tileInfoTooltip = + infoTooltip || definedInfoTooltip || description; + + const customDimensions = useMemo( () => { + if ( Array.isArray( dimensions ) && dimensions.length ) { + return dimensions; + } + + if ( + Array.isArray( requiredCustomDimensions ) && + requiredCustomDimensions.length + ) { + return requiredCustomDimensions; + } + + return null; + }, [ requiredCustomDimensions ] ); + + const hasCustomDimensions = useSelect( + ( select ) => + ! customDimensions || + select( MODULES_ANALYTICS_4 ).hasCustomDimensions( + customDimensions + ) + ); + const isCreatingCustomDimensions = useSelect( + ( select ) => + !! customDimensions && + customDimensions.some( ( dimension ) => + select( MODULES_ANALYTICS_4 ).isCreatingCustomDimension( + dimension + ) + ) + ); + const customDimensionsCreationErrors = useSelect( ( select ) => { + if ( ! customDimensions ) { + return []; + } + + const errors = []; + + customDimensions.forEach( ( dimension ) => { + const error = + select( + MODULES_ANALYTICS_4 + ).getCreateCustomDimensionError( dimension ); + + if ( error ) { + errors.push( error ); + } + } ); + + return errors; + } ); + const helpLink = useSelect( + ( select ) => + !! customDimensionsCreationErrors.length && + select( CORE_SITE ).getErrorTroubleshootingLinkURL( + customDimensionsCreationErrors.find( + isInsufficientPermissionsError + ) || customDimensionsCreationErrors[ 0 ] + ) + ); + const hasAnalyticsEditScope = useSelect( + ( select ) => + !! customDimensions && + select( CORE_USER ).hasScope( ANALYTICS_EDIT_SCOPE ) + ); + const isSyncingAvailableCustomDimensions = useSelect( + ( select ) => + !! customDimensions && + select( + MODULES_ANALYTICS_4 + ).isSyncingAvailableCustomDimensions() + ); + const isNavigatingToOAuthURL = useSelect( ( select ) => { + const OAuthURL = select( CORE_USER ).getConnectURL( { + additionalScopes: [ ANALYTICS_EDIT_SCOPE ], + redirectURL: global.location.href, + } ); + + if ( ! OAuthURL ) { + return false; + } + + return select( CORE_LOCATION ).isNavigatingTo( OAuthURL ); + } ); + const reportError = useSelect( ( select ) => { + if ( ! reportOptions ) { + return null; + } + + const args = isFunction( reportOptions ) + ? reportOptions( select ) + : reportOptions; + + return select( MODULES_ANALYTICS_4 ).getErrorForSelector( + 'getReport', + [ args ] + ); + } ); + + const { fetchSyncAvailableCustomDimensions } = + useDispatch( MODULES_ANALYTICS_4 ); + const { setValues } = useDispatch( CORE_FORMS ); + const { setPermissionScopeError } = useDispatch( CORE_USER ); + + const loading = + isCreatingCustomDimensions || + isSyncingAvailableCustomDimensions || + isNavigatingToOAuthURL; + + const commonErrorProps = { + headerText: tileTitle, + infoTooltip: tileInfoTooltip, + }; + + const handleCreateCustomDimensions = useCallback( () => { + if ( loading ) { + return; + } + + setValues( FORM_CUSTOM_DIMENSIONS_CREATE, { + autoSubmit: true, + } ); + + if ( ! hasAnalyticsEditScope ) { + setPermissionScopeError( { + code: ERROR_CODE_MISSING_REQUIRED_SCOPE, + message: __( + 'Additional permissions are required to create new Analytics custom dimensions.', + 'google-site-kit' + ), + data: { + status: 403, + scopes: [ ANALYTICS_EDIT_SCOPE ], + skipModal: true, + }, + } ); + } + }, [ + hasAnalyticsEditScope, + loading, + setPermissionScopeError, + setValues, + ] ); + + // If the list of available custom dimensions is outdated, sync it. + useEffect( () => { + if ( + ! customDimensions || + reportError?.data?.reason !== ERROR_REASON_BAD_REQUEST || + isSyncingAvailableCustomDimensions + ) { + return; + } + + fetchSyncAvailableCustomDimensions(); + }, [ + customDimensions, + isSyncingAvailableCustomDimensions, + reportError, + fetchSyncAvailableCustomDimensions, + ] ); + + // Show loading state. + if ( !! customDimensions && loading ) { + return ( + + ); + } + + // Show error states. + if ( !! customDimensions && ! loading ) { + if ( !! customDimensionsCreationErrors.length ) { + // Handle permissions error encountered while creating + // custom dimensions. + if ( + customDimensionsCreationErrors.some( + isInsufficientPermissionsError + ) + ) { + return ( + +
+ + { createInterpolateElement( + __( + 'Permissions updated? Retry', + 'google-site-kit' + ), + { + a: ( + + ), + } + ) } + + + { createInterpolateElement( + __( + 'You’ll need to contact your administrator. Learn more', + 'google-site-kit' + ), + { + a: ( + + ), + } + ) } + +
+
+ ); + } + + // Handle generic errors encountered while creating + // custom dimensions. + return ( + +
+ + + { createInterpolateElement( + __( + 'Retry didn’t work? Learn more', + 'google-site-kit' + ), + { + a: ( + + ), + } + ) } + +
+
+ ); + } + + if ( ! hasCustomDimensions ) { + return ( + +
+ + + { __( + 'Update Analytics to track metric', + 'google-site-kit' + ) } + +
+
+ ); + } + } + + return ; + }; + + WithCustomDimensionsComponent.displayName = 'WithCustomDimensions'; + + if ( WrappedComponent.displayName || WrappedComponent.name ) { + WithCustomDimensionsComponent.displayName += `(${ + WrappedComponent.displayName || WrappedComponent.name + })`; + } + + return WithCustomDimensionsComponent; + }; +} diff --git a/assets/js/modules/analytics-4/utils/withCustomDimensions.test.js b/assets/js/modules/analytics-4/utils/withCustomDimensions.test.js new file mode 100644 index 00000000000..3ff40d5a2a5 --- /dev/null +++ b/assets/js/modules/analytics-4/utils/withCustomDimensions.test.js @@ -0,0 +1,123 @@ +/** + * `withCustomDimensions` HOC tests. + * + * Site Kit by Google, Copyright 2023 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 { + createTestRegistry, + provideUserAuthentication, + provideUserCapabilities, + render, +} from '../../../../../tests/js/test-utils'; +import { provideCustomDimensionError } from '../utils/custom-dimensions'; +import { ERROR_REASON_INSUFFICIENT_PERMISSIONS } from '../../../util/errors'; +import { MODULES_ANALYTICS_4 } from '../datastore/constants'; +import withCustomDimensions from './withCustomDimensions'; + +describe( 'withCustomDimensions', () => { + let registry; + const customDimension = 'test_custom_dimension'; + const TestComponent = () =>
; + const WithCustomDimensionsComponent = withCustomDimensions( { + dimensions: [ customDimension ], + } )( TestComponent ); + + beforeEach( () => { + registry = createTestRegistry(); + provideUserAuthentication( registry ); + provideUserCapabilities( registry ); + } ); + + it( 'renders appropriate error if required custom dimensions are not available', () => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID: '123456789', + availableCustomDimensions: [], + } ); + + const { container } = render( , { + registry, + } ); + + expect( container ).toHaveTextContent( + 'Update Analytics to track metric' + ); + } ); + + it( 'renders appropriate error if creating custom dimensions failed due to insufficient permissions', () => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID: '123456789', + availableCustomDimensions: [], + } ); + + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: ERROR_REASON_INSUFFICIENT_PERMISSIONS, + }, + }; + + provideCustomDimensionError( registry, { + customDimension, + error, + } ); + + const { container } = render( , { + registry, + } ); + + expect( container ).toHaveTextContent( 'Insufficient permissions' ); + } ); + + it( 'renders appropriate error if creating custom dimensions failed due to a generic error', () => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID: '123456789', + availableCustomDimensions: [], + } ); + + const error = { + code: 'test-error-code', + message: 'Test error message', + data: { + reason: 'test-error-reason', + }, + }; + + provideCustomDimensionError( registry, { + customDimension, + error, + } ); + + const { container } = render( , { + registry, + } ); + + expect( container ).toHaveTextContent( 'Analytics update failed' ); + } ); + + it( 'renders report correctly if there are no errors', () => { + registry.dispatch( MODULES_ANALYTICS_4 ).setSettings( { + propertyID: '123456789', + availableCustomDimensions: [ customDimension ], + } ); + + const { queryByTestID } = render( , { + registry, + } ); + + expect( queryByTestID( 'component' ) ).toBeInTheDocument(); + } ); +} ); diff --git a/assets/js/util/errors.js b/assets/js/util/errors.js index c4a8e7946c2..d61f8de4b21 100644 --- a/assets/js/util/errors.js +++ b/assets/js/util/errors.js @@ -32,6 +32,7 @@ export const ERROR_REASON_INSUFFICIENT_PERMISSIONS = 'insufficientPermissions'; export const ERROR_REASON_FORBIDDEN = 'forbidden'; export const ERROR_INTERNAL_SERVER_ERROR = 'internal_server_error'; export const ERROR_INVALID_JSON = 'invalid_json'; +export const ERROR_REASON_BAD_REQUEST = 'bad_request'; /** * Checks if the provided object is an instance of WP_Error class. diff --git a/assets/sass/components/key-metrics/_googlesitekit-km-widget-tile.scss b/assets/sass/components/key-metrics/_googlesitekit-km-widget-tile.scss index 6504c866f74..c86fb380967 100644 --- a/assets/sass/components/key-metrics/_googlesitekit-km-widget-tile.scss +++ b/assets/sass/components/key-metrics/_googlesitekit-km-widget-tile.scss @@ -176,9 +176,14 @@ background: $c-white; border: 2px solid $c-utility-on-error-container; + .googlesitekit-cta__header { + column-gap: $grid-gap-phone / 2; + display: flex; + flex-basis: 50%; + } + .googlesitekit-cta__header_text { color: $c-neutral-n-500; - flex-basis: 50%; font-family: $f-primary; font-size: $fs-label-sm; font-weight: $fw-normal; @@ -205,17 +210,20 @@ margin: 0; } - button, + button:not(.googlesitekit-cta-link), a.mdc-button { font-weight: $fw-medium; margin-top: 10px; padding: 6px 16px; } + .googlesitekit-cta-link { + color: $c-teal-t-500; + } + // Removes the external link icon. .googlesitekit-cta-link--external { background: none; - color: $c-teal-t-500; padding-right: 0; } } diff --git a/includes/Modules/Analytics_4.php b/includes/Modules/Analytics_4.php index a0384ada847..ab3bee71c23 100644 --- a/includes/Modules/Analytics_4.php +++ b/includes/Modules/Analytics_4.php @@ -893,12 +893,12 @@ protected function create_data_request( Data_Request $data ) { $custom_dimension ); case 'POST:sync-custom-dimensions': - if ( ! isset( $data['propertyID'] ) ) { + $settings = $this->get_settings()->get(); + if ( empty( $settings['propertyID'] ) ) { return new WP_Error( - 'missing_required_param', - /* translators: %s: Missing parameter name */ - sprintf( __( 'Request parameter is empty: %s.', 'google-site-kit' ), 'propertyID' ), - array( 'status' => 400 ) + 'missing_required_setting', + __( 'No connected Google Analytics 4 property ID.', 'google-site-kit' ), + array( 'status' => 500 ) ); } @@ -906,7 +906,7 @@ protected function create_data_request( Data_Request $data ) { return $analyticsadmin ->properties_customDimensions // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - ->listPropertiesCustomDimensions( self::normalize_property_id( $data['propertyID'] ) ); + ->listPropertiesCustomDimensions( self::normalize_property_id( $settings['propertyID'] ) ); case 'GET:webdatastreams': if ( ! isset( $data['propertyID'] ) ) { return new WP_Error( diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_0_small.png index a8ab073e570..a7b989c4933 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_1_medium.png index 354382e88b7..8d605842bb3 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_2_large.png index 986cfd9fb38..bacfe98b3e2 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_0_small.png index f9f7ff97580..c3a934eb99e 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_1_medium.png index 877b2f68fa1..68bbd6cf6ce 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_2_large.png index 039f57038f5..461fed77a8a 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_EngagedTrafficSource_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_0_small.png index 9298fb2cec7..3b5c899b770 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_1_medium.png index ff56ecd3bd8..e3a1c7af66f 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_2_large.png index f9ca49a8e34..e09c1b5b548 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_0_small.png index 59d03931c92..dcd536bc511 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_1_medium.png index 1dd9880afc3..7c55c4683c8 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_2_large.png index 1bd53d4506c..3a21489df83 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LeastEngagingPagesWidget_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_0_small.png index 45bc0aef247..472784d208a 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_1_medium.png index a8b295353ab..1a6f36eb1df 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_2_large.png index 534e3d714ae..3c7e694bec7 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_0_small.png index 4a8c44521a3..308177e0af1 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_1_medium.png index 8c703461e48..09ca08eeeff 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_2_large.png index 84e463d14f3..9ca0aa6c4c7 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_LoyalVisitors_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_0_small.png index 1c039a7a7a1..8e5284a1e5a 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_1_medium.png index e3ac7af017c..b3aa255a953 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_2_large.png index d154b0bb3f9..1714e760a7a 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_0_small.png index 275e0ea6809..2dc046348a1 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_1_medium.png index f05156afa83..93b78ffcb44 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_2_large.png index 8a5cd274f37..926ef1085f1 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_MostEngagingPagesWidget_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_0_small.png index c4ec4b04384..173a9f6a635 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_1_medium.png index 4472229040a..d9c7ecf40ff 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_2_large.png index 78197e598c8..a9f52ee445f 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_0_small.png index 70fcd59317f..456d025134e 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_1_medium.png index 870369f6ef8..d523a0286d6 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_2_large.png index e7a66e93aba..53f9cb49f35 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_NewVisitors_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_0_small.png index 65447ecee4b..fb7c3a75c65 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_1_medium.png index ddd6dc2f79d..b6759ce656f 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_2_large.png index c63dcec7bae..f13b2790d7a 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_0_small.png index 59be446bf53..c0633b51660 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_1_medium.png index 2ab2a9ee2ac..8335a176a34 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_2_large.png index e2fbdae9e76..f7cdaaa5f27 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PagesPerVisit_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_0_small.png index 039cdc89596..a1e4afd1bf8 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_1_medium.png index c4c5ebe9071..4a04a5337fa 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_2_large.png index 752b76d414a..582abe99cbe 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_0_small.png index b6e4f7e586f..f7fb2afc8c8 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_1_medium.png index c8b0f7dc069..2a8993e2fd0 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_2_large.png index df6efa4d34a..a141deaaa2b 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularContent_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_0_small.png index bcf38ba792f..521f94f1cb0 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_1_medium.png index 57cb57a28bf..049a04fb573 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_2_large.png index d16cd5888d9..bc303c38cda 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_0_small.png index 987b4dd43a8..a2e6edae17f 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_1_medium.png index 8b656d6eaa8..d3553673ad3 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_2_large.png index 012145824ce..71731ba5768 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularKeywords_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_0_small.png index 9fe8bdd8749..ad4ab29ef90 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_1_medium.png index 61ccc409ba8..c85c444625c 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_2_large.png index bfebab9f71b..00f4dde0514 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_0_small.png index f5a1a6b2625..995e6c82c2e 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_1_medium.png index 4ad9589cb98..b370d732b9c 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_2_large.png index 73099f120c8..64eefabca99 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_PopularProducts_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_0_small.png index 236f16c7211..bbc2e9bc39a 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_1_medium.png index ab538665b8c..d9f763eca8d 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_2_large.png index 9c2b3486bf6..7fae7d64e09 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_0_small.png index 8934d2c6be2..d4aae729472 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_1_medium.png index 2a7747382d6..21baedf5bba 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_2_large.png index 81185b47921..fc1b4be2837 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCitiesWidget_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_0_small.png index ff1a6d91756..8866f617dd7 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_1_medium.png index 5bc0ad4423a..422115d138f 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_2_large.png index 7a5f4632d53..f0a2a7997f7 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_0_small.png index 298ea3b2076..9f46e4818f5 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_1_medium.png index 85505707dd7..3f51b362c42 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_2_large.png index aca5c652ab6..1404d57c4bf 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopConvertingTrafficSource_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_0_small.png index a7068922e35..8105b31230e 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_1_medium.png index 0d1d739a96f..9c99568db43 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_2_large.png index cb9899d698c..ba62f6ea99c 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_0_small.png index e6fda31c1e8..adadd6746d0 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_1_medium.png index c3f15f2b2cb..cc9b3735f0d 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_2_large.png index f443c33b7e1..0ef919bfdb4 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopCountriesWidget_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_0_small.png index 2f2f00c7d06..070c32b06fa 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_1_medium.png index 8377b9c5f12..7292ebd5982 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_2_large.png index 765b16eccb9..bdd9455f777 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_0_small.png index d75e99bd65a..ff99482f984 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_1_medium.png index c56c22ec528..8696cc02b8f 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_2_large.png index 1d82a1cf6f8..a7a5a7e035b 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopReturningVisitorPages_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_0_small.png index 71708c34bc2..89361eeee14 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_1_medium.png index 27f7f16624a..c4d0db702fb 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_2_large.png index e6633d67782..a241adce537 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_0_small.png index 0f523088d99..525e35dfcb3 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_1_medium.png index 6f5c2b89d44..138b0df2a4e 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_2_large.png index e437b218f8a..3b0f83dc22c 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopTrafficSource_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_0_small.png index 360a3027a1a..1f91fbf10fd 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_1_medium.png index e7d6270b7a1..b48106cbe74 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_2_large.png index f49286fa461..f3d4042527d 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_0_small.png index 389a6d32b8a..773278f2e47 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_1_medium.png index 060212e40d8..c5a17ddd184 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_2_large.png index 82db82c586f..74167d25507 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitLength_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_0_small.png index 6bae81e1343..88f10fe83be 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_1_medium.png index 3e18b19e274..9cff9bc2f2a 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_2_large.png index f54d79d3d99..28df6b699b1 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_Error_0_document_2_large.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_0_small.png index 43eac617666..2b2eb6b55c2 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_0_small.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_0_small.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_1_medium.png index 782b2469d4a..6fe7cef8cdf 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_1_medium.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_1_medium.png differ diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_2_large.png index 300a41b6a55..4ed8798a9a4 100644 Binary files a/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_2_large.png and b/tests/backstop/reference/google-site-kit_KeyMetrics_VisitsPerVisitor_InsufficientPermissions_0_document_2_large.png differ diff --git a/tests/phpunit/integration/Modules/Analytics_4Test.php b/tests/phpunit/integration/Modules/Analytics_4Test.php index c3d3431f61e..7f49f7027ca 100644 --- a/tests/phpunit/integration/Modules/Analytics_4Test.php +++ b/tests/phpunit/integration/Modules/Analytics_4Test.php @@ -2406,31 +2406,16 @@ public function test_create_custom_dimension() { $this->assertEquals( "/v1beta/properties/$property_id/customDimensions", $request_url['path'] ); } - public function test_sync_custom_dimensions__required_params() { - $this->enable_feature( 'newsKeyMetrics' ); - // Grant READONLY_SCOPE so request doesn't fail. - $this->authentication->get_oauth_client()->set_granted_scopes( - array_merge( - $this->authentication->get_oauth_client()->get_required_scopes(), - (array) Analytics::READONLY_SCOPE - ) - ); - - $data = $this->analytics->set_data( - 'sync-custom-dimensions', - array() - ); - - // Verify that the propertyID is required. - $this->assertWPErrorWithMessage( 'Request parameter is empty: propertyID.', $data ); - $this->assertEquals( 'missing_required_param', $data->get_error_code() ); - $this->assertEquals( array( 'status' => 400 ), $data->get_error_data( 'missing_required_param' ) ); - } - public function test_sync_custom_dimensions() { $this->enable_feature( 'newsKeyMetrics' ); $property_id = 'sync-custom-dimension-property-id'; + $this->analytics->get_settings()->merge( + array( + 'propertyID' => $property_id, + ) + ); + FakeHttp::fake_google_http_handler( $this->analytics->get_client(), $this->create_sync_custom_dimensions_fake_http_handler( $property_id ) @@ -2446,9 +2431,7 @@ public function test_sync_custom_dimensions() { $response = $this->analytics->set_data( 'sync-custom-dimensions', - array( - 'propertyID' => $property_id, - ) + array() ); $this->assertNotWPError( $response );