From 67dad6e5966b831f93fbf4b2599c5275d27be6fa Mon Sep 17 00:00:00 2001 From: Marcel Gerber Date: Tue, 21 Jan 2025 21:33:09 +0100 Subject: [PATCH 1/3] feat(gdocs): enable narrative charts inside key insights --- db/model/Gdoc/GdocBase.ts | 7 +++++ db/model/Gdoc/enrichedToMarkdown.ts | 8 +++++- db/model/Gdoc/enrichedToRaw.ts | 1 + db/model/Gdoc/exampleEnrichedBlocks.ts | 27 +++++++++++++++++++ db/model/Gdoc/rawToArchie.ts | 1 + db/model/Gdoc/rawToEnriched.ts | 21 ++++++++++++--- .../types/src/gdocTypes/ArchieMlComponents.ts | 2 ++ site/gdocs/components/KeyInsights.tsx | 27 ++++++++++++++++++- 8 files changed, 88 insertions(+), 6 deletions(-) diff --git a/db/model/Gdoc/GdocBase.ts b/db/model/Gdoc/GdocBase.ts index 9fc9741293..46dbafaebb 100644 --- a/db/model/Gdoc/GdocBase.ts +++ b/db/model/Gdoc/GdocBase.ts @@ -491,6 +491,13 @@ export class GdocBase implements OwidGdocBaseInterface { text: insight.title, }) links.push(insightLink) + } else if (insight.narrativeChartName) { + const insightLink = createLinkForChartView({ + name: insight.narrativeChartName, + source: this, + componentType: block.type, + }) + links.push(insightLink) } }) diff --git a/db/model/Gdoc/enrichedToMarkdown.ts b/db/model/Gdoc/enrichedToMarkdown.ts index 794700f30a..28be14ebc3 100644 --- a/db/model/Gdoc/enrichedToMarkdown.ts +++ b/db/model/Gdoc/enrichedToMarkdown.ts @@ -275,7 +275,13 @@ ${b.url}` { url: insight.url }, exportComponents ) - : undefined + : insight.narrativeChartName + ? markdownComponent( + "NarrativeChart", + { name: insight.narrativeChartName }, + exportComponents + ) + : undefined const content = enrichedBlocksToMarkdown( insight.content, diff --git a/db/model/Gdoc/enrichedToRaw.ts b/db/model/Gdoc/enrichedToRaw.ts index 08e8e1fa28..f090d2372e 100644 --- a/db/model/Gdoc/enrichedToRaw.ts +++ b/db/model/Gdoc/enrichedToRaw.ts @@ -428,6 +428,7 @@ export function enrichedBlockToRawBlock( title: insight.title, filename: insight.filename, url: insight.url, + narrativeChartName: insight.narrativeChartName, content: insight.content?.map((content) => enrichedBlockToRawBlock(content) ), diff --git a/db/model/Gdoc/exampleEnrichedBlocks.ts b/db/model/Gdoc/exampleEnrichedBlocks.ts index 74b2a0f884..66f3e085ed 100644 --- a/db/model/Gdoc/exampleEnrichedBlocks.ts +++ b/db/model/Gdoc/exampleEnrichedBlocks.ts @@ -440,6 +440,33 @@ export const enrichedBlockExamples: Record< }, ], }, + { + title: "Key insight number 3", + type: "key-insight-slide", + narrativeChartName: "world-has-become-less-democratic", + content: [ + { + type: "text", + parseErrors: [], + value: [ + { + spanType: "span-simple-text", + text: "I am the first paragraph of the third insight.", + }, + ], + }, + { + type: "text", + parseErrors: [], + value: [ + { + spanType: "span-simple-text", + text: "I am the second paragraph of the third insight.", + }, + ], + }, + ], + }, ], parseErrors: [], }, diff --git a/db/model/Gdoc/rawToArchie.ts b/db/model/Gdoc/rawToArchie.ts index b1b344a449..35eb35aa7b 100644 --- a/db/model/Gdoc/rawToArchie.ts +++ b/db/model/Gdoc/rawToArchie.ts @@ -562,6 +562,7 @@ function* rawKeyInsightsToArchieMLString( yield* propertyToArchieMLString("title", insight) yield* propertyToArchieMLString("filename", insight) yield* propertyToArchieMLString("url", insight) + yield* propertyToArchieMLString("narrativeChartName", insight) if (insight.content) { yield "[.+content]" for (const content of insight.content) { diff --git a/db/model/Gdoc/rawToEnriched.ts b/db/model/Gdoc/rawToEnriched.ts index 209fcc5984..afce9ae4bf 100644 --- a/db/model/Gdoc/rawToEnriched.ts +++ b/db/model/Gdoc/rawToEnriched.ts @@ -1597,16 +1597,25 @@ function parseKeyInsights(raw: RawBlockKeyInsights): EnrichedBlockKeyInsights { if (!rawInsight.title) { parseErrors.push({ message: "Key insight is missing a title" }) } - if (!rawInsight.url && !rawInsight.filename) { + if ( + !rawInsight.url && + !rawInsight.filename && + !rawInsight.narrativeChartName + ) { parseErrors.push({ message: - "Key insight is missing a url or filename. One of these two fields must be specified.", + "Key insight is missing a url, filename or narrativeChartName. One of these two fields must be specified.", }) } - if (rawInsight.url && rawInsight.filename) { + if ( + Number(!!rawInsight.url) + + Number(!!rawInsight.filename) + + Number(!!rawInsight.narrativeChartName) > + 1 + ) { parseErrors.push({ message: - "Key insight has both a url and a filename. Only one of these two fields can be specified.", + "Key insight has more than just one of the fields url, filename, narrativeChartName. Only one of these fields can be specified.", }) } const url = Url.fromURL(extractUrl(rawInsight.url)) @@ -1640,6 +1649,10 @@ function parseKeyInsights(raw: RawBlockKeyInsights): EnrichedBlockKeyInsights { if (rawInsight.filename) { enrichedInsight.filename = rawInsight.filename } + if (rawInsight.narrativeChartName) { + enrichedInsight.narrativeChartName = + rawInsight.narrativeChartName + } enrichedInsights.push(enrichedInsight) } } diff --git a/packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts b/packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts index 3d1130ea3e..50222fee90 100644 --- a/packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts +++ b/packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts @@ -598,6 +598,7 @@ export type RawBlockKeyInsightsSlide = { title?: string filename?: string url?: string + narrativeChartName?: string content?: OwidRawGdocBlock[] } @@ -614,6 +615,7 @@ export type EnrichedBlockKeyInsightsSlide = { title: string filename?: string url?: string + narrativeChartName?: string content: OwidEnrichedGdocBlock[] } diff --git a/site/gdocs/components/KeyInsights.tsx b/site/gdocs/components/KeyInsights.tsx index 0b283c5bc4..ead6e90c38 100644 --- a/site/gdocs/components/KeyInsights.tsx +++ b/site/gdocs/components/KeyInsights.tsx @@ -15,6 +15,7 @@ import { import { ArticleBlocks } from "./ArticleBlocks.js" import Image from "./Image.js" import Chart from "./Chart.js" +import NarrativeChart from "./NarrativeChart.js" export const KEY_INSIGHTS_CLASS_NAME = "key-insights" export const KEY_INSIGHTS_INSIGHT_PARAM = "insight" @@ -293,9 +294,11 @@ export const KeyInsights = ({ function renderAssetForInsight({ filename, url, + narrativeChartName, }: { filename?: string url?: string + narrativeChartName?: string }): React.ReactElement | null { if (filename) { return ( @@ -313,6 +316,18 @@ export const KeyInsights = ({ /> ) } + if (narrativeChartName) { + return ( + + ) + } return null } @@ -336,7 +351,16 @@ export const KeyInsights = ({ />
{insights.map( - ({ title, content, filename, url }, idx) => { + ( + { + title, + content, + filename, + url, + narrativeChartName, + }, + idx + ) => { return (
From b642da59a70bdaefa6e6c76da765d309513d0efe Mon Sep 17 00:00:00 2001 From: Marcel Gerber Date: Mon, 27 Jan 2025 13:23:31 +0100 Subject: [PATCH 2/3] enhance: address review comments --- adminSiteClient/constants.ts | 1 + db/model/Gdoc/rawToEnriched.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/adminSiteClient/constants.ts b/adminSiteClient/constants.ts index aac38f56c2..2bbc58ea27 100644 --- a/adminSiteClient/constants.ts +++ b/adminSiteClient/constants.ts @@ -9,4 +9,5 @@ export const GDOC_DIFF_OMITTABLE_PROPERTIES = [ "linkedCharts", "linkedDocuments", "relatedCharts", + "linkedChartViews", ] diff --git a/db/model/Gdoc/rawToEnriched.ts b/db/model/Gdoc/rawToEnriched.ts index afce9ae4bf..047d67ec6d 100644 --- a/db/model/Gdoc/rawToEnriched.ts +++ b/db/model/Gdoc/rawToEnriched.ts @@ -1607,12 +1607,12 @@ function parseKeyInsights(raw: RawBlockKeyInsights): EnrichedBlockKeyInsights { "Key insight is missing a url, filename or narrativeChartName. One of these two fields must be specified.", }) } - if ( + const hasMoreThanOneResourceField = Number(!!rawInsight.url) + Number(!!rawInsight.filename) + Number(!!rawInsight.narrativeChartName) > 1 - ) { + if (hasMoreThanOneResourceField) { parseErrors.push({ message: "Key insight has more than just one of the fields url, filename, narrativeChartName. Only one of these fields can be specified.", From 5b90d2c21be7622c7fd72afd76528237c752022d Mon Sep 17 00:00:00 2001 From: Marcel Gerber Date: Mon, 27 Jan 2025 13:26:46 +0100 Subject: [PATCH 3/3] enhance(gdocs): validate narrative chart components --- db/model/Gdoc/GdocBase.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/db/model/Gdoc/GdocBase.ts b/db/model/Gdoc/GdocBase.ts index 46dbafaebb..64e0c4fb00 100644 --- a/db/model/Gdoc/GdocBase.ts +++ b/db/model/Gdoc/GdocBase.ts @@ -803,6 +803,9 @@ export class GdocBase implements OwidGdocBaseInterface { const chartIdsBySlug = await mapSlugsToIds(knex) const publishedExplorersBySlug = await db.getPublishedExplorersBySlug(knex) + const chartViewNames = await getChartViewsInfo(knex) + .then((cv) => cv.map((c) => c.name)) + .then((chartViewNames) => new Set(chartViewNames)) const linkErrors: OwidGdocErrorMessage[] = [] for (const link of this.links) { @@ -847,6 +850,16 @@ export class GdocBase implements OwidGdocBaseInterface { } break } + case OwidGdocLinkType.ChartView: { + if (!chartViewNames.has(link.target)) { + linkErrors.push({ + property: "content", + message: `Narrative chart with name ${link.target} does not exist`, + type: OwidGdocErrorMessageType.Error, + }) + } + break + } } }