From 45b41c5de4c55843f6c9cc72f3ab05cbdad38aed Mon Sep 17 00:00:00 2001 From: sophiamersmann Date: Wed, 17 Jan 2024 16:04:58 +0000 Subject: [PATCH] :construction: (gdocs) add chart book component prototype --- db/model/Gdoc/GdocBase.ts | 3 +- db/model/Gdoc/enrichedToMarkdown.ts | 6 +++ db/model/Gdoc/enrichedToRaw.ts | 7 +++ db/model/Gdoc/exampleEnrichedBlocks.ts | 20 +++++++ db/model/Gdoc/rawToArchie.ts | 13 +++++ db/model/Gdoc/rawToEnriched.ts | 54 +++++++++++++++++++ .../types/src/gdocTypes/ArchieMlComponents.ts | 12 +++++ packages/@ourworldindata/types/src/index.ts | 2 + packages/@ourworldindata/utils/src/Util.ts | 6 +++ site/gdocs/components/ArticleBlock.tsx | 13 +++++ 10 files changed, 135 insertions(+), 1 deletion(-) diff --git a/db/model/Gdoc/GdocBase.ts b/db/model/Gdoc/GdocBase.ts index dcd30e8d8e9..55d3471b522 100644 --- a/db/model/Gdoc/GdocBase.ts +++ b/db/model/Gdoc/GdocBase.ts @@ -532,7 +532,8 @@ export class GdocBase extends BaseEntity implements OwidGdocBaseInterface { "sticky-right", "table", "text", - "key-indicator" + "key-indicator", + "chart-book" ), }, () => [] diff --git a/db/model/Gdoc/enrichedToMarkdown.ts b/db/model/Gdoc/enrichedToMarkdown.ts index e9ef6cb4f57..b765f847dd9 100644 --- a/db/model/Gdoc/enrichedToMarkdown.ts +++ b/db/model/Gdoc/enrichedToMarkdown.ts @@ -282,5 +282,11 @@ ${links}` exportComponents ) ) + .with({ type: "chart-book" }, (b): string | undefined => { + const keyIndicators = b.blocks.map((keyIndicatorBlock) => + enrichedBlockToMarkdown(keyIndicatorBlock, exportComponents) + ) + return `\n${keyIndicators.join("\n")}\n` + }) .exhaustive() } diff --git a/db/model/Gdoc/enrichedToRaw.ts b/db/model/Gdoc/enrichedToRaw.ts index 2c619fbed27..9f23b186a93 100644 --- a/db/model/Gdoc/enrichedToRaw.ts +++ b/db/model/Gdoc/enrichedToRaw.ts @@ -37,6 +37,7 @@ import { RawBlockTable, RawBlockBlockquote, RawBlockKeyIndicator, + RawBlockChartBook, } from "@ourworldindata/types" import { spanToHtmlString } from "./gdocUtils.js" import { match, P } from "ts-pattern" @@ -447,5 +448,11 @@ export function enrichedBlockToRawBlock( }, } }) + .with({ type: "chart-book" }, (b): RawBlockChartBook => { + return { + type: "chart-book", + value: b.blocks.map(enrichedBlockToRawBlock), + } + }) .exhaustive() } diff --git a/db/model/Gdoc/exampleEnrichedBlocks.ts b/db/model/Gdoc/exampleEnrichedBlocks.ts index 6316bba6dab..addd397c46d 100644 --- a/db/model/Gdoc/exampleEnrichedBlocks.ts +++ b/db/model/Gdoc/exampleEnrichedBlocks.ts @@ -541,4 +541,24 @@ export const enrichedBlockExamples: Record< blurb: [enrichedBlockText], parseErrors: [], }, + "chart-book": { + type: "chart-book", + blocks: [ + { + type: "key-indicator", + datapageUrl: + "https://ourworldindata.org/grapher/life-expectancy", + blurb: [enrichedBlockText], + parseErrors: [], + }, + { + type: "key-indicator", + datapageUrl: + "https://ourworldindata.org/grapher/share-of-population-in-extreme-poverty", + blurb: [enrichedBlockText], + parseErrors: [], + }, + ], + parseErrors: [], + }, } diff --git a/db/model/Gdoc/rawToArchie.ts b/db/model/Gdoc/rawToArchie.ts index cbec65b58cf..5a26542d9ca 100644 --- a/db/model/Gdoc/rawToArchie.ts +++ b/db/model/Gdoc/rawToArchie.ts @@ -36,6 +36,7 @@ import { RawBlockTableRow, RawBlockBlockquote, RawBlockKeyIndicator, + RawBlockChartBook, } from "@ourworldindata/types" import { isArray } from "@ourworldindata/utils" import { match } from "ts-pattern" @@ -639,6 +640,17 @@ function* rawBlockKeyIndicatorToArchieMLString( yield "{}" } +function* rawBlockChartBookToArchieMLString( + block: RawBlockChartBook +): Generator { + yield "[.+chart-book]" + if (typeof block.value !== "string") { + for (const b of block.value) + yield* OwidRawGdocBlockToArchieMLStringGenerator(b) + } + yield "[]" +} + export function* OwidRawGdocBlockToArchieMLStringGenerator( block: OwidRawGdocBlock | RawBlockTableRow ): Generator { @@ -704,6 +716,7 @@ export function* OwidRawGdocBlockToArchieMLStringGenerator( .with({ type: "table-row" }, rawBlockRowToArchieMLString) .with({ type: "blockquote" }, rawBlockBlockquoteToArchieMLString) .with({ type: "key-indicator" }, rawBlockKeyIndicatorToArchieMLString) + .with({ type: "chart-book" }, rawBlockChartBookToArchieMLString) .exhaustive() yield* content } diff --git a/db/model/Gdoc/rawToEnriched.ts b/db/model/Gdoc/rawToEnriched.ts index 3b5633e2748..993338a35a7 100644 --- a/db/model/Gdoc/rawToEnriched.ts +++ b/db/model/Gdoc/rawToEnriched.ts @@ -101,6 +101,8 @@ import { tableTemplates, RawBlockBlockquote, EnrichedBlockBlockquote, + RawBlockChartBook, + EnrichedBlockChartBook, } from "@ourworldindata/types" import { traverseEnrichedSpan, @@ -199,6 +201,7 @@ export function parseRawBlocksToEnrichedBlocks( .with({ type: "entry-summary" }, parseEntrySummary) .with({ type: "table" }, parseTable) .with({ type: "key-indicator" }, parseKeyIndicator) + .with({ type: "chart-book" }, parseChartBook) .exhaustive() } @@ -1936,3 +1939,54 @@ const parseKeyIndicator = ( parseErrors: parsedBlurbErrors, }) as EnrichedBlockKeyIndicator } + +function parseChartBook(raw: RawBlockChartBook): EnrichedBlockChartBook { + const createError = (error: ParseError): EnrichedBlockChartBook => ({ + type: "chart-book", + blocks: [], + parseErrors: [error], + }) + + const warnings = [] + + if (!Array.isArray(raw.value)) { + return createError({ + message: + "chart-book is not a freeform array. Make sure you've written [.+chart-book]", + }) + } + + const blocks = raw.value + const keyIndicatorBlocks = blocks.filter( + (block) => block.type === "key-indicator" + ) + + if (keyIndicatorBlocks.length < blocks.length) { + warnings.push({ + message: + "chart-book contains blocks that are not key-indicators blocks", + isWarning: true, + }) + } + + const parsedBlocks = compact( + keyIndicatorBlocks.map(parseRawBlocksToEnrichedBlocks) + ) as EnrichedBlockKeyIndicator[] + + if (parsedBlocks.length <= 1) { + const message = + parsedBlocks.length === 0 + ? "chart-book contains no key-indicator blocks" + : "chart-book contains only one key-indicator block" + warnings.push({ + message, + isWarning: true, + }) + } + + return { + type: "chart-book", + blocks: parsedBlocks, + parseErrors: warnings, + } +} diff --git a/packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts b/packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts index 9d5bfb12147..37b33c026fd 100644 --- a/packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts +++ b/packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts @@ -104,6 +104,16 @@ export type EnrichedBlockKeyIndicator = { title?: string } & EnrichedBlockWithParseErrors +export type RawBlockChartBook = { + type: "chart-book" + value: OwidRawGdocBlock[] +} + +export type EnrichedBlockChartBook = { + type: "chart-book" + blocks: EnrichedBlockKeyIndicator[] +} & EnrichedBlockWithParseErrors + export type RawBlockScroller = { type: "scroller" value: OwidRawGdocBlock[] | ArchieMLUnexpectedNonObjectValue @@ -742,6 +752,7 @@ export type OwidRawGdocBlock = | RawBlockTable | RawBlockBlockquote | RawBlockKeyIndicator + | RawBlockChartBook export type OwidEnrichedGdocBlock = | EnrichedBlockAllCharts @@ -780,3 +791,4 @@ export type OwidEnrichedGdocBlock = | EnrichedBlockTable | EnrichedBlockBlockquote | EnrichedBlockKeyIndicator + | EnrichedBlockChartBook diff --git a/packages/@ourworldindata/types/src/index.ts b/packages/@ourworldindata/types/src/index.ts index ba7c6ddf51a..8d2a00016f5 100644 --- a/packages/@ourworldindata/types/src/index.ts +++ b/packages/@ourworldindata/types/src/index.ts @@ -193,6 +193,7 @@ export { type RawBlockTopicPageIntro, type RawBlockUrl, type RawBlockKeyIndicator, + type RawBlockChartBook, tableTemplates, type TableTemplate, tableSizes, @@ -251,6 +252,7 @@ export { type EnrichedBlockTableRow, type EnrichedBlockTableCell, type EnrichedBlockKeyIndicator, + type EnrichedBlockChartBook, type RawBlockResearchAndWritingRow, } from "./gdocTypes/ArchieMlComponents.js" export { diff --git a/packages/@ourworldindata/utils/src/Util.ts b/packages/@ourworldindata/utils/src/Util.ts index bf1fe046df7..4efa5b6e2f4 100644 --- a/packages/@ourworldindata/utils/src/Util.ts +++ b/packages/@ourworldindata/utils/src/Util.ts @@ -1624,6 +1624,12 @@ export function traverseEnrichedBlocks( traverseEnrichedBlocks(node, callback, spanCallback) }) }) + .with({ type: "chart-book" }, (chartBook) => { + callback(chartBook) + chartBook.blocks.forEach((node) => + traverseEnrichedBlocks(node, callback, spanCallback) + ) + }) .with( { type: P.union( diff --git a/site/gdocs/components/ArticleBlock.tsx b/site/gdocs/components/ArticleBlock.tsx index dbd8506547f..b8c23892f1d 100644 --- a/site/gdocs/components/ArticleBlock.tsx +++ b/site/gdocs/components/ArticleBlock.tsx @@ -628,6 +628,19 @@ export default function ArticleBlock({ .with({ type: "key-indicator" }, (block) => ( )) + .with({ type: "chart-book" }, (block) => { + return ( + <> + {block.blocks.map((keyIndicatorBlock) => ( + + ))} + + ) + }) .exhaustive() return (