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

wip: add link to author page in article header #3626

Closed
wants to merge 1 commit into from
Closed
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
54 changes: 52 additions & 2 deletions db/model/Gdoc/GdocBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,19 @@ import {
getVariableOfDatapageIfApplicable,
} from "../Variable.js"
import { createLinkFromUrl } from "../Link.js"
import { OwidGdoc, OwidGdocContent, OwidGdocType } from "@ourworldindata/types"
import {
OwidGdoc,
OwidGdocContent,
OwidGdocType,
DbRawAuthor,
DbEnrichedAuthor,
} from "@ourworldindata/types"
import { KnexReadonlyTransaction } from "../../db"

export class GdocBase implements OwidGdocBaseInterface {
id!: string
slug: string = ""
authors: DbEnrichedAuthor[] = []
content!: OwidGdocContent
published: boolean = false
createdAt: Date = new Date()
Expand Down Expand Up @@ -178,6 +185,10 @@ export class GdocBase implements OwidGdocBaseInterface {
return [...details]
}

async loadAuthors(knex: db.KnexReadonlyTransaction): Promise<void> {
this.authors = await getMinimalAuthorByNames(knex, this.content.authors)
}

get links(): DbInsertPostGdocLink[] {
const links: DbInsertPostGdocLink[] = []

Expand Down Expand Up @@ -643,8 +654,17 @@ export class GdocBase implements OwidGdocBaseInterface {
}

async loadLinkedDocuments(knex: db.KnexReadonlyTransaction): Promise<void> {
if (!this.authors.length) await this.loadAuthors(knex)

const authorIds = excludeNullish(
this.authors.map((author) => author.id)
)

const linkedDocuments: OwidGdocMinimalPostInterface[] =
await getMinimalGdocPostsByIds(knex, this.linkedDocumentIds)
await getMinimalGdocPostsByIds(knex, [
...this.linkedDocumentIds,
...authorIds,
])

this.linkedDocuments = keyBy(linkedDocuments, "id")
}
Expand Down Expand Up @@ -792,6 +812,8 @@ export class GdocBase implements OwidGdocBaseInterface {
}

async loadState(knex: db.KnexReadonlyTransaction): Promise<void> {
// TODO explain why we're loading authors first
await this.loadAuthors(knex)
await this.loadLinkedDocuments(knex)
await this.loadImageMetadataFromDB(knex)
await this.loadLinkedCharts(knex)
Expand Down Expand Up @@ -868,3 +890,31 @@ export async function getMinimalGdocPostsByIds(
} satisfies OwidGdocMinimalPostInterface
})
}

