Skip to content

Commit

Permalink
Allow entering GA4 measurement IDs (#13403)
Browse files Browse the repository at this point in the history
  • Loading branch information
swissspidy committed Jun 28, 2023
1 parent c6ca1eb commit 2244ab7
Show file tree
Hide file tree
Showing 13 changed files with 332 additions and 80 deletions.
40 changes: 26 additions & 14 deletions packages/design-system/src/components/banner/banner.tsx
Expand Up @@ -47,26 +47,34 @@ const CloseButton = styled(Button)`
align-self: flex-start;
`;

const CloseButtonPlaceholder = styled.div`
grid-area: closeButton;
justify-self: end;
align-self: flex-start;
width: 32px;
height: 32px;
`;

const Container = styled.div`
display: grid;
width: 100%;
min-height: 60px;
grid-template-columns: 104px 1fr auto;
grid-column-gap: 32px;
grid-template-areas: 'title content closeButton';
align-items: baseline;
padding: 6px 8px;
background-color: ${({ theme }) => theme.colors.gray[5]};
border-radius: ${({ theme }) => theme.borders.radius.medium};
max-height: 184px;
border-radius: 0;
grid-template-columns: 1fr 32px;
grid-template-rows: 3;
grid-column-gap: 0;
grid-template-areas: '. closeButton' 'title title' 'content content';
text-align: center;
& + & {
margin-top: 18px;
}
${Title} {
padding-left: 0;
margin-top: -10px;
Expand All @@ -80,7 +88,7 @@ const Container = styled.div`
interface BannerProps {
closeButtonLabel: string;
title: string;
onClose: () => void;
onClose?: () => void;
}

const Banner = forwardRef(
Expand All @@ -99,15 +107,19 @@ const Banner = forwardRef(
<Title as="h2" size={TextSize.XSmall}>
{title}
</Title>
<CloseButton
type={ButtonType.Tertiary}
variant={ButtonVariant.Square}
size={ButtonSize.Small}
aria-label={closeButtonLabel}
onClick={onClose}
>
<Cross aria-hidden />
</CloseButton>
{onClose ? (
<CloseButton
type={ButtonType.Tertiary}
variant={ButtonVariant.Square}
size={ButtonSize.Small}
aria-label={closeButtonLabel}
onClick={onClose}
>
<Cross aria-hidden />
</CloseButton>
) : (
<CloseButtonPlaceholder />
)}
<Content>{children}</Content>
</Container>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/e2e-test-utils/src/setAnalyticsCode.js
Expand Up @@ -23,7 +23,7 @@ async function setAnalyticsCode(code) {
await visitSettings();

const inputSelector =
'input[placeholder^="Enter your Google Analytics Tracking ID"]';
'input[placeholder^="Enter your Google Analytics Measurement ID"]';

await expect(page).toMatchElement(inputSelector);
await page.evaluate(() => {
Expand Down
Expand Up @@ -19,7 +19,8 @@
*/
import { visitSettings } from '@web-stories-wp/e2e-test-utils';

const INPUT_SELECTOR = '[aria-label="Enter your Google Analytics Tracking ID"]';
const INPUT_SELECTOR =
'[aria-label="Enter your Google Analytics Measurement ID"]';

jest.retryTimes(3, { logErrorsBeforeRetry: true });

Expand Down
2 changes: 1 addition & 1 deletion packages/e2e-tests/src/specs/wordpress/adminMenu.js
Expand Up @@ -90,6 +90,6 @@ describe('Admin Menu', () => {
page.waitForNavigation(),
]);

await expect(page).toMatchTextContent('Google Analytics Tracking ID');
await expect(page).toMatchTextContent('Google Analytics Measurement ID');
});
});
2 changes: 1 addition & 1 deletion packages/tracking/src/shared.ts
Expand Up @@ -84,7 +84,7 @@ interface TrackingConfig {
*/
trackingEnabled?: boolean;
/**
* GA4 tracking ID.
* GA4 measurement ID.
*/
trackingIdGA4: string;
/**
Expand Down
Expand Up @@ -31,6 +31,9 @@ import {
ButtonType,
TextSize,
NotificationBubble,
Icons,
Text,
Link,
} from '@googleforcreators/design-system';
import styled from 'styled-components';

Expand Down Expand Up @@ -63,8 +66,8 @@ export const TEXT = {
CONTEXT_LINK:
'https://blog.amp.dev/2019/08/28/analytics-for-your-amp-stories/',
SECTION_HEADING: __('Google Analytics', 'web-stories'),
PLACEHOLDER: __('Enter your Google Analytics Tracking ID', 'web-stories'),
ARIA_LABEL: __('Enter your Google Analytics Tracking ID', 'web-stories'),
PLACEHOLDER: __('Enter your Google Analytics Measurement ID', 'web-stories'),
ARIA_LABEL: __('Enter your Google Analytics Measurement ID', 'web-stories'),
INPUT_ERROR: __('Invalid ID format', 'web-stories'),
SUBMIT_BUTTON: __('Save', 'web-stories'),
SITE_KIT_NOT_INSTALLED: __(
Expand All @@ -81,6 +84,27 @@ export const TEXT = {
),
};

const WarningContainer = styled.div`
display: flex;
gap: 8px;
margin: 14px auto;
border: 1px solid ${({ theme }) => theme.colors.border.defaultNormal};
border-radius: ${({ theme }) => theme.borders.radius.small};
padding: 8px;
`;

const WarningIcon = styled(Icons.ExclamationOutline)`
width: 32px;
height: 100%;
color: ${({ theme }) => theme.colors.status.warning};
`;

const Message = styled(Text.Paragraph).attrs({
size: TextSize.Small,
})`
max-width: calc(100% - 40px);
`;

function GoogleAnalyticsSettings({
googleAnalyticsId,
handleUpdateAnalyticsId,
Expand Down Expand Up @@ -222,57 +246,99 @@ function GoogleAnalyticsSettings({
</>
)}
</div>
{analyticsActive ? (
<div>
<div>
{analyticsActive ? (
<TextInputHelperText size={TextSize.Small}>
{TEXT.SITE_KIT_IN_USE}
</TextInputHelperText>
</div>
) : (
<div>
<InlineForm>
<VisuallyHiddenLabel htmlFor="gaTrackingId">
{TEXT.ARIA_LABEL}
</VisuallyHiddenLabel>
<SettingsTextInput
aria-label={TEXT.ARIA_LABEL}
id="gaTrackingId"
value={analyticsId}
onChange={onUpdateAnalyticsId}
onKeyDown={handleOnKeyDown}
placeholder={TEXT.PLACEHOLDER}
hasError={Boolean(inputError)}
hint={inputError}
disabled={analyticsActive}
/>
<SaveButton
type={ButtonType.Secondary}
size={ButtonSize.Small}
disabled={disableSaveButton}
onClick={handleOnSave}
>
{TEXT.SUBMIT_BUTTON}
</SaveButton>
</InlineForm>
<TextInputHelperText size={TextSize.Small}>
<TranslateWithMarkup
mapping={{
a: (
<InlineLink
href={TEXT.CONTEXT_LINK}
rel="noreferrer"
target="_blank"
size={TextSize.Small}
onClick={onContextClick}
/>
),
}}
>
{TEXT.CONTEXT}
</TranslateWithMarkup>
</TextInputHelperText>
</div>
)}
) : (
<>
<InlineForm>
<VisuallyHiddenLabel htmlFor="gaTrackingId">
{TEXT.ARIA_LABEL}
</VisuallyHiddenLabel>
<SettingsTextInput
aria-label={TEXT.ARIA_LABEL}
id="gaTrackingId"
value={analyticsId}
onChange={onUpdateAnalyticsId}
onKeyDown={handleOnKeyDown}
placeholder={TEXT.PLACEHOLDER}
hasError={Boolean(inputError)}
hint={inputError}
disabled={analyticsActive}
/>
<SaveButton
type={ButtonType.Secondary}
size={ButtonSize.Small}
disabled={disableSaveButton}
onClick={handleOnSave}
>
{TEXT.SUBMIT_BUTTON}
</SaveButton>
</InlineForm>
<TextInputHelperText size={TextSize.Small}>
<TranslateWithMarkup
mapping={{
a: (
<InlineLink
href={TEXT.CONTEXT_LINK}
rel="noreferrer"
target="_blank"
size={TextSize.Small}
onClick={onContextClick}
/>
),
}}
>
{TEXT.CONTEXT}
</TranslateWithMarkup>
</TextInputHelperText>
{!googleAnalyticsId || googleAnalyticsId.startsWith('UA-') ? (
<WarningContainer>
<WarningIcon aria-hidden />
<Message>
<TranslateWithMarkup
mapping={{
a: (
<Link
href={__(
'https://support.google.com/analytics/answer/11583528?hl=en',
'web-stories'
)}
rel="noreferrer"
target="_blank"
size={TextSize.Small}
onClick={(evt) =>
trackClick(evt, 'click_ua_deprecation_docs')
}
/>
),
a2: (
<Link
href={__(
'https://support.google.com/analytics/answer/10089681?hl=en',
'web-stories'
)}
rel="noreferrer"
target="_blank"
size={TextSize.Small}
onClick={(evt) => trackClick(evt, 'click_ga4_docs')}
/>
),
}}
>
{__(
'As <a>previously announced</a>, Universal Analytics will stop processing new visits starting <b>July 1, 2023</b>. We recommend switching to <a2>Google Analytics 4</a2> (GA4), our analytics product of record.',
'web-stories'
)}
</TranslateWithMarkup>
</Message>
</WarningContainer>
) : null}
</>
)}
</div>
</SettingForm>
);
}
Expand Down
Expand Up @@ -225,7 +225,7 @@ describe('Editor Settings: <Editor Settings />', () => {
expect(googleAnalyticsHeading).toBeInTheDocument();

const input = screen.getByRole('textbox', {
name: 'Enter your Google Analytics Tracking ID',
name: 'Enter your Google Analytics Measurement ID',
});
expect(input).toBeInTheDocument();

Expand Down
Expand Up @@ -27,13 +27,13 @@ const idsToValidate = [
['78787878', false],
['ua--123448-0', false],
['clearly wrong', false],
['G-9878987', false],
['g-9878987', false],
['G-1A2BCD345E', false],
['G-9878987', true],
['g-9878987', true],
['G-1A2BCD345E', true],
['X-8888888', false],
['G-123456', false],
['G-12345678', false],
['G-abcdefg8910', false],
['G-123456', true],
['G-12345678', true],
['G-abcdefg8910', true],
];

describe('validateGoogleAnalyticsIdFormat', () => {
Expand Down
Expand Up @@ -14,9 +14,7 @@
* limitations under the License.
*/

// GA4 measurement ID format is not yet supported in AMP.
// See https://github.com/googleforcreators/web-stories-wp/issues/6479
const idFormatRegex = /^ua-\d+-\d+$/;
const idFormatRegex = /^ua-\d+-\d+|g-\w+$/;

export default function validateGoogleAnalyticsIdFormat(value = '') {
return Boolean(value.toLowerCase().match(idFormatRegex));
Expand Down

0 comments on commit 2244ab7

Please sign in to comment.