Skip to content

Commit

Permalink
Implement feedback from QA
Browse files Browse the repository at this point in the history
  • Loading branch information
rakyi committed Dec 17, 2024
1 parent 42cbbf5 commit d707a42
Show file tree
Hide file tree
Showing 19 changed files with 222 additions and 28 deletions.
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
6 changes: 6 additions & 0 deletions db/model/Gdoc/enrichedToRaw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,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
29 changes: 29 additions & 0 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/1NfXOk8HVohVYjzJ1rtZYuw8h7kB9cWd5Kqxj4Dg1-WQ/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
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
2 changes: 2 additions & 0 deletions db/model/Gdoc/rawToEnriched.ts
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,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 @@ -1394,6 +1395,7 @@ function parseCallout(raw: RawBlockCallout): EnrichedBlockCallout {

return {
type: "callout",
icon: raw.value.icon,
parseErrors: [],
text: excludeNullish(enrichedTextBlocks),
title: raw.value.title,
Expand Down
Original file line number Diff line number Diff line change
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 @@ -511,13 +513,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, "")
}
13 changes: 5 additions & 8 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 @@ -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;
}
32 changes: 32 additions & 0 deletions site/gdocs/components/Callout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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
}) {
return (
<div className={className}>
{block.icon ? (
<FontAwesomeIcon
className="callout-icon"
icon={iconMap[block.icon]}
/>
) : null}
{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())
)
return (
<div className={className}>
<div className="col-start-2 span-cols-12">
Expand Down
10 changes: 9 additions & 1 deletion site/gdocs/components/People.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.people {
row-gap: 16px;
.article-block__text,
.article-block__list,
.article-block__numbered-list {
font-size: 16px;
}
}

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

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

@include lg-up {
.article-block__text {
@include body-3-medium;
Expand Down
22 changes: 22 additions & 0 deletions site/gdocs/components/Person.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
}
}

@include sm-only {
.person + .person {
margin-top: 16px;
}
}

.person-image-container {
display: flex;
flex: 0 0 193px;
Expand All @@ -21,6 +27,10 @@
}

.person-image {
picture {
display: flex; // Fix extra padding at the bottom.
}

img {
border-radius: 50%;
}
Expand All @@ -35,19 +45,31 @@
flex-direction: column;
gap: 2px;
margin-bottom: 8px;

a {
color: inherit;
}
}

.person-heading {
@include h2-bold;
margin: 0;

@include sm-only {
@include h3-bold;
margin: 0;
}
}

.person-title {
line-height: 19px;
color: $blue-60;
}

.person-socials {
margin-top: 16px;
margin-bottom: 16px;
font-size: 14px;

ul {
display: flex;
Expand Down
21 changes: 17 additions & 4 deletions site/gdocs/components/Person.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import * as React from "react"
import { useMediaQuery } from "usehooks-ts"

import { EnrichedBlockPerson } from "@ourworldindata/types"
import { getCanonicalUrl } from "@ourworldindata/components"
import { EnrichedBlockPerson, OwidGdocType } from "@ourworldindata/types"
import { SMALL_BREAKPOINT_MEDIA_QUERY } from "../../SiteConstants.js"
import { useLinkedDocument } from "../utils.js"
import { ArticleBlocks } from "./ArticleBlocks.js"
import Image from "./Image.js"
import { useMediaQuery } from "usehooks-ts"
import { SMALL_BREAKPOINT_MEDIA_QUERY } from "../../SiteConstants.js"
import { Socials } from "./Socials.js"

export default function Person({ person }: { person: EnrichedBlockPerson }) {
const { linkedDocument } = useLinkedDocument(person.url ?? "")
const isSmallScreen = useMediaQuery(SMALL_BREAKPOINT_MEDIA_QUERY)

const slug = linkedDocument?.slug
const url = slug
? getCanonicalUrl("", {
slug,
content: { type: OwidGdocType.Author },
})
: undefined

const heading = <h3 className="person-heading">{person.name}</h3>

const header = (
<div className="person-header">
<h3 className="person-heading h2-bold">{person.name}</h3>
{url ? <a href={url}>{heading}</a> : heading}
{person.title && (
<span className="person-title">{person.title}</span>
)}
Expand Down
Loading

0 comments on commit d707a42

Please sign in to comment.