export async function getMinimalAuthorByNames(
knex: KnexReadonlyTransaction,
names: string[]
): Promise<DbEnrichedAuthor[]> {
if (names.length === 0) return []
const rows = await db.knexRaw<DbRawAuthor>(
knex,
`-- sql
SELECT
id,
content ->> '$.title' as title
FROM posts_gdocs
WHERE type = 'author'
AND content->>"$.title" in (:names)
AND published = 1`,
{ names }
)

const rowsByName = keyBy(rows, "title")

return names.map((name) => {
return {
id: rowsByName[name]?.id || null,
title: name,
}
})
}
4 changes: 4 additions & 0 deletions db/model/Gdoc/GdocFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export async function getGdocBaseObjectById(
const enrichedRow = parsePostsGdocsRow(row)
const gdoc: OwidGdocBaseInterface = {
...enrichedRow,
authors: [],
tags: null,
} satisfies OwidGdocBaseInterface
if (fetchLinkedTags) {
Expand Down Expand Up @@ -244,6 +245,7 @@ export async function getGdocBaseObjectBySlug(
const enrichedRow = parsePostsGdocsRow(row)
const gdoc: OwidGdocBaseInterface = {
...enrichedRow,
authors: [],
tags: null,
} satisfies OwidGdocBaseInterface
if (fetchLinkedTags) {
Expand Down Expand Up @@ -387,6 +389,7 @@ export async function getAndLoadPublishedDataInsights(
const enrichedRows = rows.map((row) => {
return {
...parsePostsGdocsRow(row),
authors: [],
tags: groupedTags[row.id] ? groupedTags[row.id] : null,
} satisfies OwidGdocBaseInterface
})
Expand Down Expand Up @@ -507,6 +510,7 @@ export function getDbEnrichedGdocFromOwidGdoc(
gdoc: OwidGdoc | GdocBase
): DbEnrichedPostGdoc {
const enrichedGdoc = {
authors: gdoc.authors,
breadcrumbs: gdoc.breadcrumbs,
content: gdoc.content,
createdAt: gdoc.createdAt,
Expand Down
16 changes: 12 additions & 4 deletions packages/@ourworldindata/types/src/dbTypes/PostsGdocs.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DbEnrichedAuthor } from "../domainTypes/Author.js"
import { BreadcrumbItem } from "../domainTypes/Site.js"
import { JsonString } from "../domainTypes/Various.js"
import {
Expand Down Expand Up @@ -25,6 +26,7 @@ export type DbEnrichedPostGdoc = Omit<
DbRawPostGdoc,
"content" | "breadcrumbs" | "published"
> & {
authors: DbEnrichedAuthor[]
content: OwidGdocContent
breadcrumbs: BreadcrumbItem[] | null
published: boolean
Expand Down Expand Up @@ -61,6 +63,7 @@ export function serializePostsGdocsBreadcrumbs(
export function parsePostsGdocsRow(row: DbRawPostGdoc): DbEnrichedPostGdoc {
return {
...row,
authors: [],
content: parsePostGdocContent(row.content),
breadcrumbs: parsePostsGdocsBreadcrumbs(row.breadcrumbs),
published: !!row.published,
Expand All @@ -72,15 +75,20 @@ export function parsePostsGdocsWithTagsRow(
): DBEnrichedPostGdocWithTags {
return {
...parsePostsGdocsRow(row),
authors: [],
tags: JSON.parse(row.tags),
}
}

export function serializePostsGdocsRow(row: DbEnrichedPostGdoc): DbRawPostGdoc {
const { authors: _authors, ...rowWithoutAuthors } = row

return {
...row,
content: serializePostGdocContent(row.content),
breadcrumbs: serializePostsGdocsBreadcrumbs(row.breadcrumbs),
published: row.published ? 1 : 0,
...rowWithoutAuthors,
content: serializePostGdocContent(rowWithoutAuthors.content),
breadcrumbs: serializePostsGdocsBreadcrumbs(
rowWithoutAuthors.breadcrumbs
),
published: rowWithoutAuthors.published ? 1 : 0,
}
}
10 changes: 10 additions & 0 deletions packages/@ourworldindata/types/src/domainTypes/Author.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
export interface DbRawAuthor {
id: string
title: string
}

export interface DbEnrichedAuthor {
id: string | null
title: string
}

export interface DbRawLatestWork {
id: string
slug: string
Expand Down
6 changes: 5 additions & 1 deletion packages/@ourworldindata/types/src/gdocTypes/Gdoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {
} from "./ArchieMlComponents.js"
import { DbChartTagJoin } from "../dbTypes/ChartTags.js"
import { MinimalTag } from "../dbTypes/Tags.js"
import { DbEnrichedLatestWork } from "../domainTypes/Author.js"
import {
DbEnrichedAuthor,
DbEnrichedLatestWork,
} from "../domainTypes/Author.js"

export enum OwidGdocPublicationContext {
unlisted = "unlisted",
Expand Down Expand Up @@ -59,6 +62,7 @@ export interface OwidGdocBaseInterface {
id: string
slug: string
// TODO: should we type this as a union of the possible content types instead?
authors: DbEnrichedAuthor[]
content: OwidGdocContent
published: boolean
createdAt: Date
Expand Down
2 changes: 2 additions & 0 deletions packages/@ourworldindata/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,8 @@ export { RedirectCode, type DbPlainRedirect } from "./dbTypes/Redirects.js"
export type { Nominal } from "./NominalType.js"

export {
type DbRawAuthor,
type DbEnrichedAuthor,
type DbRawLatestWork,
type DbEnrichedLatestWork,
parseLatestWork,
Expand Down
24 changes: 24 additions & 0 deletions site/gdocs/components/Byline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { DbEnrichedAuthor } from "@ourworldindata/types"
import React from "react"
import { useLinkedDocument } from "../utils.js"

export const Byline = ({ authors }: { authors: DbEnrichedAuthor[] }) => {
return (
<>
By:{" "}
{authors.map((author) => (
<LinkedAuthor key={author.title} author={author} />
))}
</>
)
}

const LinkedAuthor = ({ author }: { author: DbEnrichedAuthor }) => {
const gdocUrl = `https://docs.google.com/document/d/${author.id}`
const { linkedDocument } = useLinkedDocument(gdocUrl)

if (linkedDocument && linkedDocument.published && linkedDocument.slug) {
return <a href={`/${linkedDocument.slug}`}>{author.title}</a>
}
return <>{author.title}</>
}
32 changes: 9 additions & 23 deletions site/gdocs/components/OwidGdocHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import React from "react"
import cx from "classnames"
import {
BreadcrumbItem,
DbEnrichedAuthor,
OwidGdocPostContent,
OwidGdocType,
formatDate,
} from "@ourworldindata/utils"
import { formatAuthors } from "../../clientFormatting.js"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
import { faBook } from "@fortawesome/free-solid-svg-icons"
import { faCreativeCommons } from "@fortawesome/free-brands-svg-icons"
import Image from "./Image.js"
import { Breadcrumbs } from "../../Breadcrumb/Breadcrumb.js"
import { breadcrumbColorForCoverColor } from "../utils.js"
import { Byline } from "./Byline.js"

function OwidArticleHeader({
content,
Expand All @@ -21,7 +22,7 @@ function OwidArticleHeader({
breadcrumbs,
}: {
content: OwidGdocPostContent
authors: string[]
authors: DbEnrichedAuthor[]
publishedAt: Date | null
breadcrumbs?: BreadcrumbItem[]
}) {
Expand Down Expand Up @@ -79,12 +80,7 @@ function OwidArticleHeader({
<div className="centered-article-header__meta-container col-start-2 span-cols-6 span-md-cols-10 col-md-start-2 grid grid-cols-2 ">
<div className="span-cols-1 span-sm-cols-2">
<div className="centered-article-header__byline">
{"By: "}
<a href="/team">
{formatAuthors({
authors,
})}
</a>
<Byline authors={authors} />
</div>
<div className="centered-article-header__dateline body-3-medium-italic">
{content.dateline ||
Expand Down Expand Up @@ -121,7 +117,7 @@ function OwidTopicPageHeader({
authors,
}: {
content: OwidGdocPostContent
authors: string[]
authors: DbEnrichedAuthor[]
}) {
return (
<header className="topic-page-header grid span-cols-14 grid-cols-12-full-width">
Expand All @@ -132,12 +128,7 @@ function OwidTopicPageHeader({
{content.subtitle}
</p>
<p className="topic-page-header__byline col-start-2 span-cols-8 col-sm-start-2 span-sm-cols-12">
{"By "}
<a href="/team">
{formatAuthors({
authors,
})}
</a>
<Byline authors={authors} />
</p>
</header>
)
Expand All @@ -148,7 +139,7 @@ function OwidLinearTopicPageHeader({
authors,
}: {
content: OwidGdocPostContent
authors: string[]
authors: DbEnrichedAuthor[]
}) {
return (
<header className="topic-page-header grid span-cols-14 grid-cols-12-full-width">
Expand All @@ -159,12 +150,7 @@ function OwidLinearTopicPageHeader({
{content.subtitle}
</p>
<p className="topic-page-header__byline col-start-5 span-cols-6 col-md-start-3 span-md-cols-10 span-sm-cols-12 col-sm-start-2">
{"By "}
<a href="/team">
{formatAuthors({
authors,
})}
</a>
<Byline authors={authors} />
</p>
<p className="topic-page-header__dateline body-3-medium-italic col-start-5 span-cols-6 col-md-start-3 span-md-cols-10 span-sm-cols-12 col-sm-start-2">
{content.dateline}
Expand All @@ -175,7 +161,7 @@ function OwidLinearTopicPageHeader({

export function OwidGdocHeader(props: {
content: OwidGdocPostContent
authors: string[]
authors: DbEnrichedAuthor[]
publishedAt: Date | null
breadcrumbs?: BreadcrumbItem[]
}) {
Expand Down
3 changes: 2 additions & 1 deletion site/gdocs/pages/GdocPost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const citationDescriptionsByArticleType: Record<
}

export function GdocPost({
authors,
content,
publishedAt,
slug,
Expand Down Expand Up @@ -83,7 +84,7 @@ export function GdocPost({
>
<OwidGdocHeader
content={content}
authors={content.authors}
authors={authors}
publishedAt={publishedAt}
breadcrumbs={breadcrumbs ?? undefined}
/>
Expand Down
2 changes: 2 additions & 0 deletions site/gdocs/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export const useLinkedDocument = (
} else if (!linkedDocument.published) {
errorMessage = `Article with slug "${linkedDocument.slug}" isn't published.`
}

//todo replace with getCanonicalUrl
const subdirectory =
linkedDocument.type === OwidGdocType.DataInsight ? "data-insights/" : ""
return {
Expand Down
Loading