forked from owid/owid-grapher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
VariablesIndexPage.tsx
118 lines (107 loc) · 3.65 KB
/
VariablesIndexPage.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
import * as React from "react"
import { observer } from "mobx-react"
import {
observable,
computed,
action,
runInAction,
reaction,
IReactionDisposer,
} from "mobx"
import * as lodash from "lodash"
import { AdminLayout } from "./AdminLayout"
import { SearchField, FieldsRow } from "./Forms"
import { VariableList, VariableListItem } from "./VariableList"
import { AdminAppContext, AdminAppContextType } from "./AdminAppContext"
@observer
export class VariablesIndexPage extends React.Component {
static contextType = AdminAppContext
context!: AdminAppContextType
@observable variables: VariableListItem[] = []
@observable maxVisibleRows = 50
@observable numTotalRows?: number
@observable searchInput?: string
@observable highlightSearch?: string
@computed get variablesToShow(): VariableListItem[] {
return this.variables
}
@action.bound onShowMore() {
this.maxVisibleRows += 100
}
render() {
const { variablesToShow, searchInput, numTotalRows } = this
const highlight = (text: string) => {
if (this.highlightSearch) {
const html = text.replace(
new RegExp(
this.highlightSearch.replace(
/[-\/\\^$*+?.()|[\]{}]/g,
"\\$&"
),
"i"
),
(s) => `<b>${s}</b>`
)
return <span dangerouslySetInnerHTML={{ __html: html }} />
} else return text
}
return (
<AdminLayout title="Variables">
<main className="DatasetsIndexPage">
<FieldsRow>
<span>
Showing {variablesToShow.length} of {numTotalRows}{" "}
variables
</span>
<SearchField
placeholder="Search all variables..."
value={searchInput}
onValue={action(
(v: string) => (this.searchInput = v)
)}
autofocus
/>
</FieldsRow>
<VariableList
variables={variablesToShow}
searchHighlight={highlight}
/>
{!searchInput && (
<button
className="btn btn-secondary"
onClick={this.onShowMore}
>
Show more variables...
</button>
)}
</main>
</AdminLayout>
)
}
async getData() {
const { searchInput, maxVisibleRows } = this
const json = await this.context.admin.getJSON("/api/variables.json", {
search: searchInput,
limit: maxVisibleRows,
})
runInAction(() => {
if (searchInput === this.searchInput) {
// Make sure this response is current
this.variables = json.variables
this.numTotalRows = json.numTotalRows
this.highlightSearch = searchInput
}
})
}
dispose!: IReactionDisposer
componentDidMount() {
this.dispose = reaction(
() => this.searchInput || this.maxVisibleRows,
lodash.debounce(() => this.getData(), 200)
)
this.getData()
}
componentWillUnmount() {
this.dispose()
}
}