From 12e979f3a6000c6b9400cc1275e52a44b73bca3e Mon Sep 17 00:00:00 2001 From: Dominik Lander Date: Mon, 9 Dec 2024 12:22:42 +0000 Subject: [PATCH 1/8] Remove Weather component --- .../src/components/Weather.stories.tsx | 68 ---- dotcom-rendering/src/components/Weather.tsx | 293 ------------------ .../src/components/WeatherSlot.tsx | 229 -------------- .../components/WeatherWrapper.importable.tsx | 52 ---- dotcom-rendering/src/layouts/FrontLayout.tsx | 21 -- dotcom-rendering/src/paletteDeclarations.ts | 4 - dotcom-rendering/src/types/weather.ts | 71 ----- 7 files changed, 738 deletions(-) delete mode 100644 dotcom-rendering/src/components/Weather.stories.tsx delete mode 100644 dotcom-rendering/src/components/Weather.tsx delete mode 100644 dotcom-rendering/src/components/WeatherSlot.tsx delete mode 100644 dotcom-rendering/src/components/WeatherWrapper.importable.tsx delete mode 100644 dotcom-rendering/src/types/weather.ts diff --git a/dotcom-rendering/src/components/Weather.stories.tsx b/dotcom-rendering/src/components/Weather.stories.tsx deleted file mode 100644 index 030a0f5f392..00000000000 --- a/dotcom-rendering/src/components/Weather.stories.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { splitTheme } from '../../.storybook/decorators/splitThemeDecorator'; -import { Weather as WeatherComponent } from './Weather'; - -const meta: Meta = { - title: 'Components/Weather', - component: WeatherComponent, -}; - -type Story = StoryObj; -export const Weather: Story = { - args: { - edition: 'UK', - location: { - id: '712993', - city: 'Ickleford', - country: 'United Kingdom', - }, - now: { - description: 'Sunny', - icon: 1, - link: 'http://www.accuweather.com/en/gb/ickleford/sg5-3/current-weather/712993?lang=en-us', - dateTime: null, - temperature: { metric: 27, imperial: 81 }, - }, - forecast: { - '3h': { - description: 'Mostly sunny', - icon: 2, - link: '', - dateTime: '2024-07-31T20:00:00+01:00', - temperature: { metric: 23, imperial: 74 }, - }, - '6h': { - description: 'Partly cloudy', - icon: 35, - link: '', - dateTime: '2024-07-31T23:00:00+01:00', - temperature: { metric: 18, imperial: 65 }, - }, - '9h': { - description: 'Cloudy', - icon: 7, - link: '', - dateTime: '2024-08-01T02:00:00+01:00', - temperature: { metric: 15, imperial: 59 }, - }, - '12h': { - description: 'Intermittent clouds', - icon: 36, - link: '', - dateTime: '2024-08-01T05:00:00+01:00', - temperature: { metric: 16, imperial: 61 }, - }, - }, - }, - decorators: [splitTheme()], -}; - -export const WeatherUS: Story = { - ...Weather, - args: { - ...Weather.args, - edition: 'US', - }, -}; - -export default meta; diff --git a/dotcom-rendering/src/components/Weather.tsx b/dotcom-rendering/src/components/Weather.tsx deleted file mode 100644 index b1ca8b5aaad..00000000000 --- a/dotcom-rendering/src/components/Weather.tsx +++ /dev/null @@ -1,293 +0,0 @@ -/** - * "WEATHER" - * - * Whether the weather be fine, - * Or whether the weather be not, - * Whether the weather be cold, - * Or whether the weather be hot, - * We'll weather the weather - * Whatever the weather, - * Whether we like it or not! - * - * Author: Anonymous British - */ - -import { css, keyframes } from '@emotion/react'; -import { - between, - from, - space, - textSans15, - textSans17, - until, - visuallyHidden, -} from '@guardian/source/foundations'; -import { - SvgChevronDownSingle, - SvgChevronUpSingle, - SvgExternal, -} from '@guardian/source/react-components'; -import { useId } from 'react'; -import type { EditionId } from '../lib/edition'; -import { palette } from '../palette'; -import type { WeatherApiData, WeatherData } from '../types/weather'; -import { WeatherSlot } from './WeatherSlot'; - -const visuallyHiddenCSS = css` - ${visuallyHidden} -`; - -const weatherCSS = css` - animation: ${keyframes`from { opacity: 0; } to { opacity: 1; }`} 250ms; - --border: 1px solid ${palette('--article-border')}; - width: 100%; - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; - letter-spacing: -0.56px; - - ${between.tablet.and.leftCol} { - padding-top: 6px; - height: 52px; - } -`; - -const locationCSS = css` - flex: 1; - ${textSans17}; - padding: 12px 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - - ${until.tablet} { - flex-basis: 100%; - border-bottom: var(--border); - } - - ${between.tablet.and.leftCol} { - padding-right: 1ch; - } - - ${from.leftCol} { - flex-basis: 100%; - border-bottom: var(--border); - } -`; - -const nowCSS = css` - ${until.tablet} { - justify-content: flex-end; - flex-basis: 100%; - border-bottom: var(--border); - order: -1; - padding-bottom: 4px; - margin-top: -${space[9]}px; - } - - ${from.leftCol} { - flex-basis: 100%; - border-bottom: var(--border); - padding-top: 8px; - padding-bottom: 24px; - } -`; - -const slotCSS = css` - display: flex; - flex: 1; - padding-top: 6px; - - border-left: var(--border); - padding-left: 6px; - - ${until.mobileLandscape} { - &.forecast-4 { - display: none; - } - } - - ${until.tablet} { - &.now, - &.forecast-1 { - border-left: none; - } - } - - ${between.tablet.and.desktop} { - padding-left: 6px; - padding-right: 6px; - &.forecast-3, - &.forecast-4 { - display: none; - } - } - - ${between.desktop.and.wide} { - padding-left: 4px; - padding-right: 4px; - &.forecast-4 { - display: none; - } - } - - ${from.leftCol} { - &.now, - &.forecast-1 { - border-left: none; - } - } -`; - -const linkCSS = css` - a { - ${textSans15}; - color: inherit; - text-decoration: none; - display: block; - display: flex; - flex-direction: row; - align-items: center; - - &:hover { - text-decoration: underline; - } - } - - ${until.tablet} { - flex-basis: 100%; - padding-top: 12px; - } - - ${from.leftCol} { - padding-top: 24px; - flex-basis: 100%; - } -`; - -const ExternalLinkIcon = () => ( -
- -
-); - -export interface WeatherProps - extends Pick { - now: WeatherData; - edition: EditionId; - link?: string; -} - -const collapsibleStyles = css` - .checkbox-label { - display: none; - } - - .checkbox { - display: none; - } - - ${until.tablet} { - .checkbox-label { - display: inherit; - } - - .checkbox:not(:checked) ~ .now { - border-bottom: none; - } - - .checkbox:not(:checked) ~ .now > .checkbox-label { - svg:first-child { - display: none; - } - } - - .checkbox:checked ~ .now > .checkbox-label { - svg:last-child { - display: none; - } - } - - .checkbox:not(:checked) ~ .collapsible { - display: none; - } - } -`; - -export const WeatherPlaceholder = () => ( - -); - -export const Weather = ({ - location, - now, - forecast, - edition, - link, -}: WeatherProps) => { - const checkboxId = useId(); - - return ( - - ); -}; diff --git a/dotcom-rendering/src/components/WeatherSlot.tsx b/dotcom-rendering/src/components/WeatherSlot.tsx deleted file mode 100644 index 581e8ad3b34..00000000000 --- a/dotcom-rendering/src/components/WeatherSlot.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import type { SerializedStyles } from '@emotion/react'; -import { css, keyframes } from '@emotion/react'; -import { isString } from '@guardian/libs'; -import { - from, - palette, - textSans12, - textSans17, - textSans24, - until, - visuallyHidden, -} from '@guardian/source/foundations'; -import { lazy, Suspense } from 'react'; -import { type EditionId, getEditionFromId } from '../lib/edition'; -import type { WeatherData } from '../types/weather'; - -interface IconProps { - size?: number; -} - -const formatTemperature = (value: number, unit: string) => - `${value}°${unit.toLocaleUpperCase()}`; - -const formatTime = (dateTime: string, edition: EditionId) => - new Date(dateTime).toLocaleTimeString( - getEditionFromId(edition).dateLocale, - { - hour: 'numeric', - // US and AU dates include AM/PM markers that cause the timestamp to - // wrap onto the next line, which we don't want for the design. - // Given that the times are always on the hour, i.e. the minutes are - // always "00", we can choose to show the hour only without losing - // information. This shortens the timestamp and keeps it on one line. - minute: - edition === 'US' || edition === 'AU' ? undefined : 'numeric', - }, - ); - -const visuallyHiddenCSS = css` - ${visuallyHidden} -`; - -const slotCSS = css` - animation: ${keyframes`from { opacity: 0; } to { opacity: 1; }`} 250ms; - position: relative; - display: inline-flex; - flex-direction: column; - align-items: flex-start; - justify-content: center; - padding-left: 40px; - min-height: 40px; /* icon height (32) + 4 + 4 */ - - ${from.leftCol} { - padding-left: 0; - } -`; - -const timeCSS = css` - ${textSans12}; - display: block; -`; - -const nowCSS = [ - timeCSS, - css` - ${until.tablet} { - display: none; - } - - ${from.leftCol} { - padding-bottom: 4px; - } - `, -]; - -const tempCSS = (isNow: boolean) => [ - css` - display: block; - ${textSans17}; - - ${from.leftCol} { - order: 1; - padding-top: 4px; - } - `, - isNow && - css` - ${from.leftCol} { - ${textSans24}; - line-height: 1; - } - `, -]; - -const iconCSS = (size: number) => css` - position: absolute; - top: 50%; - left: 0px; - margin-top: -16px; - - ${from.leftCol} { - position: static; - margin-top: 0; - height: ${size}px; - width: ${size}px; - margin-right: ${size === 50 ? 8 : 0}px; - } -`; - -const flexRow = css` - display: flex; - flex-direction: row; -`; - -const flexColumn = css` - display: flex; - flex-direction: column; -`; - -const flexRowBelowLeftCol = css` - ${until.leftCol} { - ${flexRow} - } -`; - -const flexColumnBelowLeftCol = css` - ${until.leftCol} { - ${flexColumn} - } -`; - -const LoadingIcon = () => ( - -); - -export type WeatherSlotProps = WeatherData & { - edition: EditionId; - css?: SerializedStyles; -}; - -export const WeatherSlot = ({ - icon, - temperature, - dateTime, - description, - edition, - ...props -}: WeatherSlotProps) => { - const isNow = !isString(dateTime); - - const Icon = lazy(() => - import(`../static/icons/weather/weather-${icon}.svg`).then( - ({ default: Component }) => { - return { - default: ({ size = 32 }: IconProps) => ( - - ), - }; - }, - ), - ); - - return ( -

- - {isNow ? 'The current weather' : 'The forecast for'} - - {isNow ? ( -

-
- }> - - -
-
- - Now - - is - - {formatTemperature( - edition === 'US' - ? temperature.imperial - : temperature.metric, - edition === 'US' ? 'F' : 'C', - )} - - - , {description.toLowerCase()}. - -
-
- ) : ( -
-
- - is - - {formatTemperature( - edition === 'US' - ? temperature.imperial - : temperature.metric, - edition === 'US' ? 'F' : 'C', - )} - - - , {description.toLowerCase()}. - -
- }> - - -
- )} -

