-
-
Notifications
You must be signed in to change notification settings - Fork 228
/
ChartList.tsx
168 lines (148 loc) · 5.16 KB
/
ChartList.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import React from "react"
import { observer } from "mobx-react"
import { runInAction, observable } from "mobx"
import { bind } from "decko"
import { AdminAppContext, AdminAppContextType } from "./AdminAppContext.js"
import {
GrapherChartType,
GrapherInterface,
GRAPHER_CHART_TYPES,
GRAPHER_TAB_OPTIONS,
} from "@ourworldindata/types"
import { startCase, DbChartTagJoin } from "@ourworldindata/utils"
import { getFullReferencesCount } from "./ChartEditor.js"
import { ChartRow } from "./ChartRow.js"
import { References } from "./AbstractChartEditor.js"
// These properties are coming from OldChart.ts
export interface ChartListItem {
// the first few entries mirror GrapherInterface, so take the types from there
id: GrapherInterface["id"]
title: GrapherInterface["title"]
slug: GrapherInterface["slug"]
internalNotes: GrapherInterface["internalNotes"]
variantName: GrapherInterface["variantName"]
isPublished: GrapherInterface["isPublished"]
tab: GrapherInterface["tab"]
hasMapTab: GrapherInterface["hasMapTab"]
type?: GrapherChartType
hasChartTab: boolean
lastEditedAt: string
lastEditedBy: string
publishedAt: string
publishedBy: string
hasParentIndicator?: boolean
isInheritanceEnabled?: boolean
tags: DbChartTagJoin[]
}
@observer
export class ChartList extends React.Component<{
charts: ChartListItem[]
searchHighlight?: (text: string) => string | React.ReactElement
onDelete?: (chart: ChartListItem) => void
}> {
static contextType = AdminAppContext
context!: AdminAppContextType
@observable availableTags: DbChartTagJoin[] = []
async fetchRefs(grapherId: number | undefined): Promise<References> {
const { admin } = this.context
const json =
grapherId === undefined
? {}
: await admin.getJSON(
`/api/charts/${grapherId}.references.json`
)
return json.references
}
@bind async onDeleteChart(chart: ChartListItem) {
const refs = await this.fetchRefs(chart.id)
if (getFullReferencesCount(refs) > 0) {
window.alert(
`Cannot delete chart ${
chart.slug
} because it is used in ${getFullReferencesCount(
refs
)} places. See the references tab in the chart editor for details.`
)
return
}
if (
!window.confirm(
`Delete the chart ${chart.slug}? This action cannot be undone!`
)
)
return
const json = await this.context.admin.requestJSON(
`/api/charts/${chart.id}`,
{},
"DELETE"
)
if (json.success) {
if (this.props.onDelete) this.props.onDelete(chart)
else
runInAction(() =>
this.props.charts.splice(
this.props.charts.indexOf(chart),
1
)
)
}
}
@bind async getTags() {
const json = await this.context.admin.getJSON("/api/tags.json")
runInAction(() => (this.availableTags = json.tags))
}
componentDidMount() {
void this.getTags()
}
render() {
const { charts, searchHighlight } = this.props
const { availableTags } = this
// if the first chart has inheritance information, we assume all charts have it
const showInheritanceColumn =
charts[0]?.isInheritanceEnabled !== undefined
return (
<table className="table table-bordered">
<thead>
<tr>
<th></th>
<th>Chart</th>
<th>Id</th>
<th>Type</th>
{showInheritanceColumn && <th>Inheritance</th>}
<th>Tags</th>
<th>Published</th>
<th>Last Updated</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{charts.map((chart) => (
<ChartRow
chart={chart}
key={chart.id}
availableTags={availableTags}
searchHighlight={searchHighlight}
onDelete={this.onDeleteChart}
showInheritanceColumn={showInheritanceColumn}
/>
))}
</tbody>
</table>
)
}
}
export function showChartType(chart: ChartListItem): string {
const chartType = chart.type
if (!chartType) return "Map"
const displayType = GRAPHER_CHART_TYPES[chartType]
? startCase(GRAPHER_CHART_TYPES[chartType])
: "Unknown"
if (chart.tab === GRAPHER_TAB_OPTIONS.map) {
if (chart.hasChartTab) return `Map + ${displayType}`
else return "Map"
} else {
if (chart.hasMapTab) return `${displayType} + Map`
else return displayType
}
}