Skip to content

Commit

Permalink
feat(TMRS-482): add new CategorisedArticles component
Browse files Browse the repository at this point in the history
  • Loading branch information
times-tools committed Nov 28, 2024
1 parent 2cc8cc7 commit 3398acb
Show file tree
Hide file tree
Showing 17 changed files with 168 additions and 17 deletions.
12 changes: 11 additions & 1 deletion packages/article-extras/src/article-extras.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ArticleComments from "@times-components/article-comments";
import RelatedArticles from "@times-components/related-articles";
import { MessageContext } from "@times-components/message-bar";
import SaveAndShareBar from "@times-components/save-and-share-bar";
import { RecommendedFetch, Breadcrumb } from "@times-components/ts-components";
import { RecommendedFetch, Breadcrumb, CategorisedArticles } from "@times-components/ts-components";

import ArticleTopics from "./article-topics";
import {
Expand Down Expand Up @@ -35,6 +35,7 @@ const ArticleExtras = ({
section,
articleHeadline,
relatedArticleSlice,
categorisedArticles,
relatedArticlesVisible,
commentingConfig,
topics,
Expand All @@ -57,6 +58,8 @@ const ArticleExtras = ({
return null;
};

const { categoryArticles, parentCategoryArticles } = categorisedArticles;

/* Nativo insert Sponsored Articles after the div#sponsored-article element. They are not able to insert directly into that element hence the container div */
const sponsoredArticlesAndRelatedArticles = (
isRecommendedActive,
Expand All @@ -69,6 +72,7 @@ const ArticleExtras = ({
analyticsStream={analyticsStream}
isVisible={relatedArticlesVisible}
slice={relatedArticleSlice}
hideBorder={!isRecommendedActive && Boolean(categoryArticles)}
/>
{isRecommendedActive && (
<RecommendedFetch
Expand All @@ -77,6 +81,12 @@ const ArticleExtras = ({
articleSection={section}
/>
)}
{!isRecommendedActive && categoryArticles && (
<CategorisedArticles heading={categoryArticles.label} articles={categoryArticles.articles} />
)}
{!isRecommendedActive && parentCategoryArticles && (
<CategorisedArticles heading={parentCategoryArticles.label} articles={parentCategoryArticles.articles} />
)}
</div>
<PromotedContentContainer>
<PromotedContentTitle>PROMOTED CONTENT</PromotedContentTitle>
Expand Down
3 changes: 2 additions & 1 deletion packages/article-skeleton/src/article-skeleton.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ const ArticleSkeleton = ({
window.removeEventListener("scroll", handleScroll);
};
}, []);
const { hostName, canonicalUrl, breadcrumbs } = articleDataFromRender || {};
const { hostName, canonicalUrl, breadcrumbs, categorisedArticles } = articleDataFromRender || {};
const articleUrl =
hostName && canonicalUrl ? `${hostName}${canonicalUrl}` : url;

Expand Down Expand Up @@ -424,6 +424,7 @@ const ArticleSkeleton = ({
commentsEnabled={commentsEnabled}
registerNode={registerNode}
relatedArticleSlice={relatedArticleSlice}
categorisedArticles={categorisedArticles}
relatedArticlesVisible={
!!observed.get("related-articles")
}
Expand Down
3 changes: 2 additions & 1 deletion packages/related-articles/src/related-articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class RelatedArticles extends Component {
}

render() {
const { isVisible, onPress, slice, heading } = this.props;
const { isVisible, onPress, slice, heading, hideBorder } = this.props;
if (!slice) return null;
const { items, sliceName } = slice;
if (
Expand Down Expand Up @@ -61,6 +61,7 @@ class RelatedArticles extends Component {
<TcView>
<RelatedArticlesHeading heading={heading} />
<StandardSlice
hideBorder={hideBorder}
itemCount={items.length}
renderItems={config =>
items.map(item =>
Expand Down
5 changes: 2 additions & 3 deletions packages/slice-layout/src/templates/standard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class StandardSlice extends Component {
}

render() {
const { renderItems } = this.props;
const { renderItems, hideBorder } = this.props;

const items = renderItems(this.config);

Expand All @@ -28,10 +28,9 @@ class StandardSlice extends Component {
}

const { ChildrenContainer, ConfigWrapper } = this;

return (
<ConfigWrapper>
<SliceContainer>
<SliceContainer hideBorder={hideBorder}>
<ChildrenContainer>
{items
.map(item => (
Expand Down
6 changes: 4 additions & 2 deletions packages/slice-layout/src/templates/styles/responsive.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import { breakpoints, colours, spacing } from "@times-components/ts-styleguide";
export const SliceContainer = styled(TcView)`
align-items: center;
border-bottom-color: ${colours.functional.keyline};
border-bottom-width: 1px;
border-bottom-width: ${({ hideBorder }) => hideBorder ? 0 : '1px'};
border-style: solid;
flex: 1;
justify-content: center;
${({ hideBorder }) => hideBorder && 'margin-bottom: 12px'};
@media (-webkit-min-device-pixel-ratio: 2) {
border-bottom-width: 0.5px;
border-bottom-width: ${({ hideBorder }) => hideBorder ? 0 : '0.5px'};
}
`;

Expand Down
1 change: 1 addition & 0 deletions packages/ts-components/src/components/carousel/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ export const CarouselContainer = styled.div<{
}
`;

// @ts-ignore
export const StyledCarousel = styled(ReactElasticCarousel)<{
isWide: boolean;
sectionColour: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import {
Slice,
SliceArticle,
MouseEventType
} from '@times-components/ts-slices';

import { useTrackingContext } from '../../helpers/tracking/TrackingContextProvider';
import {
Article,
getRecommendedArticlesSlice
} from '../../utils/linkedArticles/formatters';

import { Header } from '../../utils/linkedArticles/styles';

interface CategorisedArticles {
heading: string;
articles: Article[];
}
export const CategorisedArticles: React.FC<{
heading: string;
articles: any;
}> = ({ heading, articles }) => {
const { fireAnalyticsEvent } = useTrackingContext();

const onClickHandler = (__: MouseEventType, article: SliceArticle) => {
if (fireAnalyticsEvent) {
fireAnalyticsEvent({
action: 'Clicked',
attrs: { article_parent_name: article.headline }
});
}
};

return (
<div id="categorised-articles">
<Header>{`More from ${heading}`}</Header>
<Slice
slice={getRecommendedArticlesSlice(articles)}
clickHandler={onClickHandler}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import { CategorisedArticles } from '../CategorisedArticles';

describe('render CategorisedArticles', () => {
it('should render header and slice with articles when valid props provided', () => {
const mockArticles = [{ headline: 'Test Article' }];
const mockFireEvent = jest.fn();

jest.mock('../../../helpers/tracking/TrackingContextProvider', () => ({
useTrackingContext: () => ({
fireAnalyticsEvent: mockFireEvent
})
}));

const { container, asFragment } = render(
<CategorisedArticles heading="Sports" articles={mockArticles} />
);

expect(asFragment()).toMatchSnapshot();
expect(
container.querySelector('#categorised-articles')
).toBeInTheDocument();
expect(screen.getByText('More from Sports')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`render CategorisedArticles should render header and slice with articles when valid props provided 1`] = `
<DocumentFragment>
<div
id="categorised-articles"
>
<div
class="sc-bdVaJa vbIkV"
>
More from Sports
</div>
<div
class="shared-styles__SliceContainer-ismxwo-0 styles__SliceContainer-b33h2c-0 bJHjPH"
>
<div
class="shared-styles__SlotContainer-ismxwo-1 styles__SlotContainer-b33h2c-1 cKwigu"
>
<article
class="shared-styles__ArticleContainer-sc-1kek94e-0 jgpbxb"
>
<div
class="shared-styles__SideBySideColumn-sc-1kek94e-1 jOKfAL"
>
<div
class="styles__ImageContainer-sc-8lglkt-0 hmOUZw"
>
<a>
<div
class="styles__ImageRatio-sc-8lglkt-1 kDSgGC"
>
<div
class="styles__LazyContainer-qsbah5-0 iKBUbT"
>
<img
alt="Test Article"
/>
</div>
</div>
</a>
</div>
</div>
<div
class="shared-styles__SideBySideColumn-sc-1kek94e-1 jOKfAL"
>
<div
class="styles__HeadlineContainer-k0mgwi-0 ghKmOQ"
>
<a>
<h3>
Test Article
</h3>
</a>
</div>
</div>
</article>
</div>
</div>
</div>
</DocumentFragment>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export const CarouselIndicator = styled.div<{ active?: boolean }>`
cursor: pointer;
`;

// @ts-ignore
export const StyledCarousel = styled(ReactElasticCarousel)<{
sectionColour: string;
}>`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {

import { useFetch } from '../../helpers/fetch/FetchProvider';
import { useTrackingContext } from '../../helpers/tracking/TrackingContextProvider';
import { getRecommendedArticlesSlice } from './formatters';
import { getRecommendedArticlesSlice } from '../../utils/linkedArticles/formatters';

import { Header } from './styles';
import { Header } from '../../utils/linkedArticles/styles';

export const RecommendedArticles: React.FC<{
heading: string;
Expand Down
3 changes: 3 additions & 0 deletions packages/ts-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ export {
export {
RecommendedFetch
} from './components/recommended-articles/RecommendedFetch';
export {
CategorisedArticles
} from './components/categorised-articles/CategorisedArticles';

// Helpers
export { FetchProvider } from './helpers/fetch/FetchProvider';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getArticles } from '../helpers';
import previewData from '../../../fixtures/preview-data/recommended-articles';
import { getArticles } from '../../components/recommended-articles/helpers';
import previewData from '../../fixtures/preview-data/recommended-articles';

import { getRecommendedArticlesSlice } from '../formatters';
import { getRecommendedArticlesSlice } from '../linkedArticles/formatters';

const expectedArticles = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Media = {
type SummaryText = { __typename: string; text: string };
type Summary = { __typename: string; children: SummaryText[] };

type Article = {
export type Article = {
__typename: string;
url: string;
slug: string;
Expand All @@ -31,7 +31,7 @@ type Article = {
bylines?: Byline[];
summary?: Summary;
media?: Media;
categoryPath: string;
categoryPath?: string;
};

// HELPERS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const LazyImage: React.FC<{
}> = ({ url, alt, isRoundal, isBackground }) => {
const ref: React.RefObject<HTMLImageElement> = React.createRef();

const [src, setSrc] = useState<string>();
const [src, setSrc] = useState<string | undefined>(url);

useEffect(
() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ exports[`<Image /> should render image component correctly 1`] = `
class="sc-bxivhb gqElVf"
>
<div
class="sc-bdVaJa gqNbEe"
class="sc-bdVaJa fdpJDB"
>
<img
alt="image alt text"
src="https://dummyimage.com/300"
/>
</div>
</div>
Expand Down

0 comments on commit 3398acb

Please sign in to comment.