@cdc/core 4.25.3 → 4.25.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/icon-close.svg +1 -1
- package/components/Alert/components/Alert.tsx +1 -1
- package/components/DataTable/DataTable.tsx +18 -16
- package/components/DataTable/DataTableStandAlone.tsx +15 -9
- package/components/DataTable/components/CellAnchor.tsx +1 -1
- package/components/DataTable/components/ChartHeader.tsx +8 -5
- package/components/DataTable/components/DataTableEditorPanel.tsx +25 -3
- package/components/DataTable/components/MapHeader.tsx +1 -0
- package/components/DataTable/helpers/chartCellMatrix.tsx +14 -10
- package/components/DataTable/helpers/getChartCellValue.ts +42 -26
- package/components/DataTable/helpers/mapCellMatrix.tsx +25 -7
- package/components/DownloadButton.tsx +17 -2
- package/components/EditorPanel/DataTableEditor.tsx +1 -1
- package/components/EditorPanel/FootnotesEditor.tsx +76 -22
- package/components/EditorPanel/Inputs.tsx +12 -4
- package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +3 -2
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +51 -35
- package/components/Filters/Filters.tsx +158 -461
- package/components/Filters/components/Dropdown.tsx +39 -0
- package/components/Filters/components/Tabs.tsx +82 -0
- package/components/Filters/helpers/getChangedFilters.ts +31 -0
- package/components/Filters/helpers/getNestedOptions.ts +2 -2
- package/components/Filters/helpers/handleSorting.ts +2 -2
- package/components/Filters/helpers/tests/getChangedFilters.test.ts +92 -0
- package/components/Filters/helpers/tests/getNestedOptions.test.ts +31 -0
- package/components/Filters/index.ts +1 -1
- package/components/Footnotes/Footnotes.tsx +1 -1
- package/components/Footnotes/FootnotesStandAlone.tsx +8 -33
- package/components/Layout/components/Visualization/index.tsx +4 -3
- package/components/Legend/Legend.Gradient.tsx +68 -24
- package/components/MultiSelect/MultiSelect.tsx +3 -6
- package/components/MultiSelect/multiselect.styles.css +2 -0
- package/components/NestedDropdown/NestedDropdown.tsx +21 -21
- package/components/RichTooltip/RichTooltip.tsx +37 -0
- package/components/RichTooltip/richTooltip.css +16 -0
- package/components/Table/Table.tsx +142 -142
- package/components/Table/components/Row.tsx +1 -1
- package/components/Table/table.styles.css +10 -0
- package/components/_stories/DataTable.stories.tsx +9 -2
- package/components/_stories/Table.stories.tsx +1 -1
- package/components/_stories/styles.scss +0 -4
- package/components/ui/Accordion.jsx +8 -1
- package/components/ui/Title/index.tsx +4 -1
- package/components/ui/Title/{Title.scss → title.styles.css} +0 -2
- package/components/ui/_stories/Colors.stories.mdx +220 -0
- package/components/ui/_stories/IconGallery.stories.mdx +14 -0
- package/components/ui/_stories/Title.stories.tsx +29 -4
- package/components/ui/accordion.styles.css +3 -0
- package/data/colorPalettes.js +0 -1
- package/dist/cove-main.css +3 -8
- package/dist/cove-main.css.map +1 -1
- package/helpers/constants.ts +6 -0
- package/helpers/cove/accessibility.ts +7 -8
- package/helpers/cove/number.ts +5 -3
- package/helpers/coveUpdateWorker.ts +7 -1
- package/helpers/filterOrderOptions.ts +17 -0
- package/helpers/formatConfigBeforeSave.ts +19 -32
- package/helpers/isNumber.ts +20 -0
- package/helpers/isRightAlignedTableValue.js +1 -1
- package/helpers/pivotData.ts +16 -11
- package/helpers/tests/pivotData.test.ts +74 -0
- package/helpers/updateFieldFactory.ts +1 -0
- package/helpers/ver/4.25.3.ts +25 -2
- package/helpers/ver/4.25.4.ts +110 -0
- package/helpers/ver/4.25.6.ts +36 -0
- package/helpers/ver/tests/4.25.4.test.ts +89 -0
- package/helpers/ver/tests/4.25.6.test.ts +84 -0
- package/helpers/viewports.ts +4 -0
- package/package.json +7 -6
- package/styles/_global-variables.scss +3 -0
- package/styles/_reset.scss +0 -6
- package/styles/v2/main.scss +0 -5
- package/types/Axis.ts +2 -0
- package/types/DataSet.ts +14 -0
- package/types/Footnotes.ts +5 -2
- package/types/General.ts +1 -0
- package/types/Legend.ts +1 -0
- package/types/Table.ts +1 -0
- package/types/Visualization.ts +3 -12
- package/types/VizFilter.ts +3 -0
- package/components/ui/_stories/Colors.stories.tsx +0 -92
- package/components/ui/_stories/Icon.stories.tsx +0 -29
- package/helpers/cove/fontSettings.ts +0 -2
- package/helpers/isNumber.js +0 -24
- package/helpers/isNumberLog.js +0 -18
- /package/helpers/{fetchRemoteData.js → fetchRemoteData.ts} +0 -0
|
@@ -1,75 +1,129 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
1
2
|
import { UpdateFieldFunc } from '../../types/UpdateFieldFunc'
|
|
2
3
|
import _ from 'lodash'
|
|
3
4
|
import Footnotes, { Footnote } from '../../types/Footnotes'
|
|
4
5
|
import { footnotesSymbols } from '../../helpers/footnoteSymbols'
|
|
5
6
|
import InputSelect from '../inputs/InputSelect'
|
|
6
7
|
import { TextField } from './Inputs'
|
|
8
|
+
import { Datasets } from '@cdc/core/types/DataSet'
|
|
9
|
+
import DataTransform from '../../helpers/DataTransform'
|
|
10
|
+
import fetchRemoteData from '../../helpers/fetchRemoteData'
|
|
11
|
+
import Loader from '../Loader'
|
|
12
|
+
import { AnyVisualization } from '../../types/Visualization'
|
|
7
13
|
interface FootnotesEditorProps {
|
|
8
|
-
config:
|
|
9
|
-
updateField: UpdateFieldFunc<Footnote[]>
|
|
14
|
+
config: AnyVisualization
|
|
15
|
+
updateField: UpdateFieldFunc<Footnote[] | Object>
|
|
16
|
+
datasets: Datasets
|
|
10
17
|
}
|
|
11
18
|
|
|
12
|
-
const FootnotesEditor: React.FC<FootnotesEditorProps> = ({ config, updateField }) => {
|
|
19
|
+
const FootnotesEditor: React.FC<FootnotesEditorProps> = ({ config, updateField, datasets }) => {
|
|
20
|
+
const footnotesConfig = config.footnotes || {}
|
|
21
|
+
const [errorMessage, setErrorMessage] = useState('')
|
|
22
|
+
const [loadingAPIData, setLoadingAPIData] = useState(false)
|
|
23
|
+
const [datasetsCache, setDatasetsCache] = useState(datasets || {})
|
|
24
|
+
const transform = new DataTransform()
|
|
25
|
+
|
|
26
|
+
const fetchData = async datasetKey => {
|
|
27
|
+
const { data, dataUrl } = datasetsCache[datasetKey]
|
|
28
|
+
if (!dataUrl) return data
|
|
29
|
+
let newData = data
|
|
30
|
+
const noCachedData = dataUrl && !data
|
|
31
|
+
const dataSetChanged = datasetKey !== footnotesConfig.dataKey
|
|
32
|
+
setErrorMessage('')
|
|
33
|
+
if (dataSetChanged || noCachedData) {
|
|
34
|
+
setLoadingAPIData(true)
|
|
35
|
+
try {
|
|
36
|
+
newData = await fetchRemoteData(dataUrl)
|
|
37
|
+
newData = transform.autoStandardize(newData)
|
|
38
|
+
} catch (e) {
|
|
39
|
+
setErrorMessage('There was an issue loading the data source. Please check the datasource URL and try again.')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
setLoadingAPIData(false)
|
|
43
|
+
}
|
|
44
|
+
return newData
|
|
45
|
+
}
|
|
46
|
+
|
|
13
47
|
const addStaticFootnote = () => {
|
|
14
|
-
const newStaticNotes = [...(
|
|
15
|
-
updateField(
|
|
48
|
+
const newStaticNotes = [...(footnotesConfig.staticFootnotes || []), { text: 'Add Footnote Text' }]
|
|
49
|
+
updateField('footnotes', null, 'staticFootnotes', newStaticNotes)
|
|
16
50
|
}
|
|
17
51
|
|
|
18
52
|
const updateStaticFootnote = (footnoteIndex, footnoteUpdate: Footnote) => {
|
|
19
|
-
const footnoteCopy = _.cloneDeep(
|
|
53
|
+
const footnoteCopy = _.cloneDeep(footnotesConfig.staticFootnotes)
|
|
20
54
|
footnoteCopy[footnoteIndex] = footnoteUpdate
|
|
21
|
-
updateField(
|
|
55
|
+
updateField('footnotes', null, 'staticFootnotes', footnoteCopy)
|
|
22
56
|
}
|
|
23
57
|
|
|
24
58
|
const deleteStaticFootnote = footnoteIndex => {
|
|
25
|
-
const footnoteCopy = _.cloneDeep(
|
|
59
|
+
const footnoteCopy = _.cloneDeep(footnotesConfig.staticFootnotes)
|
|
26
60
|
footnoteCopy.splice(footnoteIndex, 1)
|
|
27
|
-
updateField(
|
|
61
|
+
updateField('footnotes', null, 'staticFootnotes', footnoteCopy)
|
|
28
62
|
}
|
|
29
63
|
|
|
30
64
|
const getOptions = (opts: string[]) => {
|
|
31
65
|
return [['', '--Select--']].concat(opts.map(key => [key, key]))
|
|
32
66
|
}
|
|
33
67
|
|
|
34
|
-
const
|
|
68
|
+
const dataColumns = footnotesConfig.dataKey
|
|
69
|
+
? getOptions(Object.keys(datasetsCache[footnotesConfig.dataKey]?.data?.[0] || {}))
|
|
70
|
+
: []
|
|
71
|
+
const dataSetOptions = getOptions(Object.keys(datasetsCache))
|
|
72
|
+
|
|
73
|
+
const changeFootnoteDataKey = async value => {
|
|
74
|
+
if (value) {
|
|
75
|
+
if (!datasetsCache[value]) {
|
|
76
|
+
const newData = await fetchData(value)
|
|
77
|
+
setDatasetsCache({ ...datasetsCache, [value]: { ...datasetsCache[value], data: newData } })
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
updateField('footnotes', null, 'dynamicFootnotes', {})
|
|
81
|
+
}
|
|
35
82
|
|
|
36
|
-
|
|
37
|
-
|
|
83
|
+
updateField('footnotes', null, 'dataKey', value)
|
|
84
|
+
}
|
|
38
85
|
return (
|
|
39
86
|
<>
|
|
87
|
+
{loadingAPIData && <Loader fullScreen />}
|
|
40
88
|
<em>Dynamic Footnotes</em>
|
|
41
89
|
<div className='row border p-2'>
|
|
42
90
|
<InputSelect
|
|
43
91
|
label='Select a Footnote Dataset'
|
|
44
|
-
value={
|
|
92
|
+
value={footnotesConfig.dataKey}
|
|
45
93
|
options={dataSetOptions}
|
|
46
94
|
fieldName='dataKey'
|
|
47
|
-
updateField={
|
|
95
|
+
updateField={(section, subsection, fieldname, dataKey) => {
|
|
96
|
+
changeFootnoteDataKey(dataKey)
|
|
97
|
+
}}
|
|
48
98
|
/>
|
|
99
|
+
{errorMessage && <p className='text-danger'>{errorMessage}</p>}
|
|
49
100
|
|
|
50
|
-
{
|
|
101
|
+
{footnotesConfig.dataKey && (
|
|
51
102
|
<div className='p-3'>
|
|
52
103
|
<InputSelect
|
|
53
104
|
label='Footnote Symbol Column'
|
|
54
|
-
value={
|
|
105
|
+
value={footnotesConfig.dynamicFootnotes?.symbolColumn}
|
|
55
106
|
options={dataColumns}
|
|
56
|
-
section='
|
|
107
|
+
section='footnotes'
|
|
108
|
+
subsection='dynamicFootnotes'
|
|
57
109
|
fieldName='symbolColumn'
|
|
58
110
|
updateField={updateField}
|
|
59
111
|
/>
|
|
60
112
|
<InputSelect
|
|
61
113
|
label='Footnote Text Column'
|
|
62
|
-
value={
|
|
114
|
+
value={footnotesConfig.dynamicFootnotes?.textColumn}
|
|
63
115
|
options={dataColumns}
|
|
64
|
-
section='
|
|
116
|
+
section='footnotes'
|
|
117
|
+
subsection='dynamicFootnotes'
|
|
65
118
|
fieldName='textColumn'
|
|
66
119
|
updateField={updateField}
|
|
67
120
|
/>
|
|
68
121
|
<InputSelect
|
|
69
122
|
label='Footnote Order Column'
|
|
70
|
-
value={
|
|
123
|
+
value={footnotesConfig.dynamicFootnotes?.orderColumn}
|
|
71
124
|
options={dataColumns}
|
|
72
|
-
section='
|
|
125
|
+
section='footnotes'
|
|
126
|
+
subsection='dynamicFootnotes'
|
|
73
127
|
fieldName='orderColumn'
|
|
74
128
|
updateField={updateField}
|
|
75
129
|
/>
|
|
@@ -81,7 +135,7 @@ const FootnotesEditor: React.FC<FootnotesEditorProps> = ({ config, updateField }
|
|
|
81
135
|
|
|
82
136
|
<em>Static Footnotes</em>
|
|
83
137
|
|
|
84
|
-
{
|
|
138
|
+
{footnotesConfig.staticFootnotes?.map((note, index) => (
|
|
85
139
|
<div key={index} className='row border p-2'>
|
|
86
140
|
<div className='col-8'>
|
|
87
141
|
<InputSelect
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { memo, useEffect, useState } from 'react'
|
|
2
2
|
import { useDebounce } from 'use-debounce'
|
|
3
|
-
import { DROPDOWN_STYLES } from '../Filters/
|
|
3
|
+
import { DROPDOWN_STYLES } from '../Filters/components/Dropdown'
|
|
4
4
|
|
|
5
5
|
export type Input = {
|
|
6
6
|
label: string
|
|
@@ -118,9 +118,17 @@ const CheckBox = memo((props: CheckboxProps) => {
|
|
|
118
118
|
return <></>
|
|
119
119
|
}
|
|
120
120
|
return (
|
|
121
|
-
<label
|
|
121
|
+
<label
|
|
122
|
+
className='checkbox column-heading'
|
|
123
|
+
onClick={e => {
|
|
124
|
+
if (!['SPAN', 'INPUT'].includes(e.target.nodeName)) {
|
|
125
|
+
e.preventDefault()
|
|
126
|
+
}
|
|
127
|
+
}}
|
|
128
|
+
>
|
|
122
129
|
<input
|
|
123
130
|
type='checkbox'
|
|
131
|
+
className='edit-checkbox'
|
|
124
132
|
name={fieldName}
|
|
125
133
|
checked={value}
|
|
126
134
|
onChange={e => {
|
|
@@ -161,7 +169,7 @@ const Select = memo((props: SelectProps) => {
|
|
|
161
169
|
initial: initialValue,
|
|
162
170
|
...attributes
|
|
163
171
|
} = props
|
|
164
|
-
const optionsJsx = options
|
|
172
|
+
const optionsJsx = options?.map((option, index) => {
|
|
165
173
|
if (typeof option === 'string') {
|
|
166
174
|
return (
|
|
167
175
|
<option value={option} key={index}>
|
|
@@ -178,7 +186,7 @@ const Select = memo((props: SelectProps) => {
|
|
|
178
186
|
})
|
|
179
187
|
|
|
180
188
|
if (initialValue) {
|
|
181
|
-
optionsJsx
|
|
189
|
+
optionsJsx?.unshift(
|
|
182
190
|
<option value='' key='initial'>
|
|
183
191
|
{initialValue}
|
|
184
192
|
</option>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import { SubGrouping, VizFilter, OrderBy } from '../../../types/VizFilter'
|
|
3
|
-
import {
|
|
3
|
+
import { handleSorting } from '../../Filters/helpers/handleSorting'
|
|
4
|
+
import { filterOrderOptions } from '../../../helpers/filterOrderOptions'
|
|
4
5
|
import FilterOrder from './components/FilterOrder'
|
|
5
6
|
import { Visualization } from '../../../types/Visualization'
|
|
6
7
|
import { useMemo } from 'react'
|
|
@@ -266,7 +267,7 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
|
|
|
266
267
|
const orderedSubGroupValues = subGrouping.valuesLookup[groupName].orderedValues
|
|
267
268
|
return (
|
|
268
269
|
<div key={`group-subgroup-values-${groupName}-${i}`}>
|
|
269
|
-
<span className='font-weight-bold'>{groupName}</span>
|
|
270
|
+
<span className='font-weight-bold fw-bold'>{groupName}</span>
|
|
270
271
|
<FilterOrder
|
|
271
272
|
key={`subgroup-values-${groupName}-${i}`}
|
|
272
273
|
orderedValues={orderedSubGroupValues}
|
|
@@ -5,7 +5,9 @@ import { Visualization } from '../../../types/Visualization'
|
|
|
5
5
|
import { UpdateFieldFunc } from '../../../types/UpdateFieldFunc'
|
|
6
6
|
import _ from 'lodash'
|
|
7
7
|
import { MultiSelectFilter, VizFilter, VizFilterStyle } from '../../../types/VizFilter'
|
|
8
|
-
import {
|
|
8
|
+
import { handleSorting } from '../../Filters/helpers/handleSorting'
|
|
9
|
+
import { filterOrderOptions } from '../../../helpers/filterOrderOptions'
|
|
10
|
+
import { filterStyleOptions } from '../../Filters'
|
|
9
11
|
import FieldSetWrapper from '../FieldSetWrapper'
|
|
10
12
|
|
|
11
13
|
import FilterOrder from './components/FilterOrder'
|
|
@@ -17,9 +19,10 @@ type VizFilterProps = {
|
|
|
17
19
|
config: Visualization
|
|
18
20
|
updateField: UpdateFieldFunc<string | VizFilter[] | VizFilter>
|
|
19
21
|
rawData: Object[]
|
|
22
|
+
hasFootnotes?: boolean
|
|
20
23
|
}
|
|
21
24
|
|
|
22
|
-
const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawData }) => {
|
|
25
|
+
const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawData, hasFootnotes }) => {
|
|
23
26
|
const openControls = useState({})
|
|
24
27
|
const dataColumns = useMemo(() => {
|
|
25
28
|
return _.uniq(_.flatten(rawData?.map(row => Object.keys(row))))
|
|
@@ -169,20 +172,6 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
169
172
|
options={filterStyleOptions}
|
|
170
173
|
/>
|
|
171
174
|
|
|
172
|
-
<Select
|
|
173
|
-
value={filter.defaultValue}
|
|
174
|
-
options={
|
|
175
|
-
filter.resetLabel
|
|
176
|
-
? [filter.resetLabel, ...config.filters?.[filterIndex].values]
|
|
177
|
-
: config.filters?.[filterIndex].values
|
|
178
|
-
}
|
|
179
|
-
updateField={(_section, _subSection, _key, value) => {
|
|
180
|
-
updateFilterDefaultValue(filterIndex, value)
|
|
181
|
-
}}
|
|
182
|
-
label='Filter Default Value'
|
|
183
|
-
initial='Select'
|
|
184
|
-
/>
|
|
185
|
-
|
|
186
175
|
{filter.filterStyle !== 'nested-dropdown' ? (
|
|
187
176
|
<>
|
|
188
177
|
<Select
|
|
@@ -194,16 +183,21 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
194
183
|
initial='- Select Option -'
|
|
195
184
|
/>
|
|
196
185
|
|
|
197
|
-
|
|
198
|
-
<
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
186
|
+
{filter.columnName && (
|
|
187
|
+
<Select
|
|
188
|
+
value={filter.defaultValue}
|
|
189
|
+
options={
|
|
190
|
+
filter.resetLabel
|
|
191
|
+
? [filter.resetLabel, ...config.filters?.[filterIndex].values]
|
|
192
|
+
: config.filters?.[filterIndex].values
|
|
193
|
+
}
|
|
194
|
+
updateField={(_section, _subSection, _key, value) => {
|
|
195
|
+
updateFilterDefaultValue(filterIndex, value)
|
|
204
196
|
}}
|
|
197
|
+
label='Filter Default Value'
|
|
198
|
+
initial='Select'
|
|
205
199
|
/>
|
|
206
|
-
|
|
200
|
+
)}
|
|
207
201
|
|
|
208
202
|
<label>
|
|
209
203
|
<span className='edit-label column-heading'>Label</span>
|
|
@@ -238,17 +232,6 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
238
232
|
/>
|
|
239
233
|
)}
|
|
240
234
|
|
|
241
|
-
<label>
|
|
242
|
-
<span className='edit-label column-heading'>Default Value Set By Query String Parameter</span>
|
|
243
|
-
<input
|
|
244
|
-
type='text'
|
|
245
|
-
value={filter.setByQueryParameter}
|
|
246
|
-
onChange={e => {
|
|
247
|
-
updateFilterProp('setByQueryParameter', filterIndex, e.target.value)
|
|
248
|
-
}}
|
|
249
|
-
/>
|
|
250
|
-
</label>
|
|
251
|
-
|
|
252
235
|
<Select
|
|
253
236
|
value={filter.order || 'asc'}
|
|
254
237
|
fieldName='order'
|
|
@@ -276,6 +259,27 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
276
259
|
options={dataColumns}
|
|
277
260
|
/>
|
|
278
261
|
)}
|
|
262
|
+
<label>
|
|
263
|
+
<span className='edit-label column-heading'>Default Value Set By Query String Parameter</span>
|
|
264
|
+
<input
|
|
265
|
+
type='text'
|
|
266
|
+
value={filter.setByQueryParameter}
|
|
267
|
+
onChange={e => {
|
|
268
|
+
updateFilterProp('setByQueryParameter', filterIndex, e.target.value)
|
|
269
|
+
}}
|
|
270
|
+
/>
|
|
271
|
+
</label>
|
|
272
|
+
|
|
273
|
+
<label>
|
|
274
|
+
<input
|
|
275
|
+
type='checkbox'
|
|
276
|
+
checked={filter.showDropdown === undefined ? true : filter.showDropdown}
|
|
277
|
+
onChange={e => {
|
|
278
|
+
updateFilterProp('showDropdown', filterIndex, e.target.checked)
|
|
279
|
+
}}
|
|
280
|
+
/>
|
|
281
|
+
<span className='edit-showDropdown column-heading'>Show Filter</span>
|
|
282
|
+
</label>
|
|
279
283
|
</>
|
|
280
284
|
) : (
|
|
281
285
|
<NestedDropdownEditor
|
|
@@ -289,6 +293,18 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
289
293
|
updateFilterStyle={updateFilterStyle}
|
|
290
294
|
/>
|
|
291
295
|
)}
|
|
296
|
+
{hasFootnotes && (
|
|
297
|
+
<label>
|
|
298
|
+
<input
|
|
299
|
+
type='checkbox'
|
|
300
|
+
checked={!!filter.filterFootnotes}
|
|
301
|
+
onChange={e => {
|
|
302
|
+
updateFilterProp('filterFootnotes', filterIndex, e.target.checked)
|
|
303
|
+
}}
|
|
304
|
+
/>
|
|
305
|
+
<span className='edit-showDropdown column-heading'>Filter Footnotes</span>
|
|
306
|
+
</label>
|
|
307
|
+
)}
|
|
292
308
|
<label>
|
|
293
309
|
<span className='edit-label column-heading'>
|
|
294
310
|
Filter Parents{' '}
|