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

Data pages: Extract data page component IndicatorBrief #2839

Merged
merged 3 commits into from
Oct 24, 2023
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
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import React from "react"
import { faArrowDown } from "@fortawesome/free-solid-svg-icons/faArrowDown"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
import { ExpandableToggle } from "../ExpandableToggle/ExpandableToggle.js"
import { SimpleMarkdownText } from "../SimpleMarkdownText.js"
import {
DATAPAGE_SOURCES_AND_PROCESSING_SECTION_ID,
dayjs,
} from "@ourworldindata/utils"

interface IndicatorBriefProps {
descriptionShort: string | undefined
descriptionKey: string[] | undefined
hasFaqEntries: boolean
descriptionFromProducer: string | undefined
attributionShort: string | undefined
attribution: string
processedAdapted: string
dateRange: string | undefined
lastUpdated: string
nextUpdate: string | undefined
}

export const IndicatorBrief = (props: IndicatorBriefProps) => {
let descriptionKeyBulletPointsOrText: JSX.Element | null = null
const lastUpdated = dayjs(props.lastUpdated, ["YYYY", "YYYY-MM-DD"])
if (props.descriptionKey)
if (props.descriptionKey.length === 1)
descriptionKeyBulletPointsOrText = (
<SimpleMarkdownText text={props.descriptionKey[0]} />
)
else
descriptionKeyBulletPointsOrText = (
<ul className="article-block__list">
{props.descriptionKey.map((item, i) => (
<li key={i}>
<SimpleMarkdownText text={item} />
</li>
))}
</ul>
)

return (
<div className="key-info__wrapper wrapper grid grid-cols-12">
<div className="key-info__left col-start-2 span-cols-7 span-lg-cols-8 span-sm-cols-12">
{(props.descriptionShort || props.descriptionKey) && (
<div className="key-info__curated">
{props.descriptionShort ? (
<>
<h2 className="key-info__title">
About this data
</h2>
<div className="key-info__content article_block__text">
<SimpleMarkdownText
text={props.descriptionShort}
/>
</div>
</>
) : null}
{props.descriptionKey ? (
<>
<h2 className="key-info__title">
What you should know about this indicator
</h2>
<div className="key-info__content">
{descriptionKeyBulletPointsOrText}
</div>
</>
) : null}

{props.hasFaqEntries && (
<a className="key-info__learn-more" href="#faqs">
Learn more in the FAQs
<FontAwesomeIcon icon={faArrowDown} />
</a>
)}
</div>
)}
{props.descriptionFromProducer && (
<ExpandableToggle
label={
props.attributionShort
? `How does the producer of this data - ${props.attributionShort} - describe this data?`
: "How does the producer of this data describe this data?"
}
content={
<SimpleMarkdownText
text={props.descriptionFromProducer}
/>
}
isExpandedDefault={
!(props.descriptionShort || props.descriptionKey)
}
/>
)}
</div>
<div className="key-info__right grid grid-cols-3 grid-lg-cols-4 grid-sm-cols-12 span-cols-3 span-lg-cols-4 span-sm-cols-12">
<div className="key-data span-cols-3 span-lg-cols-4 span-sm-cols-12">
<div className="key-data__title">Source</div>
<div>
{props.attribution} – with{" "}
<a
href={`#${DATAPAGE_SOURCES_AND_PROCESSING_SECTION_ID}`}
>
{props.processedAdapted}
</a>{" "}
by Our World In Data
</div>
</div>
<div className="key-data span-cols-3 span-lg-cols-4 span-sm-cols-6">
<div className="key-data__title">Date range</div>
<div>{props.dateRange}</div>
</div>
<div className="key-data span-cols-3 span-lg-cols-4 span-sm-cols-6">
<div className="key-data__title">Last updated</div>
<div>{lastUpdated.format("MMMM D, YYYY")}</div>
</div>
{props.nextUpdate && (
<div className="key-data span-cols-3 span-lg-cols-4 span-sm-cols-6">
<div className="key-data__title">
Next expected update
</div>
<div>{props.nextUpdate}</div>
</div>
)}
</div>
</div>
)
}
4 changes: 4 additions & 0 deletions packages/@ourworldindata/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ export {
convertHeadingTextToId,
markdownToEnrichedTextBlock,
} from "./GdocsUtils.js"

export { ExpandableToggle } from "./ExpandableToggle/ExpandableToggle.js"

