Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gdocs): enable narrative charts inside key insights #4473

Merged
merged 3 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions adminSiteClient/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export const GDOC_DIFF_OMITTABLE_PROPERTIES = [
"linkedCharts",
"linkedDocuments",
"relatedCharts",
"linkedChartViews",
]
20 changes: 20 additions & 0 deletions db/model/Gdoc/GdocBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
})

Expand Down Expand Up @@ -796,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) {
Expand Down Expand Up @@ -840,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
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion db/model/Gdoc/enrichedToMarkdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions db/model/Gdoc/enrichedToRaw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
),
Expand Down
27 changes: 27 additions & 0 deletions db/model/Gdoc/exampleEnrichedBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [],
},
Expand Down
1 change: 1 addition & 0 deletions db/model/Gdoc/rawToArchie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
21 changes: 17 additions & 4 deletions db/model/Gdoc/rawToEnriched.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
const hasMoreThanOneResourceField =
Number(!!rawInsight.url) +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice 🙂

Number(!!rawInsight.filename) +
Number(!!rawInsight.narrativeChartName) >
1
if (hasMoreThanOneResourceField) {
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))
Expand Down Expand Up @@ -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)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ export type RawBlockKeyInsightsSlide = {
title?: string
filename?: string
url?: string
narrativeChartName?: string
content?: OwidRawGdocBlock[]
}

Expand All @@ -614,6 +615,7 @@ export type EnrichedBlockKeyInsightsSlide = {
title: string
filename?: string
url?: string
narrativeChartName?: string
content: OwidEnrichedGdocBlock[]
}

Expand Down
27 changes: 26 additions & 1 deletion site/gdocs/components/KeyInsights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -293,9 +294,11 @@ export const KeyInsights = ({
function renderAssetForInsight({
filename,
url,
narrativeChartName,
}: {
filename?: string
url?: string
narrativeChartName?: string
}): React.ReactElement | null {
if (filename) {
return (
Expand All @@ -313,6 +316,18 @@ export const KeyInsights = ({
/>
)
}
if (narrativeChartName) {
return (
<NarrativeChart
d={{
name: narrativeChartName,
type: "narrative-chart",
parseErrors: [],
}}
fullWidthOnMobile={true}
/>
)
}

return null
}
Expand All @@ -336,7 +351,16 @@ export const KeyInsights = ({
/>
<div className={KEY_INSIGHTS_SLIDES_CLASS_NAME}>
{insights.map(
({ title, content, filename, url }, idx) => {
(
{
title,
content,
filename,
url,
narrativeChartName,
},
idx
) => {
return (
<div
key={idx}
Expand Down Expand Up @@ -368,6 +392,7 @@ export const KeyInsights = ({
{renderAssetForInsight({
filename,
url,
narrativeChartName,
})}
</div>
</div>
Expand Down
Loading