Skip to content

Commit

Permalink
Split banner and epic factories (#194)
Browse files Browse the repository at this point in the history
* Split the BrazeMessageComponent factory in two

Now we have two factory components, one per slot. This has the advantage
of having to only pass in the set of props that we might need for the
components for a given slot. So we now no longer need to pass subscribe
ToNewsletter to the banner component factory, as none of the underlying
components require it.

I also removed some unused props from the common end of article props
interface which weren’t used by any of the underlying components.

* We need to export these to be used by the platform

Co-authored-by: Michael Clapham <[email protected]>
  • Loading branch information
tjmw and michaelclapham authored Jul 26, 2021
1 parent 0716ff7 commit 5ffdb35
Show file tree
Hide file tree
Showing 16 changed files with 50 additions and 128 deletions.
10 changes: 2 additions & 8 deletions src/AUNewsletterEpic/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { ReactElement } from 'react';
import { BrazeMessageComponent } from '../BrazeMessageComponent';
import { BrazeEndOfArticleComponent } from '../BrazeMessageComponent';
import { StorybookWrapper } from '../utils/StorybookWrapper';
import { withKnobs, text } from '@storybook/addon-knobs';

Expand Down Expand Up @@ -28,14 +28,8 @@ export const defaultStory = (): ReactElement | null => {

return (
<StorybookWrapper>
<BrazeMessageComponent
<BrazeEndOfArticleComponent
componentName={componentName}
logButtonClickWithBraze={(internalButtonId) => {
console.log(`Button with internal ID ${internalButtonId} clicked`);
}}
submitComponentEvent={(componentEvent) => {
console.log('submitComponentEvent called with: ', componentEvent);
}}
brazeMessageProps={{
header,
frequency,
Expand Down
4 changes: 0 additions & 4 deletions src/AUNewsletterEpic/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from 'react';
import { canRender, COMPONENT_NAME } from './canRender';
import { NewsletterEpic, NewsletterSubscribeCallback } from '../NewsletterEpic';
import { BrazeClickHandler } from '../utils/tracking';
import { OphanComponentEvent } from '@guardian/types';

const IMAGE_URL =
'https://i.guim.co.uk/img/media/9f9f9c06ed5a323b13be816d5c160728c81d1bf9/0_0_784_784/784.png?width=196&s=4c4d5ff2c20821a6e6ff4d25f8ebcc16';
Expand All @@ -18,8 +16,6 @@ export type BrazeMessageProps = {
};

export type Props = {
logButtonClickWithBraze: BrazeClickHandler;
submitComponentEvent: (componentEvent: OphanComponentEvent) => void;
brazeMessageProps: BrazeMessageProps;
subscribeToNewsletter: NewsletterSubscribeCallback;
};
Expand Down
5 changes: 2 additions & 3 deletions src/AppBanner/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { ReactElement } from 'react';
import { withKnobs, text } from '@storybook/addon-knobs';
import { BrazeMessageComponent } from '../BrazeMessageComponent';
import { BrazeBannerComponent } from '../BrazeMessageComponent';
import { StorybookWrapper } from '../utils/StorybookWrapper';
import { knobsData } from '../utils/knobsData';
import { withGrid, grid } from '../../.storybook/grid/withGrid';
Expand Down Expand Up @@ -38,7 +38,7 @@ export const defaultStory = (): ReactElement => {

return (
<StorybookWrapper>
<BrazeMessageComponent
<BrazeBannerComponent
componentName={componentName}
logButtonClickWithBraze={(internalButtonId) => {
console.log(`Button with internal ID ${internalButtonId} clicked`);
Expand All @@ -52,7 +52,6 @@ export const defaultStory = (): ReactElement => {
imageUrl,
cta,
}}
subscribeToNewsletter={() => Promise.resolve()}
/>
</StorybookWrapper>
);
Expand Down
20 changes: 2 additions & 18 deletions src/BrazeMessageComponent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,7 @@ describe('BrazeMessage', () => {
};
const BrazeMessageComponent = buildBrazeMessageComponent(mappings);

render(
<BrazeMessageComponent
componentName={'ExampleComponent'}
logButtonClickWithBraze={jest.fn()}
submitComponentEvent={jest.fn()}
brazeMessageProps={{}}
subscribeToNewsletter={() => Promise.resolve()}
/>,
);
render(<BrazeMessageComponent componentName={'ExampleComponent'} />);

expect(ExampleComponent).toHaveBeenCalled();
});
Expand All @@ -34,15 +26,7 @@ describe('BrazeMessage', () => {
};
const BrazeMessageComponent = buildBrazeMessageComponent(mappings);

render(
<BrazeMessageComponent
componentName={'NoSuchComponent'}
logButtonClickWithBraze={jest.fn()}
submitComponentEvent={jest.fn()}
brazeMessageProps={{}}
subscribeToNewsletter={() => Promise.resolve()}
/>,
);
render(<BrazeMessageComponent componentName={'NoSuchComponent'} />);

expect(ExampleComponent).not.toHaveBeenCalled();
});
Expand Down
62 changes: 30 additions & 32 deletions src/BrazeMessageComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,65 +33,63 @@ type BrazeMessageProps = {
[key: string]: string | undefined;
};

type CommonComponentProps = {
export type CommonBannerComponentProps = {
componentName: string;
logButtonClickWithBraze: BrazeClickHandler;
submitComponentEvent: (componentEvent: OphanComponentEvent) => void;
brazeMessageProps: BrazeMessageProps;
countryCode?: string;
};

export type CommonEndOfArticleComponentProps = {
componentName: string;
brazeMessageProps: BrazeMessageProps;
subscribeToNewsletter: NewsletterSubscribeCallback;
countryCode?: string;
};

type ComponentMapping = {
[key: string]: React.FC<CommonComponentProps>;
type ComponentMapping<A> = {
[key: string]: React.FC<A>;
};

const COMPONENT_MAPPINGS: ComponentMapping = {
const BANNER_MAPPINGS: ComponentMapping<CommonBannerComponentProps> = {
[DIGITAL_SUBSCRIBER_APP_BANNER_NAME]: DigitalSubscriberAppBanner,
[APP_BANNER_NAME]: AppBanner,
[SPECIAL_EDITION_BANNER_NAME]: SpecialEditionBanner,
[THE_GUARDIAN_IN_2020_BANNER_NAME]: TheGuardianIn2020Banner,
};

const END_OF_ARTICLE_MAPPINGS: ComponentMapping<CommonEndOfArticleComponentProps> = {
[NEWSLETTER_EPIC_NAME]: NewsletterEpic,
[US_NEWSLETTER_EPIC_NAME]: USNewsletterEpic,
[AU_NEWSLETTER_EPIC_NAME]: AUNewsletterEpic,
[UK_NEWSLETTER_EPIC_NAME]: UKNewsletterEpic,
[EPIC_NAME]: Epic,
};

export type Props = {
interface HasComponentName {
componentName: string;
logButtonClickWithBraze: BrazeClickHandler;
submitComponentEvent: (componentEvent: OphanComponentEvent) => void;
brazeMessageProps: BrazeMessageProps;
subscribeToNewsletter: (newsletterId: string) => Promise<void>;
};
}

export const buildBrazeMessageComponent = (mappings: ComponentMapping): React.FC<Props> => {
const BrazeMessageComponent = ({
logButtonClickWithBraze,
submitComponentEvent,
componentName,
brazeMessageProps,
subscribeToNewsletter,
}: Props) => {
const ComponentToRender = mappings[componentName];
export function buildBrazeMessageComponent<A extends HasComponentName>(
mappings: ComponentMapping<A>,
): React.FC<A> {
const BrazeMessageComponent = (props: A) => {
const ComponentToRender = mappings[props.componentName];

if (!ComponentToRender) {
return null;
}

return (
<ComponentToRender
logButtonClickWithBraze={logButtonClickWithBraze}
submitComponentEvent={submitComponentEvent}
subscribeToNewsletter={subscribeToNewsletter}
brazeMessageProps={brazeMessageProps}
/>
);
return <ComponentToRender {...props} />;
};

return BrazeMessageComponent;
};
}

export const BrazeBannerComponent: React.FC<CommonBannerComponentProps> = buildBrazeMessageComponent<
CommonBannerComponentProps
>(BANNER_MAPPINGS);

export const BrazeMessageComponent: React.FC<Props> = buildBrazeMessageComponent(
COMPONENT_MAPPINGS,
);
export const BrazeEndOfArticleComponent: React.FC<CommonEndOfArticleComponentProps> = buildBrazeMessageComponent<
CommonEndOfArticleComponentProps
>(END_OF_ARTICLE_MAPPINGS);
5 changes: 2 additions & 3 deletions src/DigitalSubscriberAppBanner/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { ReactElement } from 'react';
import { withKnobs, text } from '@storybook/addon-knobs';
import { BrazeMessageComponent } from '../BrazeMessageComponent';
import { BrazeBannerComponent } from '../BrazeMessageComponent';
import { StorybookWrapper } from '../utils/StorybookWrapper';
import { knobsData } from '../utils/knobsData';

Expand All @@ -26,7 +26,7 @@ export const defaultStory = (): ReactElement => {
return (
<StorybookWrapper>
<>
<BrazeMessageComponent
<BrazeBannerComponent
componentName={componentName}
logButtonClickWithBraze={(internalButtonId) => {
console.log(`Button with internal ID ${internalButtonId} clicked`);
Expand All @@ -38,7 +38,6 @@ export const defaultStory = (): ReactElement => {
header: header,
body: body,
}}
subscribeToNewsletter={() => Promise.resolve()}
/>
</>
</StorybookWrapper>
Expand Down
13 changes: 4 additions & 9 deletions src/Epic/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { ReactElement } from 'react';
import { withKnobs, text } from '@storybook/addon-knobs';
import { StorybookWrapper } from '../utils/StorybookWrapper';
import { BrazeMessageComponent } from '../BrazeMessageComponent';
import { BrazeEndOfArticleComponent } from '../BrazeMessageComponent';

export default {
component: 'Epic',
Expand Down Expand Up @@ -58,7 +58,7 @@ export const defaultStory = (): ReactElement | null => {

return (
<StorybookWrapper>
<BrazeMessageComponent
<BrazeEndOfArticleComponent
brazeMessageProps={{
slotName,
ophanComponentId,
Expand All @@ -69,13 +69,8 @@ export const defaultStory = (): ReactElement | null => {
...paragraphMap,
}}
componentName={componentName}
logButtonClickWithBraze={(internalButtonId) => {
console.log(`Button with internal ID ${internalButtonId} clicked`);
}}
submitComponentEvent={(componentEvent) => {
console.log('submitComponentEvent called with: ', componentEvent);
}}
></BrazeMessageComponent>
subscribeToNewsletter={() => Promise.resolve()}
/>
</StorybookWrapper>
);
};
Expand Down
7 changes: 0 additions & 7 deletions src/Epic/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { css, ThemeProvider } from '@emotion/react';
import React from 'react';
import { brand, palette, space } from '@guardian/src-foundations';
import { OphanComponentEvent } from '@guardian/types';
import { BrazeClickHandler } from '../utils/tracking';
import { ContributionsEpicButtons } from './ContributionsEpicButtons';
import { body, headline } from '@guardian/src-foundations/typography';
import { COMPONENT_NAME, canRenderEpic, parseParagraphs } from './canRender';
Expand Down Expand Up @@ -67,18 +65,13 @@ export type BrazeMessageProps = {
};

export type EpicProps = {
logButtonClickWithBraze: BrazeClickHandler;
submitComponentEvent: (componentEvent: OphanComponentEvent) => void;
ophanComponentId?: string;
brazeMessageProps: BrazeMessageProps;
countryCode?: string;
};

export const Epic: React.FC<EpicProps> = (props: EpicProps) => {
const {
// logButtonClickWithBraze,
// submitComponentEvent,
// ophanComponentId = COMPONENT_NAME,
brazeMessageProps: { heading, buttonText, buttonUrl, highlightedText },
countryCode,
} = props;
Expand Down
10 changes: 0 additions & 10 deletions src/NewsletterEpic/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ import { NewsletterEpic } from '.';

describe('NewsletterEpic', () => {
describe('when the sign up button is clicked', () => {
const logButtonClickWithOphan = () => {
return;
};
const logButtonClickWithBraze = () => {
return;
};
const newsletterId = '4156';
const brazeMessageProps = {
header: 'First Thing',
Expand All @@ -30,8 +24,6 @@ describe('NewsletterEpic', () => {

render(
<NewsletterEpic
submitComponentEvent={logButtonClickWithOphan}
logButtonClickWithBraze={logButtonClickWithBraze}
brazeMessageProps={brazeMessageProps}
subscribeToNewsletter={subscribeToNewsletter}
/>,
Expand All @@ -48,8 +40,6 @@ describe('NewsletterEpic', () => {

render(
<NewsletterEpic
submitComponentEvent={logButtonClickWithOphan}
logButtonClickWithBraze={logButtonClickWithBraze}
brazeMessageProps={brazeMessageProps}
subscribeToNewsletter={subscribeToNewsletter}
/>,
Expand Down
4 changes: 0 additions & 4 deletions src/NewsletterEpic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { Button, buttonBrandAlt } from '@guardian/src-button';
import { COMPONENT_NAME } from './canRender';
import { body, headline, textSans } from '@guardian/src-foundations/typography';
import { canRender } from './canRender';
import { OphanComponentEvent } from '@guardian/types';
import { BrazeClickHandler } from '../utils/tracking';
import { from, until } from '@guardian/src-foundations/mq';

// Once https://github.com/guardian/source/pull/843 is merged and in a
Expand Down Expand Up @@ -119,8 +117,6 @@ export type BrazeMessageProps = {
};

export type Props = {
logButtonClickWithBraze: BrazeClickHandler;
submitComponentEvent: (componentEvent: OphanComponentEvent) => void;
brazeMessageProps: BrazeMessageProps;
subscribeToNewsletter: NewsletterSubscribeCallback;
};
Expand Down
5 changes: 2 additions & 3 deletions src/SpecialEditionBanner/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { ReactElement } from 'react';
import { withKnobs, text } from '@storybook/addon-knobs';
import { BrazeMessageComponent } from '../BrazeMessageComponent';
import { BrazeBannerComponent } from '../BrazeMessageComponent';
import { StorybookWrapper } from '../utils/StorybookWrapper';
import { knobsData } from '../utils/knobsData';

Expand Down Expand Up @@ -31,7 +31,7 @@ export const defaultStory = (): ReactElement => {
return (
<StorybookWrapper>
<>
<BrazeMessageComponent
<BrazeBannerComponent
componentName={componentName}
logButtonClickWithBraze={(internalButtonId) => {
console.log(`Button with internal ID ${internalButtonId} clicked`);
Expand All @@ -43,7 +43,6 @@ export const defaultStory = (): ReactElement => {
header: header,
body: body,
}}
subscribeToNewsletter={() => Promise.resolve()}
/>
</>
</StorybookWrapper>
Expand Down
5 changes: 2 additions & 3 deletions src/TheGuardianIn2020Banner/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { ReactElement } from 'react';
import { withKnobs, text } from '@storybook/addon-knobs';
import { BrazeMessageComponent } from '../BrazeMessageComponent';
import { BrazeBannerComponent } from '../BrazeMessageComponent';
import { StorybookWrapper } from '../utils/StorybookWrapper';
import { knobsData } from '../utils/knobsData';

Expand Down Expand Up @@ -30,7 +30,7 @@ export const defaultStory = (): ReactElement => {

return (
<StorybookWrapper>
<BrazeMessageComponent
<BrazeBannerComponent
componentName={componentName}
logButtonClickWithBraze={(internalButtonId) => {
console.log(`Button with internal ID ${internalButtonId} clicked`);
Expand All @@ -42,7 +42,6 @@ export const defaultStory = (): ReactElement => {
header,
body,
}}
subscribeToNewsletter={() => Promise.resolve()}
/>
</StorybookWrapper>
);
Expand Down
Loading

0 comments on commit 5ffdb35

Please sign in to comment.