export { IndicatorBrief } from "./IndicatorBrief/IndicatorBrief.js"
2 changes: 1 addition & 1 deletion site/DataPageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect } from "react"
import { faArrowDown } from "@fortawesome/free-solid-svg-icons/faArrowDown"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
import { Grapher, GrapherInterface } from "@ourworldindata/grapher"
import { ExpandableToggle } from "./ExpandableToggle.js"
import { ExpandableToggle } from "@ourworldindata/components"
import ReactDOM from "react-dom"
import { GrapherWithFallback } from "./GrapherWithFallback.js"
import { formatAuthors } from "./clientFormatting.js"
Expand Down
161 changes: 20 additions & 141 deletions site/DataPageV2Content.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import React, { useEffect } from "react"
import { faArrowDown } from "@fortawesome/free-solid-svg-icons/faArrowDown"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
import { Grapher, GrapherInterface } from "@ourworldindata/grapher"
import { ExpandableToggle } from "./ExpandableToggle.js"
import {
ExpandableToggle,
markdownToEnrichedTextBlock,
IndicatorBrief,
} from "@ourworldindata/components"
import ReactDOM from "react-dom"
import { GrapherWithFallback } from "./GrapherWithFallback.js"
import { ArticleBlocks } from "./gdocs/ArticleBlocks.js"
import { RelatedCharts } from "./blocks/RelatedCharts.js"
import {
DataPageV2ContentFields,
excludeNullish,
slugify,
DATAPAGE_SOURCES_AND_PROCESSING_SECTION_ID,
EnrichedBlockList,
uniq,
pick,
OwidOrigin,
formatAuthors,
} from "@ourworldindata/utils"
import { markdownToEnrichedTextBlock } from "@ourworldindata/components"
import { AttachmentsContext, DocumentContext } from "./gdocs/OwidGdoc.js"
import StickyNav from "./blocks/StickyNav.js"
import cx from "classnames"
Expand Down Expand Up @@ -171,6 +170,7 @@ export const DataPageV2Content = ({
attributionFragments.length > 3
? `${attributionFragments[0]} and other sources`
: attributionFragments.join(", ")
const attributionUnshortened = attributionFragments.join(", ")
const processedAdapted =
datapageData.owidProcessingLevel === "minor"
? `minor processing`
Expand All @@ -195,35 +195,6 @@ export const DataPageV2Content = ({
relatedCharts = [],
} = faqEntries ?? {}

const keyInfoBlocks = datapageData?.descriptionKey
? excludeNullish(
datapageData.descriptionKey.flatMap(markdownToEnrichedTextBlock)
)
: undefined
const keyInfoBlocksAsList = keyInfoBlocks
? ({
type: "list",
items: keyInfoBlocks,
parseErrors: [],
} satisfies EnrichedBlockList)
: undefined

const keyInfo = keyInfoBlocksAsList ? (
<ArticleBlocks
blocks={[keyInfoBlocksAsList]}
containerType="datapage"
/>
) : null

const aboutThisData = datapageData?.descriptionShort ? (
<ArticleBlocks
blocks={[
markdownToEnrichedTextBlock(datapageData.descriptionShort),
]}
containerType="datapage"
/>
) : null

const citationFullBlockFn = (source: OriginSubset) => {
source.citationFull && (
<div
Expand Down Expand Up @@ -314,112 +285,20 @@ export const DataPageV2Content = ({
className="wrapper"
id="explore-the-data"
/>
<div className="key-info__wrapper wrapper grid grid-cols-12">
<div className="key-info__left col-start-2 span-cols-7 span-lg-cols-8 span-sm-cols-12">
{(datapageData?.descriptionKey ||
datapageData.descriptionShort) && (
<div className="key-info__curated">
{aboutThisData ? (
<>
<h2 className="key-info__title">
About this data
</h2>
<div className="key-info__content">
{aboutThisData}
</div>
</>
) : null}
{keyInfo ? (
<>
<h2 className="key-info__title">
What you should know about
this indicator
</h2>
<div className="key-info__content">
{keyInfo}
</div>
</>
) : null}

{!!faqEntries?.faqs.length && (
<a
className="key-info__learn-more"
href="#faqs"
>
Learn more in the FAQs
<FontAwesomeIcon
icon={faArrowDown}
/>
</a>
)}
</div>
)}
{datapageData.descriptionFromProducer && (
<ExpandableToggle
label={
datapageData.attributionShort
? `How does the producer of this data - ${datapageData.attributionShort} - describe this data?`
: "How does the producer of this data describe this data?"
}
content={
<ArticleBlocks
blocks={[
markdownToEnrichedTextBlock(
datapageData.descriptionFromProducer ??
""
),
]}
containerType="datapage"
/>
}
isExpandedDefault={
!(
datapageData.descriptionShort ||
datapageData.descriptionKey
)
}
/>
)}
</div>
<div className="key-info__right grid grid-cols-3 grid-lg-cols-4 grid-sm-cols-12 span-cols-3 span-lg-cols-4 span-sm-cols-12">
<div className="key-data span-cols-3 span-lg-cols-4 span-sm-cols-12">
<div className="key-data__title">
Source
</div>
<div>
{datapageData.attributions} – with{" "}
<a
href={`#${DATAPAGE_SOURCES_AND_PROCESSING_SECTION_ID}`}
>
{processedAdapted}
</a>{" "}
by Our World In Data
</div>
</div>
<div className="key-data span-cols-3 span-lg-cols-4 span-sm-cols-6">
<div className="key-data__title">
Date range
</div>
<div>{dateRange}</div>
</div>
<div className="key-data span-cols-3 span-lg-cols-4 span-sm-cols-6">
<div className="key-data__title">
Last updated
</div>
<div>
{lastUpdated.format("MMMM D, YYYY")}
</div>
</div>
{datapageData.nextUpdate && (
<div className="key-data span-cols-3 span-lg-cols-4 span-sm-cols-6">
<div className="key-data__title">
Next expected update
</div>
<div>{datapageData.nextUpdate}</div>
</div>
)}
</div>
</div>
<IndicatorBrief
descriptionShort={datapageData.descriptionShort}
descriptionKey={datapageData.descriptionKey}
hasFaqEntries={!!faqEntries?.faqs.length}
descriptionFromProducer={
datapageData.descriptionFromProducer
}
attributionShort={datapageData.attributionShort}
attribution={attributionUnshortened}
processedAdapted={processedAdapted}
dateRange={dateRange ?? undefined}
lastUpdated={datapageData.lastUpdated}
nextUpdate={datapageData.nextUpdate}
/>
</div>
<div className="wrapper">
{datapageData.relatedResearch &&
Expand Down
2 changes: 1 addition & 1 deletion site/owid.scss
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
@import "./gdocs/Chart.scss";
@import "./DataPage.scss";
@import "./DataPageContent.scss";
@import "./ExpandableToggle.scss";
@import "../packages/@ourworldindata/components/src/ExpandableToggle/ExpandableToggle.scss";
@import "./detailsOnDemand.scss";

/* HACK (Mispy): Fix search autozooming on iPhone Safari.
Expand Down
Loading