- ); -}; diff --git a/dotcom-rendering/src/components/WeatherWrapper.importable.tsx b/dotcom-rendering/src/components/WeatherWrapper.importable.tsx deleted file mode 100644 index 007b2c2294e..00000000000 --- a/dotcom-rendering/src/components/WeatherWrapper.importable.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import type { EditionId } from '../lib/edition'; -import { useApi } from '../lib/useApi'; -import { parseWeatherData } from '../types/weather'; -import { Weather, WeatherPlaceholder } from './Weather'; - -const appendPartnerCodeToUrl = ( - url: string | undefined, -): string | undefined => { - if (!url) return undefined; - - try { - const link = new URL(url); - link.searchParams.append('partner', 'web_guardian_adc'); - return link.href; - } catch { - return undefined; - } -}; - -type Props = { - ajaxUrl: string; - edition: EditionId; -}; - -export const WeatherWrapper = ({ ajaxUrl, edition }: Props) => { - const { data, error } = useApi(`${ajaxUrl}/weather.json`); - - if (error) { - window.guardian.modules.sentry.reportError(error, 'weather'); - } - - const result = parseWeatherData(data); - - if (result.kind === 'error' && result.error === 'ParsingError') { - window.guardian.modules.sentry.reportError( - Error('Invalid weather data'), - 'weather', - ); - } - - return result.kind === 'error' ? ( - - ) : ( - - ); -}; diff --git a/dotcom-rendering/src/layouts/FrontLayout.tsx b/dotcom-rendering/src/layouts/FrontLayout.tsx index c941774e857..6bde73e2dcf 100644 --- a/dotcom-rendering/src/layouts/FrontLayout.tsx +++ b/dotcom-rendering/src/layouts/FrontLayout.tsx @@ -32,7 +32,6 @@ import { StickyBottomBanner } from '../components/StickyBottomBanner.importable' import { SubNav } from '../components/SubNav.importable'; import { TrendingTopics } from '../components/TrendingTopics'; import { UsEoy2024Wrapper } from '../components/UsEoy2024Wrapper.importable'; -import { WeatherWrapper } from '../components/WeatherWrapper.importable'; import { ArticleDisplay } from '../lib/articleFormat'; import { badgeFromBranding, isPaidContentSameBranding } from '../lib/branding'; import { canRenderAds } from '../lib/canRenderAds'; @@ -95,7 +94,6 @@ const isToggleable = ( const decideLeftContent = ( front: DCRFrontType, collection: DCRCollectionType, - hasPageSkin: boolean, ) => { // show CPScott? if ( @@ -107,24 +105,6 @@ const decideLeftContent = ( return ; } - // show weather? - if ( - front.config.switches['weather'] && - isNetworkFrontPageId(front.config.pageId) && - // based on https://github.com/guardian/frontend/blob/473aafd168fec7f2a578a52c8e84982e3ec10fea/common/app/views/support/GetClasses.scala#L107 - collection.displayName.toLowerCase() === 'headlines' && - !hasPageSkin - ) { - return ( - - - - ); - } - // show nothing! return null; }; @@ -723,7 +703,6 @@ export const FrontLayout = ({ front, NAV }: Props) => { leftContent={decideLeftContent( front, collection, - hasPageSkin, )} sectionId={ophanName} collectionId={collection.id} diff --git a/dotcom-rendering/src/paletteDeclarations.ts b/dotcom-rendering/src/paletteDeclarations.ts index 121fae015e5..18b7c77d204 100644 --- a/dotcom-rendering/src/paletteDeclarations.ts +++ b/dotcom-rendering/src/paletteDeclarations.ts @@ -7246,10 +7246,6 @@ const paletteColours = { light: () => sourcePalette.news[400], dark: () => '#DC2E1C', }, - '--weather-icon': { - light: () => sourcePalette.neutral[97], - dark: () => sourcePalette.neutral[7], - }, '--witness-title-author': { light: witnessTitleAuthor, dark: witnessTitleAuthor, diff --git a/dotcom-rendering/src/types/weather.ts b/dotcom-rendering/src/types/weather.ts deleted file mode 100644 index 6afd6cad436..00000000000 --- a/dotcom-rendering/src/types/weather.ts +++ /dev/null @@ -1,71 +0,0 @@ -import type { Output } from 'valibot'; -import { - nullable, - number, - object, - optional, - safeParse, - string, - transform, - tuple, - unknown, -} from 'valibot'; -import type { Result } from '../lib/result'; -import { error, ok } from '../lib/result'; - -const weatherDataSchema = object({ - description: string(), - icon: number(), - link: nullable(string(), ''), - dateTime: nullable(string()), - temperature: object({ - metric: number(), - imperial: number(), - }), -}); -export type WeatherData = Output; - -const weatherApiDataSchema = object({ - location: object({ - id: string(), - city: string(), - country: string(), - }), - weather: weatherDataSchema, - /** - * Our weather API returns 24h forecast. - * Each forecast is 1 hour offset from the previous forecast, and the first forecast is 1 hour offset from now. - */ - forecast: transform( - tuple([ - unknown(), - unknown(), - unknown(), - weatherDataSchema, - unknown(), - unknown(), - weatherDataSchema, - unknown(), - unknown(), - weatherDataSchema, - unknown(), - unknown(), - weatherDataSchema, - ]), - (forecast) => ({ - '3h': forecast[3], - '6h': forecast[6], - '9h': forecast[9], - '12h': forecast[12], - }), - ), -}); -export type WeatherApiData = Output; - -export const parseWeatherData = ( - data: unknown, -): Result<'Loading' | 'ParsingError', WeatherApiData> => { - const result = safeParse(optional(weatherApiDataSchema), data); - if (!result.success) return error('ParsingError'); - return result.output ? ok(result.output) : error('Loading'); -}; From e9e6e0024dd99ab8b5dcd08c6d7c65c9a15fc3ba Mon Sep 17 00:00:00 2001 From: Charlotte Emms <43961396+cemms1@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:28:51 +0000 Subject: [PATCH 2/8] Pin version 4.1.2 of actions-riff-raff (#13106) --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6f20e7270c0..70ac6387886 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -55,7 +55,7 @@ jobs: # All rendering apps deployment - name: Upload rendering apps to RiffRaff - uses: guardian/actions-riff-raff@v4 + uses: guardian/actions-riff-raff@v4.1.2 with: githubToken: ${{ secrets.GITHUB_TOKEN }} roleArn: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} From 054778f6861f2d4ab3c1625eef584f33e5a3cb6c Mon Sep 17 00:00:00 2001 From: Charlotte Emms <43961396+cemms1@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:48:58 +0000 Subject: [PATCH 3/8] Include beta collection types in ad placement logic for desktop (#12942) * include beta collection types in ad placement logic * Add 6 as value for collection height of very long containers that are at least double a standard screen height --- .../src/lib/getFrontsAdPositions.ts | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/dotcom-rendering/src/lib/getFrontsAdPositions.ts b/dotcom-rendering/src/lib/getFrontsAdPositions.ts index 4d0fd72fa1e..44179f544c9 100644 --- a/dotcom-rendering/src/lib/getFrontsAdPositions.ts +++ b/dotcom-rendering/src/lib/getFrontsAdPositions.ts @@ -12,6 +12,7 @@ type GroupedCounts = { veryBig: number; big: number; standard: number; + splash: number; }; type AdCandidate = Pick; @@ -75,13 +76,14 @@ const getMobileAdPositions = (collections: AdCandidate[]): number[] => { * * A result of 3 would approximately be the height of a typical desktop viewport (~900px). * A result of 1 would be a third of the height, a result of 1.5 would be half, etc. + * A result of 6 indicates a container is at least double the height of a typical desktop viewport. */ const getCollectionHeight = ( collction: Pick< DCRCollectionType, 'collectionType' | 'containerPalette' | 'grouped' >, -): 0.5 | 1 | 1.5 | 2 | 2.5 | 3 => { +): 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 6 => { const { collectionType, containerPalette, grouped } = collction; if (containerPalette === 'PodcastPalette') { @@ -95,18 +97,22 @@ const getCollectionHeight = ( veryBig: grouped.veryBig.length, big: grouped.big.length, standard: grouped.standard.length, + splash: grouped.splash.length, }; switch (collectionType) { // Some thrashers are very small. Since we'd prefer to have ads above content rather than thrashers, // err on the side of inserting fewer ads, by setting the number on the small side for thrashers case 'fixed/thrasher': + case 'scrollable/small': return 0.5; case 'fixed/small/slow-IV': case 'fixed/small/slow-V-mpu': case 'nav/list': case 'nav/media-list': + case 'scrollable/medium': + case 'static/medium/4': return 1; case 'fixed/small/slow-I': @@ -116,6 +122,7 @@ const getCollectionHeight = ( case 'fixed/small/fast-VIII': case 'fixed/video': case 'fixed/video/vertical': + case 'scrollable/feature': return 1.5; case 'fixed/medium/slow-VI': @@ -123,6 +130,7 @@ const getCollectionHeight = ( case 'fixed/medium/slow-XII-mpu': case 'fixed/medium/fast-XI': case 'fixed/medium/fast-XII': + case 'static/feature/2': return 2; case 'fixed/large/slow-XIV': @@ -157,6 +165,29 @@ const getCollectionHeight = ( } return 1; + case 'flexible/special': + if (groupedCounts.snap && !groupedCounts.splash) { + return 1.5; + } else if (groupedCounts.splash && !groupedCounts.standard) { + return 2.5; + } else { + return 3; + } + + case 'flexible/general': + if (groupedCounts.splash && !groupedCounts.standard) { + return 2.5; + } else if (groupedCounts.splash && groupedCounts.standard > 2) { + return 6; + } else if ( + grouped.splash[0]?.boostLevel === 'megaboost' || + grouped.splash[0]?.boostLevel === 'gigaboost' + ) { + return 6; + } else { + return 3; + } + default: return 1; // Unknown collection type. } From f244edb143baefe7c989aaca8b2f2fc45a77fa46 Mon Sep 17 00:00:00 2001 From: Jake Date: Wed, 8 Jan 2025 14:52:10 +0000 Subject: [PATCH 4/8] bump commercial (#13103) --- dotcom-rendering/package.json | 2 +- pnpm-lock.yaml | 76 +++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/dotcom-rendering/package.json b/dotcom-rendering/package.json index 6ab042c52b6..16fe2eba188 100644 --- a/dotcom-rendering/package.json +++ b/dotcom-rendering/package.json @@ -41,7 +41,7 @@ "@guardian/bridget": "8.1.0", "@guardian/browserslist-config": "6.1.0", "@guardian/cdk": "50.13.0", - "@guardian/commercial": "23.7.4", + "@guardian/commercial": "24.0.0", "@guardian/core-web-vitals": "7.0.0", "@guardian/eslint-config": "7.0.1", "@guardian/eslint-config-typescript": "9.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a238575d840..9adc5e49b7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -338,8 +338,8 @@ importers: specifier: 50.13.0 version: 50.13.0(@swc/core@1.9.2)(@types/node@20.14.10)(aws-cdk-lib@2.100.0)(aws-cdk@2.100.0)(constructs@10.3.0)(typescript@5.5.3) '@guardian/commercial': - specifier: 23.7.4 - version: 23.7.4(@guardian/ab-core@8.0.0)(@guardian/core-web-vitals@7.0.0)(@guardian/identity-auth-frontend@4.0.0)(@guardian/identity-auth@2.1.0)(@guardian/libs@19.2.1)(@guardian/source@8.0.0)(react-dom@18.3.1)(react@18.3.1)(typescript@5.5.3) + specifier: 24.0.0 + version: 24.0.0(@guardian/ab-core@8.0.0)(@guardian/core-web-vitals@7.0.0)(@guardian/identity-auth-frontend@4.0.0)(@guardian/identity-auth@2.1.0)(@guardian/libs@19.2.1)(@guardian/source@8.0.0)(react-dom@18.3.1)(react@18.3.1)(typescript@5.5.3) '@guardian/core-web-vitals': specifier: 7.0.0 version: 7.0.0(@guardian/libs@19.2.1)(tslib@2.6.2)(typescript@5.5.3)(web-vitals@4.2.3) @@ -3849,31 +3849,31 @@ packages: - typescript dev: false - /@guardian/commercial@23.7.4(@guardian/ab-core@8.0.0)(@guardian/core-web-vitals@7.0.0)(@guardian/identity-auth-frontend@4.0.0)(@guardian/identity-auth@2.1.0)(@guardian/libs@19.2.1)(@guardian/source@8.0.0)(react-dom@18.3.1)(react@18.3.1)(typescript@5.5.3): - resolution: {integrity: sha512-VMRRWR0pUMcZkDYfJ8kf8LD5OK/x29WPjbphizCAB0h7zJTeRKhUiJfQQ3l0YNZA+MrRXzY+PZIaf2IZvQJbGg==} + /@guardian/commercial@24.0.0(@guardian/ab-core@8.0.0)(@guardian/core-web-vitals@7.0.0)(@guardian/identity-auth-frontend@4.0.0)(@guardian/identity-auth@2.1.0)(@guardian/libs@19.2.1)(@guardian/source@8.0.0)(react-dom@18.3.1)(react@18.3.1)(typescript@5.5.3): + resolution: {integrity: sha512-GlM/kkyDXHySjnmy0L6byzIQCV9ZER39YufTQR151uK404AwPF7Mgxyr3oj0erkUh6jEyQfwfn5VXqEUTk6/vw==} peerDependencies: '@guardian/ab-core': ^8.0.0 - '@guardian/core-web-vitals': ^7.0.0 - '@guardian/identity-auth': ^3.0.0 - '@guardian/identity-auth-frontend': ^5.0.0 + '@guardian/core-web-vitals': ^8.0.1 + '@guardian/identity-auth': ^4.0.0 + '@guardian/identity-auth-frontend': ^6.0.0 '@guardian/libs': ^19.1.0 '@guardian/source': ^8.0.0 - typescript: ~5.5.3 + typescript: ~5.5.2 dependencies: '@guardian/ab-core': 8.0.0(tslib@2.6.2)(typescript@5.5.3) '@guardian/core-web-vitals': 7.0.0(@guardian/libs@19.2.1)(tslib@2.6.2)(typescript@5.5.3)(web-vitals@4.2.3) '@guardian/identity-auth': 2.1.0(@guardian/libs@19.2.1)(tslib@2.6.2)(typescript@5.5.3) '@guardian/identity-auth-frontend': 4.0.0(@guardian/identity-auth@2.1.0)(@guardian/libs@19.2.1)(tslib@2.6.2)(typescript@5.5.3) '@guardian/libs': 19.2.1(tslib@2.6.2)(typescript@5.5.3) - '@guardian/prebid.js': 8.52.0-8(react-dom@18.3.1)(react@18.3.1)(tslib@2.6.2)(typescript@5.5.3) + '@guardian/prebid.js': 8.52.0-10(react-dom@18.3.1)(react@18.3.1)(tslib@2.8.1)(typescript@5.5.3) '@guardian/source': 8.0.0(@emotion/react@11.11.3)(@types/react@18.3.1)(react@18.3.1)(tslib@2.6.2)(typescript@5.5.3) '@octokit/core': 6.1.2 fastdom: 1.0.12 lodash-es: 4.17.21 process: 0.11.10 - tslib: 2.6.2 + tslib: 2.8.1 typescript: 5.5.3 - web-vitals: 4.2.3 + web-vitals: 4.2.4 transitivePeerDependencies: - arc-templates - atpl @@ -4024,7 +4024,7 @@ packages: '@typescript-eslint/parser': 6.18.0(eslint@8.56.0)(typescript@5.5.3) eslint: 8.56.0 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.18.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) tslib: 2.6.2 typescript: 5.5.3 transitivePeerDependencies: @@ -4132,7 +4132,7 @@ packages: typescript: 5.5.3 dev: false - /@guardian/libs@18.0.0(tslib@2.6.2)(typescript@5.5.3): + /@guardian/libs@18.0.0(tslib@2.8.1)(typescript@5.5.3): resolution: {integrity: sha512-V/aVeCg3yEDBiw6ykAIRux3HCpORKPAzTReDogg2ZHf8BV0v7P2ysc/etO5TW4+8FVd6X8SpX3GmTP3YePx8FQ==} peerDependencies: tslib: ^2.6.2 @@ -4141,7 +4141,7 @@ packages: typescript: optional: true dependencies: - tslib: 2.6.2 + tslib: 2.8.1 typescript: 5.5.3 dev: false @@ -4165,8 +4165,8 @@ packages: '@guardian/tsconfig': 1.0.0 dev: false - /@guardian/prebid.js@8.52.0-8(react-dom@18.3.1)(react@18.3.1)(tslib@2.6.2)(typescript@5.5.3): - resolution: {integrity: sha512-JQ9unudgn5DAwLoqEiBdjuEaEFOhR9JZhjHD46pm4306C1XfYF0ts3YWIT9poq6vN1tbMQJw0NQeyXcL5QGIcA==} + /@guardian/prebid.js@8.52.0-10(react-dom@18.3.1)(react@18.3.1)(tslib@2.8.1)(typescript@5.5.3): + resolution: {integrity: sha512-/oGFQ3GlwzJOfc7Fe1AiTI2XCjPcco7fDDli4FDJx0GAuiJDuzL6hEogqATXJzbmaXx3zp21nRgyxYh+ykR1AA==} engines: {node: '>=12.0.0'} dependencies: '@babel/core': 7.26.0 @@ -4174,7 +4174,7 @@ packages: '@babel/preset-env': 7.26.0(@babel/core@7.26.0) '@babel/register': 7.24.6(@babel/core@7.26.0) '@babel/runtime': 7.26.0 - '@guardian/libs': 18.0.0(tslib@2.6.2)(typescript@5.5.3) + '@guardian/libs': 18.0.0(tslib@2.8.1)(typescript@5.5.3) core-js: 3.33.3 core-js-pure: 3.38.1 criteo-direct-rsa-validate: 1.1.0 @@ -6191,7 +6191,7 @@ packages: react-docgen-typescript: 2.2.2(typescript@5.5.3) tslib: 2.6.2 typescript: 5.5.3 - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) transitivePeerDependencies: - supports-color dev: false @@ -7749,8 +7749,8 @@ packages: webpack: 5.x.x webpack-cli: 5.x.x dependencies: - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.97.1) dev: false /@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.97.1): @@ -7760,8 +7760,8 @@ packages: webpack: 5.x.x webpack-cli: 5.x.x dependencies: - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.97.1) dev: false /@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.1.0)(webpack@5.97.1): @@ -7775,8 +7775,8 @@ packages: webpack-dev-server: optional: true dependencies: - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.97.1) webpack-dev-server: 5.1.0(webpack-cli@5.1.4)(webpack@5.97.1) dev: false @@ -8384,7 +8384,7 @@ packages: '@babel/core': 7.26.0 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /babel-plugin-istanbul@6.1.1: @@ -9552,7 +9552,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.47) postcss-value-parser: 4.2.0 semver: 7.5.4 - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /css-loader@7.1.2(webpack@5.97.1): @@ -10530,7 +10530,7 @@ packages: enhanced-resolve: 5.17.0 eslint: 8.56.0 eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.15.1 @@ -11536,7 +11536,7 @@ packages: semver: 7.5.4 tapable: 2.2.1 typescript: 5.5.3 - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /form-data-encoder@2.1.4: @@ -16720,7 +16720,7 @@ packages: peerDependencies: webpack: ^5.0.0 dependencies: - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /stylelint-config-recommended@14.0.0(stylelint@16.5.0): @@ -17206,7 +17206,7 @@ packages: semver: 7.5.4 source-map: 0.7.4 typescript: 5.5.3 - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /ts-node@10.9.2(@swc/core@1.9.2)(@types/node@16.18.68)(typescript@5.1.6): @@ -17341,6 +17341,10 @@ packages: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: false + /tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + dev: false + /tsutils@3.21.0(typescript@5.5.3): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -17840,6 +17844,10 @@ packages: resolution: {integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==} dev: false + /web-vitals@4.2.4: + resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} + dev: false + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false @@ -17980,7 +17988,7 @@ packages: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /webpack-dev-middleware@7.4.2(webpack@5.97.1): @@ -18040,8 +18048,8 @@ packages: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.1.0)(webpack@5.97.1) webpack-dev-middleware: 7.4.2(webpack@5.97.1) ws: 8.18.0 transitivePeerDependencies: @@ -18086,7 +18094,7 @@ packages: webpack: ^5.47.0 dependencies: tapable: 2.2.1 - webpack: 5.97.1(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.9.2)(esbuild@0.18.20)(webpack-cli@5.1.4) webpack-sources: 2.3.1 dev: false patched: true From 8cff2982a81c7415d0a19581c52609b8db6118e9 Mon Sep 17 00:00:00 2001 From: Dominik Lander Date: Wed, 8 Jan 2025 16:25:53 +0000 Subject: [PATCH 5/8] Remove weatherapiurl from schema and FEFrontConfigType --- dotcom-rendering/src/model/front-schema.json | 4 ---- dotcom-rendering/src/model/tag-page-schema.json | 4 ---- dotcom-rendering/src/types/front.ts | 1 - 3 files changed, 9 deletions(-) diff --git a/dotcom-rendering/src/model/front-schema.json b/dotcom-rendering/src/model/front-schema.json index 0dcefd774f3..83f8a1da22b 100644 --- a/dotcom-rendering/src/model/front-schema.json +++ b/dotcom-rendering/src/model/front-schema.json @@ -241,9 +241,6 @@ "discussionD2Uid": { "type": "string" }, - "weatherapiurl": { - "type": "string" - }, "googleSearchUrl": { "type": "string" }, @@ -346,7 +343,6 @@ "supportUrl", "switches", "userAttributesApiUrl", - "weatherapiurl", "webTitle" ] }, diff --git a/dotcom-rendering/src/model/tag-page-schema.json b/dotcom-rendering/src/model/tag-page-schema.json index 0cee409dec3..be8da9d9169 100644 --- a/dotcom-rendering/src/model/tag-page-schema.json +++ b/dotcom-rendering/src/model/tag-page-schema.json @@ -1131,9 +1131,6 @@ "discussionD2Uid": { "type": "string" }, - "weatherapiurl": { - "type": "string" - }, "googleSearchUrl": { "type": "string" }, @@ -1236,7 +1233,6 @@ "supportUrl", "switches", "userAttributesApiUrl", - "weatherapiurl", "webTitle" ] }, diff --git a/dotcom-rendering/src/types/front.ts b/dotcom-rendering/src/types/front.ts index cb8f0477a88..a68347551a1 100644 --- a/dotcom-rendering/src/types/front.ts +++ b/dotcom-rendering/src/types/front.ts @@ -520,7 +520,6 @@ export type FEFrontConfigType = { stripePublicToken: string; googleRecaptchaSiteKey: string; discussionD2Uid: string; - weatherapiurl: string; googleSearchUrl: string; optimizeEpicUrl: string; stage: StageType; From b4ea0b2fd89321f88a52f05df15381da331ecc2a Mon Sep 17 00:00:00 2001 From: Anna Beddow Date: Thu, 9 Jan 2025 09:28:37 +0000 Subject: [PATCH 6/8] Podcast series image on cards (#13072) * Add fixed image sizes for podcast series image * Display podcast series image if available * Update flex styling to account for podcast type * refactor duplicated css styles --- dotcom-rendering/src/components/Card/Card.tsx | 54 +++++++++++++++++++ .../Card/components/ImageWrapper.tsx | 10 ++-- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/dotcom-rendering/src/components/Card/Card.tsx b/dotcom-rendering/src/components/Card/Card.tsx index c365f02e91e..18e5a04d50e 100644 --- a/dotcom-rendering/src/components/Card/Card.tsx +++ b/dotcom-rendering/src/components/Card/Card.tsx @@ -186,6 +186,35 @@ const HorizontalDivider = () => ( /> ); +const podcastImageStyles = (imageSize: ImageSizeType) => { + switch (imageSize) { + case 'small': + return css` + width: 69px; + height: 69px; + ${from.tablet} { + width: 98px; + height: 98px; + } + `; + + case 'medium': + return css` + width: 98px; + height: 98px; + ${from.tablet} { + width: 120px; + height: 120px; + } + `; + default: + return css` + width: 120px; + height: 120px; + `; + } +}; + const getMedia = ({ imageUrl, imageAltText, @@ -814,6 +843,31 @@ export const Card = ({ {media.type === 'crossword' && ( )} + + {media.type === 'podcast' && ( + <> + {media.podcastImage.src ? ( +
+ +
+ ) : ( + + )} + + )} )} diff --git a/dotcom-rendering/src/components/Card/components/ImageWrapper.tsx b/dotcom-rendering/src/components/Card/components/ImageWrapper.tsx index b575061c5fb..7fac7e984fa 100644 --- a/dotcom-rendering/src/components/Card/components/ImageWrapper.tsx +++ b/dotcom-rendering/src/components/Card/components/ImageWrapper.tsx @@ -135,12 +135,10 @@ export const ImageWrapper = ({ return (
Date: Thu, 9 Jan 2025 09:30:05 +0000 Subject: [PATCH 7/8] Render star rating on highlights card (#13104) * Render star rating on highlights card * Remove double negation * Use isundefined from libs * reinstate highlights checks after testing --- .../Masthead/HighlightsCard.stories.tsx | 13 ++++++++++ .../components/Masthead/HighlightsCard.tsx | 24 +++++++++++++++++++ .../ScrollableHighlights.importable.tsx | 1 + 3 files changed, 38 insertions(+) diff --git a/dotcom-rendering/src/components/Masthead/HighlightsCard.stories.tsx b/dotcom-rendering/src/components/Masthead/HighlightsCard.stories.tsx index c81762453a1..fea6d68f065 100644 --- a/dotcom-rendering/src/components/Masthead/HighlightsCard.stories.tsx +++ b/dotcom-rendering/src/components/Masthead/HighlightsCard.stories.tsx @@ -92,3 +92,16 @@ export const WithLiveKicker: Story = { parameters: {}, name: 'With Live Kicker', }; + +export const WithStarRating: Story = { + args: { + format: { + display: ArticleDisplay.Standard, + design: ArticleDesign.Standard, + theme: Pillar.Culture, + }, + starRating: 4, + }, + parameters: {}, + name: 'With Star Rating', +}; diff --git a/dotcom-rendering/src/components/Masthead/HighlightsCard.tsx b/dotcom-rendering/src/components/Masthead/HighlightsCard.tsx index fb795e98487..ad3a181f8b1 100644 --- a/dotcom-rendering/src/components/Masthead/HighlightsCard.tsx +++ b/dotcom-rendering/src/components/Masthead/HighlightsCard.tsx @@ -1,8 +1,10 @@ import { css } from '@emotion/react'; +import { isUndefined } from '@guardian/libs'; import { between, from, until } from '@guardian/source/foundations'; import { ArticleDesign, type ArticleFormat } from '../../lib/articleFormat'; import { isMediaCard } from '../../lib/cardHelpers'; import { palette } from '../../palette'; +import type { StarRating as Rating } from '../../types/content'; import type { DCRFrontImage } from '../../types/front'; import type { MainMedia } from '../../types/mainMedia'; import { Avatar } from '../Avatar'; @@ -12,6 +14,7 @@ import type { Loading } from '../CardPicture'; import { CardPicture } from '../CardPicture'; import { FormatBoundary } from '../FormatBoundary'; import { Icon } from '../MediaMeta'; +import { StarRating } from '../StarRating/StarRating'; export type HighlightsCardProps = { linkTo: string; @@ -26,6 +29,7 @@ export type HighlightsCardProps = { dataLinkName: string; byline?: string; isExternalLink: boolean; + starRating?: Rating; }; const gridContainer = css` @@ -37,6 +41,7 @@ const gridContainer = css` gap: 8px; grid-template-areas: 'headline headline' + 'rating rating' 'media-icon image'; /* Applied word-break: break-word to prevent text overflow @@ -121,6 +126,18 @@ const hoverStyles = css` } `; +const starWrapper = css` + background-color: ${palette('--star-rating-background')}; + color: ${palette('--star-rating-fill')}; + width: fit-content; + height: fit-content; + grid-area: rating; + ${from.desktop} { + grid-area: media-icon; + align-self: flex-end; + } +`; + export const HighlightsCard = ({ linkTo, format, @@ -134,6 +151,7 @@ export const HighlightsCard = ({ dataLinkName, byline, isExternalLink, + starRating, }: HighlightsCardProps) => { const showMediaIcon = isMediaCard(format); @@ -169,6 +187,12 @@ export const HighlightsCard = ({ />
+ {!isUndefined(starRating) ? ( +
+ +
+ ) : null} + {!!mainMedia && showMediaIcon && (
diff --git a/dotcom-rendering/src/components/ScrollableHighlights.importable.tsx b/dotcom-rendering/src/components/ScrollableHighlights.importable.tsx index e4c4e3c3631..d86cf905048 100644 --- a/dotcom-rendering/src/components/ScrollableHighlights.importable.tsx +++ b/dotcom-rendering/src/components/ScrollableHighlights.importable.tsx @@ -262,6 +262,7 @@ export const ScrollableHighlights = ({ trails }: Props) => { isExternalLink={trail.isExternalLink} showQuotedHeadline={trail.showQuotedHeadline} mainMedia={trail.mainMedia} + starRating={trail.starRating} /> ); From b3567e988120650948fdaea3b627343b6185b1b7 Mon Sep 17 00:00:00 2001 From: Anna Beddow Date: Thu, 9 Jan 2025 09:44:53 +0000 Subject: [PATCH 8/8] Correctly align outer sublinks and livelinks (#13087) * Correctly align sublinks and livelinks * Apply styles only to beta containers --- dotcom-rendering/src/components/Card/Card.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dotcom-rendering/src/components/Card/Card.tsx b/dotcom-rendering/src/components/Card/Card.tsx index 18e5a04d50e..f925dcd2539 100644 --- a/dotcom-rendering/src/components/Card/Card.tsx +++ b/dotcom-rendering/src/components/Card/Card.tsx @@ -1008,6 +1008,15 @@ export const Card = ({