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

Implement feedback from QA #4297

Merged
merged 3 commits into from
Dec 19, 2024
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
12 changes: 11 additions & 1 deletion db/model/Gdoc/GdocBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,17 @@ export class GdocBase implements OwidGdocBaseInterface {
block: OwidEnrichedGdocBlock
): DbInsertPostGdocLink[] | void {
const links: DbInsertPostGdocLink[] = match(block)
.with({ type: "person" }, (block) => {
if (!block.url) return []
return [
createLinkFromUrl({
url: block.url,
source: this,
componentType: block.type,
text: block.name,
}),
]
})
.with({ type: "prominent-link" }, (block) => [
createLinkFromUrl({
url: block.url,
Expand Down Expand Up @@ -559,7 +570,6 @@ export class GdocBase implements OwidGdocBaseInterface {
"numbered-list",
"people",
"people-rows",
"person",
"pull-quote",
"sdg-grid",
"sdg-toc",
Expand Down
4 changes: 3 additions & 1 deletion db/model/Gdoc/enrichedToMarkdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ ${items}
)
.with({ type: "code" }, (b): string | undefined => {
return (
"```\n" + b.text.map((text) => text.value).join("\n") + "\n```"
"```\n" +
b.text.map((text) => text.value.text).join("\n") +
"\n```"
)
})
.with({ type: "donors" }, (_): string | undefined =>
Expand Down
11 changes: 10 additions & 1 deletion db/model/Gdoc/enrichedToRaw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,10 @@ export function enrichedBlockToRawBlock(
{ type: "code" },
(b): RawBlockCode => ({
type: b.type,
value: b.text,
value: b.text.map((text) => ({
type: "text",
value: text.value.text,
})),
})
)
.with(
Expand Down Expand Up @@ -228,7 +231,13 @@ export function enrichedBlockToRawBlock(
image: b.image,
name: b.name,
title: b.title,
url: b.url,
text: b.text.map(enrichedBlockToRawBlock) as RawBlockText[],
socials: b.socials?.map((social) => ({
type: social.type,
url: social.url,
text: social.text,
})),
},
})
)
Expand Down
37 changes: 35 additions & 2 deletions db/model/Gdoc/exampleEnrichedBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,36 @@ const enrichedBlockPerson: EnrichedBlockPerson = {
type: "person",
image: "example.png",
name: "Max Roser",
title: "Founder and Executive Co-Director",
url: "https://docs.google.com/document/d/7Kj2Pq5MvNxRzF8tLwB3nY9pQx4vC8mXkHs6jWn3-Hy/edit",
text: [enrichedBlockText],
socials: [
{
type: SocialLinkType.X,
url: "https://x.com/MaxCRoser",
text: "@MaxCRoser",
parseErrors: [],
},
{
type: SocialLinkType.Mastodon,
url: "https://mas.to/@maxroser",
text: "@maxroser",
parseErrors: [],
},
{
type: SocialLinkType.Bluesky,
url: "https://bsky.app/profile/maxroser.bsky.social",
text: "@maxroser.bsky.social",
parseErrors: [],
},
{
type: SocialLinkType.Threads,
url: "https://www.threads.net/@max.roser.ox",
text: "@max.roser.ox",
parseErrors: [],
},
],

parseErrors: [],
}

Expand Down Expand Up @@ -96,8 +125,12 @@ export const enrichedBlockExamples: Record<
type: "code",
text: [
{
type: "text",
value: '<iframe src="https://ourworldindata.org/grapher/children-per-woman-un?region=Africa&tab=map" loading="lazy" style="width: 100%; height: 600px; border: 0px none;" allow="web-share; clipboard-write"></iframe>',
type: "simple-text",
value: {
spanType: "span-simple-text",
text: '<iframe src="https://ourworldindata.org/grapher/children-per-woman-un?region=Africa&tab=map" loading="lazy" style="width: 100%; height: 600px; border: 0px none;" allow="web-share; clipboard-write"></iframe>',
},
parseErrors: [],
},
],
parseErrors: [],
Expand Down
10 changes: 10 additions & 0 deletions db/model/Gdoc/rawToArchie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,21 @@ function* rawBlockPersonToArchieMLString(
yield* propertyToArchieMLString("image", block.value)
yield* propertyToArchieMLString("name", block.value)
yield* propertyToArchieMLString("title", block.value)
yield* propertyToArchieMLString("url", block.value)
yield "[.+text]"
for (const b of block.value.text) {
yield* OwidRawGdocBlockToArchieMLStringGenerator(b)
}
yield "[]"
if (block.value.socials?.length) {
yield "[.socials]"
for (const b of block.value.socials) {
yield* propertyToArchieMLString("type", b)
yield* propertyToArchieMLString("url", b)
yield* propertyToArchieMLString("text", b)
}
yield "[]"
}
yield "{}"
}

Expand Down
16 changes: 14 additions & 2 deletions db/model/Gdoc/rawToEnriched.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,12 @@ const parseCode = (raw: RawBlockCode): EnrichedBlockCode => {
return {
type: "code",
text: raw.value.map((text) => ({
type: "text",
value: toAsciiQuotes(text.value),
type: "simple-text",
value: {
spanType: "span-simple-text",
text: toAsciiQuotes(text.value),
},
parseErrors: [],
})),
parseErrors: [],
}
Expand Down Expand Up @@ -843,6 +847,7 @@ const parsePerson = (raw: RawBlockPerson): EnrichedBlockPerson => {
image: raw.value.image,
name: raw.value.name,
title: raw.value.title,
url: extractUrl(raw.value.url),
text: raw.value.text.map(parseText),
socials: raw.value.socials?.map(parseSocialLink),
parseErrors: [],
Expand Down Expand Up @@ -1369,6 +1374,12 @@ function parseCallout(raw: RawBlockCallout): EnrichedBlockCallout {
text: [],
})

if (raw.value.icon && raw.value.icon !== "info") {
return createError({
message: "Only the 'info' icon is supported for callouts",
})
}

if (!raw.value.text) {
return createError({ message: "No text provided for callout block" })
}
Expand All @@ -1394,6 +1405,7 @@ function parseCallout(raw: RawBlockCallout): EnrichedBlockCallout {

return {
type: "callout",
icon: raw.value.icon,
rakyi marked this conversation as resolved.
Show resolved Hide resolved
parseErrors: [],
text: excludeNullish(enrichedTextBlocks),
title: raw.value.title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export type RawBlockCode = {

export type EnrichedBlockCode = {
type: "code"
text: RawBlockText[]
text: EnrichedBlockSimpleText[]
} & EnrichedBlockWithParseErrors

export type RawBlockDonorList = {
Expand Down Expand Up @@ -284,6 +284,7 @@ export type RawBlockPerson = {
image?: string
name: string
title?: string
url?: string
text: RawBlockText[]
socials?: RawSocialLink[]
}
Expand All @@ -305,6 +306,7 @@ export type EnrichedBlockPerson = {
image?: string
name: string
title?: string
url?: string
text: EnrichedBlockText[]
socials?: EnrichedSocialLink[]
} & EnrichedBlockWithParseErrors
Expand Down Expand Up @@ -366,6 +368,7 @@ export type EnrichedBlockSimpleText = {
type: "simple-text"
value: SpanSimpleText
} & EnrichedBlockWithParseErrors

export type RawBlockHtml = {
type: "html"
value: string
Expand Down Expand Up @@ -511,13 +514,15 @@ export type EnrichedBlockProminentLink = {
export type RawBlockCallout = {
type: "callout"
value: {
icon?: "info"
title?: string
text: (RawBlockText | RawBlockHeading | RawBlockList)[]
}
}

export type EnrichedBlockCallout = {
type: "callout"
icon?: "info"
title?: string
text: (EnrichedBlockText | EnrichedBlockHeading | EnrichedBlockList)[]
} & EnrichedBlockWithParseErrors
Expand Down
7 changes: 6 additions & 1 deletion packages/@ourworldindata/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,12 @@ export { Url, setWindowUrl, getWindowUrl } from "./urls/Url.js"

export { type UrlMigration, performUrlMigrations } from "./urls/UrlMigration.js"

export { camelCaseProperties, titleCase, toAsciiQuotes } from "./string.js"
export {
camelCaseProperties,
titleCase,
toAsciiQuotes,
removeDiacritics,
} from "./string.js"

export { serializeJSONForHTML, deserializeJSONFromHTML } from "./serializers.js"

Expand Down
5 changes: 5 additions & 0 deletions packages/@ourworldindata/utils/src/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ export const titleCase = (str: string): string => {
export function toAsciiQuotes(str: string): string {
return str.replace(/[“”]/g, '"').replace(/[‘’]/g, "'")
}

// https://stackoverflow.com/a/37511463/9846837
export function removeDiacritics(str: string): string {
return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "")
}
2 changes: 1 addition & 1 deletion site/gdocs/components/AllCharts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function AllCharts(props: AllChartsProps) {
className="article-block__heading h1-semibold"
id={ALL_CHARTS_ID}
>
{heading}
<span>{heading}</span>
<a
className="deep-link"
aria-labelledby={ALL_CHARTS_ID}
Expand Down
15 changes: 6 additions & 9 deletions site/gdocs/components/ArticleBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react"
import cx from "classnames"

import Callout from "./Callout.js"
import ChartStory from "./ChartStory.js"
import Scroller from "./Scroller.js"
import Chart from "./Chart.js"
Expand Down Expand Up @@ -248,7 +249,7 @@ export default function ArticleBlock({
.with({ type: "code" }, (block) => (
<CodeSnippet
className={getLayout("code-snippet", containerType)}
code={block.text.map((text) => text.value).join("\n")}
code={block.text.map((text) => text.value.text).join("\n")}
/>
))
.with({ type: "donors" }, (_block) => (
Expand All @@ -261,14 +262,10 @@ export default function ArticleBlock({
/>
))
.with({ type: "callout" }, (block) => (
<div className={getLayout("callout", containerType)}>
{block.title ? (
<h4 className="h4-semibold">{block.title}</h4>
) : null}
{block.text.map((textBlock, i) => (
<ArticleBlock key={i} b={textBlock} />
))}
</div>
<Callout
className={getLayout("callout", containerType)}
block={block}
/>
))
.with({ type: "chart-story" }, (block) => (
<ChartStory
Expand Down
3 changes: 3 additions & 0 deletions site/gdocs/components/Callout.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.callout-icon {
margin-right: 8px;
}
28 changes: 28 additions & 0 deletions site/gdocs/components/Callout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from "react"
import { EnrichedBlockCallout } from "@ourworldindata/types"
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { ArticleBlocks } from "./ArticleBlocks.js"

const iconMap = {
info: faInfoCircle,
}

export default function Callout({
className,
block,
}: {
className?: string
block: EnrichedBlockCallout
}) {
const icon = block.icon ? iconMap[block.icon] : null
return (
<div className={className}>
{icon && <FontAwesomeIcon className="callout-icon" icon={icon} />}
{block.title ? (
<h4 className="h4-semibold">{block.title}</h4>
) : null}
<ArticleBlocks blocks={block.text} />
</div>
)
}
6 changes: 4 additions & 2 deletions site/gdocs/components/Donors.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import * as React from "react"
import { groupBy } from "@ourworldindata/utils"
import { groupBy, removeDiacritics } from "@ourworldindata/utils"
import { useDonors } from "../utils.js"

export default function Donors({ className }: { className?: string }) {
const donors = useDonors()
if (!donors) return null

const donorsByLetter = groupBy(donors, (donor) => donor[0])
const donorsByLetter = groupBy(donors, (donor) =>
removeDiacritics(donor[0].toUpperCase())
Copy link
Member

Choose a reason for hiding this comment

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

I noticed this the first time around and though "oh that's cool, I guess we're embracing unicode multiculturalism" 😅

Guess someone else realized it was a bit silly 👍

Looks like it's not handling Ø though

image

And maybe we should just have a single "Other" heading at the bottom, because otherwise we'll get a new heading for each non-latin script name at the bottom.

Copy link
Contributor Author

@rakyi rakyi Dec 19, 2024

Choose a reason for hiding this comment

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

Both Marwa and I think this is fine (for now). The new code groups Í and I together, because they differ in diacritic and are ortherwise the same characters, but O with the slash is a different character than normal O. Same as e.g. Q.

)
return (
<div className={className}>
<div className="col-start-2 span-cols-12">
Expand Down
2 changes: 1 addition & 1 deletion site/gdocs/components/KeyInsights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ export const KeyInsights = ({
className="article-block__heading h1-semibold"
id={KEY_INSIGHTS_ID}
>
{heading}
<span>{heading}</span>
<a
className="deep-link"
aria-labelledby={KEY_INSIGHTS_ID}
Expand Down
18 changes: 17 additions & 1 deletion site/gdocs/components/People.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
.people {
row-gap: 16px;
display: grid;
row-gap: 48px;
margin-bottom: 24px;

.article-block__text,
.article-block__list,
.article-block__numbered-list {
font-size: 16px;
}

@include sm-only {
row-gap: 40px;
}
}

.people-cols-2 {
Expand All @@ -15,6 +27,10 @@
}

.people-cols-4 {
.person-heading {
font-size: 18px;
}

@include lg-up {
.article-block__text {
@include body-3-medium;
Expand Down
Loading
Loading