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

✨ add data page metadata fields to admin #3006

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
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"typescript.preferences.useAliasesForRenames": false,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"typescript.preferences.importModuleSpecifierEnding": "js",
"javascript.preferences.importModuleSpecifierEnding": "js",
Expand Down
74 changes: 23 additions & 51 deletions adminSiteClient/DatasetEditPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import * as lodash from "lodash"
import { Prompt, Redirect } from "react-router-dom"
import filenamify from "filenamify"

import { OwidSource, ChartTagJoin } from "@ourworldindata/utils"
import { OwidSource, ChartTagJoin, OwidOrigin } from "@ourworldindata/utils"

import { AdminLayout } from "./AdminLayout.js"
import { Link } from "./Link.js"
import { BindString, Toggle, FieldsRow, Timeago } from "./Forms.js"
import { EditableTags } from "./EditableTags.js"
import { ChartList, ChartListItem } from "./ChartList.js"
import { OriginList } from "./OriginList.js"
import { SourceList } from "./SourceList.js"
import { VariableList, VariableListItem } from "./VariableList.js"
import { AdminAppContext, AdminAppContextType } from "./AdminAppContext.js"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
Expand All @@ -27,6 +29,7 @@ interface DatasetPageData {
version: string
isPrivate: boolean
nonRedistributable: boolean
updatePeriodDays: number

dataEditedAt: Date
dataEditedByUserId: number
Expand All @@ -40,15 +43,18 @@ interface DatasetPageData {
tags: { id: number; name: string }[]
variables: VariableListItem[]
charts: ChartListItem[]
source?: OwidSource
variableSources: OwidSource[]
zipFile?: { filename: string }

origins: OwidOrigin[]
}

class DatasetEditable {
@observable name: string = ""
@observable description: string = ""
@observable isPrivate: boolean = false
@observable nonRedistributable: boolean = false
@observable updatePeriodDays: number | undefined = undefined

@observable source: OwidSource = {
id: -1,
Expand Down Expand Up @@ -279,32 +285,6 @@ class DatasetEditor extends React.Component<{ dataset: DatasetPageData }> {
disabled={isDisabled}
helpText="Short name for this dataset, followed by the source and year. Example: Government Revenue Data – ICTD (2016)"
/>
<BindString
field="additionalInfo"
store={newDataset.source}
label="Description"
secondaryLabel="DB field: sources.description ->> '$.additionalInfo' - only the lowest id source is shown!"
textarea
disabled={isDisabled}
helpText="Describe the dataset and the methodology used in its construction. This can be as long and detailed as you like."
rows={10}
/>
<BindString
field="link"
store={newDataset.source}
label="Link"
secondaryLabel="DB field: sources.description ->> '$.link' - only the lowest id source is shown!"
disabled={isDisabled}
helpText="Link to the publication from which we retrieved this data"
/>
<BindString
field="retrievedDate"
store={newDataset.source}
label="Retrieved"
secondaryLabel="DB field: sources.description ->> '$.retrievedDate' - only the lowest id source is shown!"
disabled={isDisabled}
helpText="Date when this data was obtained by us. Date format should always be YYYY-MM-DD."
/>
<DatasetTagEditor
newDataset={newDataset}
availableTags={dataset.availableTags}
Expand Down Expand Up @@ -332,32 +312,13 @@ class DatasetEditor extends React.Component<{ dataset: DatasetPageData }> {
/>
</FieldsRow>
</div>

<div className="col">
<BindString
field="name"
store={newDataset.source}
label="Source name"
secondaryLabel="DB field: sources.description ->> '$.name' - only the lowest id source is shown!"
disabled={isDisabled}
helpText={`Short citation of the main sources, to be displayed on the charts. Additional sources (e.g. population denominator) should not be included. Use semi-colons to separate multiple sources e.g. "UN (2022); World Bank (2022)". For institutional datasets or reports, use "Institution, Project (year or vintage)" e.g. "IHME, Global Burden of Disease (2019)". For data we have modified extensively, use "Our World in Data based on X (year)" e.g. "Our World in Data based on Pew Research Center (2022)". For academic papers, use "Authors (year)" e.g. "Arroyo-Abad and Lindert (2016)".`}
/>

<BindString
field="dataPublishedBy"
store={newDataset.source}
label="Data published by"
secondaryLabel="DB field: sources.description ->> '$.dataPublishedBy' - only the lowest id source is shown!"
disabled={isDisabled}
helpText={`Full citation of main and additional sources. For academic papers, institutional datasets, and reports, use the complete citation recommended by the publisher. For data we have modified extensively, use "Our World in Data based on X (year) and Y (year)" e.g. "Our World in Data based on Pew Research Center (2022) and UN (2022)".`}
/>
<BindString
field="dataPublisherSource"
store={newDataset.source}
label="Data publisher's source"
secondaryLabel="DB field: sources.description ->> '$.dataPublisherSource' - only the lowest id source is shown!"
label="Number of days between OWID updates"
field="updatePeriodDays"
store={newDataset}
disabled={isDisabled}
helpText={`Optional field. Basic indication of how the publisher collected this data e.g. "Survey data". Anything longer than a line should go in the dataset description.`}
helpText="Date when this data was obtained by us. Date format should always be YYYY-MM-DD."
/>
<BindString
field="description"
Expand All @@ -376,6 +337,17 @@ class DatasetEditor extends React.Component<{ dataset: DatasetPageData }> {
/>
</form>
</section>
<section>
<h3>Origins</h3>
<OriginList origins={dataset.origins || []} />
</section>
{dataset.variableSources &&
dataset.variableSources.length > 0 && (
<section>
<h3>Sources</h3>
<SourceList sources={dataset.variableSources} />
</section>
)}
<section>
<h3>Indicators</h3>
<VariableList variables={dataset.variables} />
Expand Down
111 changes: 111 additions & 0 deletions adminSiteClient/OriginList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React from "react"
import { observer } from "mobx-react"
import { AdminAppContext, AdminAppContextType } from "./AdminAppContext.js"
import { OwidOrigin } from "@ourworldindata/utils"
import { BindString, FieldsRow } from "./Forms.js"

@observer
export class OriginList extends React.Component<{
origins: OwidOrigin[]
}> {
static contextType = AdminAppContext
context!: AdminAppContextType

render() {
const { origins } = this.props
const isDisabled = true

return (
<div>
{origins.map((origin, index) => (
<div key={index}>
<h4>{origin.title}</h4>
<FieldsRow>
<BindString
label="Title"
field="title"
store={origin}
disabled={isDisabled}
/>
<BindString
label="Title Snapshot"
field="titleSnapshot"
store={origin}
disabled={isDisabled}
/>
<BindString
label="Attribution"
field="attribution"
store={origin}
disabled={isDisabled}
/>
<BindString
label="Attribution Short"
field="attributionShort"
store={origin}
disabled={isDisabled}
/>
</FieldsRow>
<FieldsRow>
<BindString
label="Description"
field="description"
store={origin}
disabled={isDisabled}
textarea
/>
<BindString
label="Description Snapshot"
field="descriptionSnapshot"
store={origin}
disabled={isDisabled}
textarea
/>
<BindString
label="Citation Full"
field="citationFull"
store={origin}
disabled={isDisabled}
textarea
/>
<BindString
label="Producer"
field="producer"
store={origin}
disabled={isDisabled}
/>
</FieldsRow>
<FieldsRow>
<BindString
label="URL Main"
field="urlMain"
store={origin}
disabled={isDisabled}
/>
<BindString
label="URL Download"
field="urlDownload"
store={origin}
disabled={isDisabled}
/>
<BindString
label="Date Accessed"
field="dateAccessed"
store={origin}
disabled={isDisabled}
/>
<BindString
label="Date Published"
field="datePublished"
store={origin}
disabled={isDisabled}
/>
{/* Missing origin license... is it worth adding it? */}
</FieldsRow>
<hr />
</div>
))}
</div>
)
}
}
100 changes: 100 additions & 0 deletions adminSiteClient/SourceList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from "react"
import { observer } from "mobx-react"
import { AdminAppContext, AdminAppContextType } from "./AdminAppContext.js"
import { OwidSource } from "@ourworldindata/utils"
import { BindString } from "./Forms.js"

const MAX_SOURCES = 10

@observer
export class SourceList extends React.Component<{
sources: OwidSource[]
}> {
static contextType = AdminAppContext
context!: AdminAppContextType

render() {
const { sources } = this.props
const isDisabled = true

// limit sources to MAX_SOURCES, if there's over MAX_SOURCES, add a warning at the top
const sourcesLength = sources.length
if (sourcesLength > MAX_SOURCES) {
sources.length = MAX_SOURCES
}

return (
<div>
{sourcesLength > MAX_SOURCES && (
<div className="alert alert-warning">
<strong>Warning:</strong> There are {sourcesLength}{" "}
sources for this dataset. Only the first {MAX_SOURCES}{" "}
will be displayed.
</div>
)}
{sources.map((source, index) => (
<div key={index}>
<div className="row">
<div className="col">
<BindString
field="name"
store={source}
label="Source name"
secondaryLabel="DB field: sources.description ->> '$.name'"
disabled={isDisabled}
// helpText={`Short citation of the main sources, to be displayed on the charts. Additional sources (e.g. population denominator) should not be included. Use semi-colons to separate multiple sources e.g. "UN (2022); World Bank (2022)". For institutional datasets or reports, use "Institution, Project (year or vintage)" e.g. "IHME, Global Burden of Disease (2019)". For data we have modified extensively, use "Our World in Data based on X (year)" e.g. "Our World in Data based on Pew Research Center (2022)". For academic papers, use "Authors (year)" e.g. "Arroyo-Abad and Lindert (2016)".`}
/>
<BindString
field="dataPublishedBy"
store={source}
label="Data published by"
secondaryLabel="DB field: sources.description ->> '$.dataPublishedBy'"
disabled={isDisabled}
// helpText={`Full citation of main and additional sources. For academic papers, institutional datasets, and reports, use the complete citation recommended by the publisher. For data we have modified extensively, use "Our World in Data based on X (year) and Y (year)" e.g. "Our World in Data based on Pew Research Center (2022) and UN (2022)".`}
/>
<BindString
field="dataPublisherSource"
store={source}
label="Data publisher's source"
secondaryLabel="DB field: sources.description ->> '$.dataPublisherSource'"
disabled={isDisabled}
// helpText={`Optional field. Basic indication of how the publisher collected this data e.g. "Survey data". Anything longer than a line should go in the dataset description.`}
/>
<BindString
field="link"
store={source}
label="Link"
secondaryLabel="DB field: sources.description ->> '$.link'"
disabled={isDisabled}
// helpText="Link to the publication from which we retrieved this data"
/>
<BindString
field="retrievedDate"
store={source}
label="Retrieved"
secondaryLabel="DB field: sources.description ->> '$.retrievedDate'"
disabled={isDisabled}
// helpText="Date when this data was obtained by us. Date format should always be YYYY-MM-DD."
/>
</div>

<div className="col">
<BindString
field="additionalInfo"
store={source}
label="Additional info"
secondaryLabel="DB field: sources.description ->> '$.additionalInfo'"
textarea
disabled={isDisabled}
// helpText="Describe the dataset and the methodology used in its construction. This can be as long and detailed as you like."
rows={15}
/>
</div>
</div>
<hr />
</div>
))}
</div>
)
}
}
Loading
Loading