@cdc/dashboard 4.25.5-1 → 4.25.6-2
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/LICENSE +201 -0
- package/dist/cdcdashboard.js +77621 -77591
- package/examples/private/DEV-10120.json +1294 -0
- package/examples/private/DEV-10527.json +845 -0
- package/examples/private/DEV-10586.json +54319 -0
- package/examples/private/DEV-10856.json +54319 -0
- package/examples/private/DEV-9199.json +606 -0
- package/examples/private/DEV-9644.json +20092 -0
- package/examples/private/DEV-9684.json +2135 -0
- package/examples/private/DEV-9932.json +95 -0
- package/examples/private/DEV-9989.json +229 -0
- package/examples/private/art-dashboard.json +18174 -0
- package/examples/private/art-scratch.json +2406 -0
- package/examples/private/bird-flu-2.json +440 -0
- package/examples/private/bird-flu.json +413 -0
- package/examples/private/crashing-sidebar.json +975 -0
- package/examples/private/d.json +1561 -0
- package/examples/private/dashboard-config-ehdi.json +29915 -0
- package/examples/private/dashboard-map-filter.json +815 -0
- package/examples/private/dashboard-margins.js +15 -0
- package/examples/private/dataset.json +1452 -0
- package/examples/private/dev-10856-2.json +1348 -0
- package/examples/private/ehdi-data.json +29502 -0
- package/examples/private/exposure-source-h5-data.csv +26 -0
- package/examples/private/fatal-data.csv +3159 -0
- package/examples/private/feelings.json +1 -0
- package/examples/private/gaza-issue.json +1214 -0
- package/examples/private/josh.json +6175 -0
- package/examples/private/map-issue.json +628 -0
- package/examples/private/markup.json +115 -0
- package/examples/private/mpox.json +429 -0
- package/examples/private/nhis.json +1792 -0
- package/examples/private/testing-pie.json +436 -0
- package/examples/private/workforce.json +2041 -0
- package/examples/special-classes.json +54340 -0
- package/package.json +9 -9
- package/src/CdcDashboardComponent.tsx +36 -214
- package/src/_stories/_mock/api-filter-map.json +1 -0
- package/src/components/CollapsibleVisualizationRow.tsx +2 -4
- package/src/components/DashboardEditors.tsx +143 -0
- package/src/components/DashboardFilters/DashboardFilters.tsx +205 -205
- package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +286 -287
- package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +198 -198
- package/src/components/Header/Header.tsx +7 -9
- package/src/components/Row.tsx +1 -24
- package/src/components/VisualizationRow.tsx +190 -213
- package/src/helpers/getVizConfig.ts +93 -80
- package/src/helpers/getVizRowColumnLocator.ts +0 -1
- package/src/helpers/reloadURLHelpers.ts +10 -13
- package/src/store/dashboard.actions.ts +61 -64
- package/src/store/dashboard.reducer.ts +0 -11
- package/src/types/ConfigRow.ts +0 -1
- package/src/types/Dashboard.ts +1 -1
- package/src/types/DashboardConfig.ts +1 -1
- package/src/types/DataSet.ts +0 -12
|
@@ -1,287 +1,286 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Accordion,
|
|
3
|
-
AccordionItem,
|
|
4
|
-
AccordionItemButton,
|
|
5
|
-
AccordionItemHeading,
|
|
6
|
-
AccordionItemPanel
|
|
7
|
-
} from 'react-accessible-accordion'
|
|
8
|
-
import { useContext, useMemo, useState } from 'react'
|
|
9
|
-
import { CheckBox, Select, TextField } from '@cdc/core/components/EditorPanel/Inputs'
|
|
10
|
-
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
11
|
-
import Icon from '@cdc/core/components/ui/Icon'
|
|
12
|
-
import FieldSetWrapper from '@cdc/core/components/EditorPanel/FieldSetWrapper'
|
|
13
|
-
import FilterEditor from './components/FilterEditor'
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
const {
|
|
33
|
-
const {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
value?.
|
|
66
|
-
value?.
|
|
67
|
-
value?.
|
|
68
|
-
value?.
|
|
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
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
filter.setByQueryParameter = checked ?
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
const
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
...vizConfig,
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
export default DashboardFiltersEditor
|
|
1
|
+
import {
|
|
2
|
+
Accordion,
|
|
3
|
+
AccordionItem,
|
|
4
|
+
AccordionItemButton,
|
|
5
|
+
AccordionItemHeading,
|
|
6
|
+
AccordionItemPanel
|
|
7
|
+
} from 'react-accessible-accordion'
|
|
8
|
+
import { useContext, useMemo, useState } from 'react'
|
|
9
|
+
import { CheckBox, Select, TextField } from '@cdc/core/components/EditorPanel/Inputs'
|
|
10
|
+
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
11
|
+
import Icon from '@cdc/core/components/ui/Icon'
|
|
12
|
+
import FieldSetWrapper from '@cdc/core/components/EditorPanel/FieldSetWrapper'
|
|
13
|
+
import FilterEditor from './components/FilterEditor'
|
|
14
|
+
import { DashboardContext, DashboardDispatchContext } from '../../../DashboardContext'
|
|
15
|
+
import _ from 'lodash'
|
|
16
|
+
import { DashboardFilters } from '../../../types/DashboardFilters'
|
|
17
|
+
import { SharedFilter } from '../../../types/SharedFilter'
|
|
18
|
+
import { useGlobalContext } from '@cdc/core/components/GlobalContext'
|
|
19
|
+
import DeleteFilterModal from './components/DeleteFilterModal'
|
|
20
|
+
import { addValuesToDashboardFilters } from '../../../helpers/addValuesToDashboardFilters'
|
|
21
|
+
import { FILTER_STYLE } from '../../../types/FilterStyles'
|
|
22
|
+
import { handleSorting } from '@cdc/core/components/Filters'
|
|
23
|
+
import { removeDashboardFilter } from '../../../helpers/removeDashboardFilter'
|
|
24
|
+
|
|
25
|
+
type DashboardFitlersEditorProps = {
|
|
26
|
+
vizConfig: DashboardFilters
|
|
27
|
+
updateConfig: Function
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const DashboardFiltersEditor: React.FC<DashboardFitlersEditorProps> = ({ vizConfig, updateConfig }) => {
|
|
31
|
+
const { config, loadAPIFilters, data } = useContext(DashboardContext)
|
|
32
|
+
const { overlay } = useGlobalContext()
|
|
33
|
+
const {
|
|
34
|
+
dashboard: { sharedFilters },
|
|
35
|
+
visualizations
|
|
36
|
+
} = config
|
|
37
|
+
const dispatch = useContext(DashboardDispatchContext)
|
|
38
|
+
|
|
39
|
+
const existingOptions = useMemo(() => {
|
|
40
|
+
const sharedFilterIndexes = (config.visualizations[vizConfig.uid] as DashboardFilters).sharedFilterIndexes.map(
|
|
41
|
+
Number
|
|
42
|
+
)
|
|
43
|
+
return config.dashboard.sharedFilters
|
|
44
|
+
?.map<[number, string]>(({ key }, i) => [i, key])
|
|
45
|
+
.filter(([filterIndex]) => !sharedFilterIndexes.includes(filterIndex)) // filter out already added filters
|
|
46
|
+
.map(([filterIndex, filterName]) => (
|
|
47
|
+
<option key={filterIndex} value={filterIndex}>{`${filterIndex} - ${filterName}`}</option>
|
|
48
|
+
))
|
|
49
|
+
}, [config.visualizations, vizConfig.uid])
|
|
50
|
+
|
|
51
|
+
const openControls = useState({})
|
|
52
|
+
const [canAddExisting, setCanAddExisting] = useState(false)
|
|
53
|
+
|
|
54
|
+
const updateFilterProp = (prop: string, index: number, value) => {
|
|
55
|
+
const newSharedFilters = _.cloneDeep(sharedFilters)
|
|
56
|
+
const {
|
|
57
|
+
apiEndpoint: oldEndpoint,
|
|
58
|
+
valueSelector: oldValueSelector,
|
|
59
|
+
textSelector: oldTextSelector,
|
|
60
|
+
subgroupValueSelector: oldSubgroupValueSelector,
|
|
61
|
+
subgroupTextSelector: oldSubgroupTextSelector
|
|
62
|
+
} = sharedFilters[index].apiFilter || {}
|
|
63
|
+
const apiFilterChanged =
|
|
64
|
+
value?.apiEndpoint !== oldEndpoint ||
|
|
65
|
+
value?.valueSelector !== oldValueSelector ||
|
|
66
|
+
value?.textSelector !== oldTextSelector ||
|
|
67
|
+
value?.subgroupValueSelector !== oldSubgroupValueSelector ||
|
|
68
|
+
value?.subgroupTextSelector !== oldSubgroupTextSelector
|
|
69
|
+
|
|
70
|
+
newSharedFilters[index][prop] = value
|
|
71
|
+
if (prop === 'columnName') {
|
|
72
|
+
if (newSharedFilters[index].subGrouping) delete newSharedFilters[index].subGrouping
|
|
73
|
+
// changing a data column and want to load the data into the preview options
|
|
74
|
+
const sharedFiltersWithValues = addValuesToDashboardFilters(newSharedFilters, data)
|
|
75
|
+
dispatch({ type: 'SET_SHARED_FILTERS', payload: sharedFiltersWithValues })
|
|
76
|
+
} else if (prop === 'filterStyle') {
|
|
77
|
+
newSharedFilters[index] = {
|
|
78
|
+
...newSharedFilters[index],
|
|
79
|
+
active: '',
|
|
80
|
+
apiFilter: {
|
|
81
|
+
apiEndpoint: '',
|
|
82
|
+
subgroupValueSelector: '',
|
|
83
|
+
textSelector: '',
|
|
84
|
+
valueSelector: ''
|
|
85
|
+
},
|
|
86
|
+
filterStyle: value
|
|
87
|
+
}
|
|
88
|
+
dispatch({ type: 'SET_SHARED_FILTERS', payload: newSharedFilters })
|
|
89
|
+
} else if (prop === 'apiFilter' && value.apiEndpoint && value.valueSelector && apiFilterChanged) {
|
|
90
|
+
if (sharedFilters[index].filterStyle === FILTER_STYLE.nestedDropdown && value.subgroupValueSelector) {
|
|
91
|
+
newSharedFilters[index].subGrouping = {
|
|
92
|
+
active: '',
|
|
93
|
+
columnName: '',
|
|
94
|
+
setByQueryParameter: '',
|
|
95
|
+
valuesLookup: {}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// changing a api filter and want to load the api data into the preview.
|
|
99
|
+
// automatically dispatches SET_SHARED_FILTERS
|
|
100
|
+
loadAPIFilters(newSharedFilters, {})
|
|
101
|
+
} else {
|
|
102
|
+
handleSorting(newSharedFilters[index])
|
|
103
|
+
dispatch({ type: 'SET_SHARED_FILTERS', payload: newSharedFilters })
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const toggleNestedQueryParameters = (index, checked: boolean) => {
|
|
108
|
+
const newSharedFilters = _.cloneDeep(sharedFilters)
|
|
109
|
+
const filter = newSharedFilters[index]
|
|
110
|
+
const isUrlFilter = filter.type === 'urlfilter'
|
|
111
|
+
const groupColumnName = isUrlFilter ? filter.apiFilter.valueSelector : filter.columnName
|
|
112
|
+
const subGroupColumnName = isUrlFilter ? filter.apiFilter.subgroupValueSelector : filter.subGrouping.columnName
|
|
113
|
+
filter.setByQueryParameter = checked ? groupColumnName : undefined
|
|
114
|
+
filter.subGrouping.setByQueryParameter = checked ? subGroupColumnName : undefined
|
|
115
|
+
dispatch({ type: 'SET_SHARED_FILTERS', payload: newSharedFilters })
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const removeFilter = index => {
|
|
119
|
+
const [newSharedFilters, newVisualizations] = removeDashboardFilter(index, sharedFilters, visualizations)
|
|
120
|
+
const dashboard = { ...config.dashboard, sharedFilters: newSharedFilters }
|
|
121
|
+
dispatch({ type: 'SET_CONFIG', payload: { dashboard, visualizations: newVisualizations } })
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const addNewFilter = () => {
|
|
125
|
+
const _sharedFilters = _.cloneDeep(sharedFilters) || []
|
|
126
|
+
const columnName = 'New Dashboard Filter ' + (_sharedFilters.length + 1)
|
|
127
|
+
const newFilter = { key: columnName, showDropdown: true, values: [] } as SharedFilter
|
|
128
|
+
dispatch({ type: 'SET_SHARED_FILTERS', payload: [..._sharedFilters, newFilter] })
|
|
129
|
+
updateConfig({ ...vizConfig, sharedFilterIndexes: [...vizConfig.sharedFilterIndexes, _sharedFilters.length] })
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<Accordion allowZeroExpanded={true}>
|
|
134
|
+
<AccordionItem>
|
|
135
|
+
<AccordionItemHeading>
|
|
136
|
+
<AccordionItemButton>General</AccordionItemButton>
|
|
137
|
+
</AccordionItemHeading>
|
|
138
|
+
<AccordionItemPanel>
|
|
139
|
+
<Select
|
|
140
|
+
value={vizConfig.filterBehavior}
|
|
141
|
+
label='Filter Behavior'
|
|
142
|
+
updateField={(_section, _subsection, _key, value) => {
|
|
143
|
+
updateConfig({ ...vizConfig, filterBehavior: value })
|
|
144
|
+
}}
|
|
145
|
+
options={['Apply Button', 'Filter Change']}
|
|
146
|
+
tooltip={
|
|
147
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
148
|
+
<Tooltip.Target>
|
|
149
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
150
|
+
</Tooltip.Target>
|
|
151
|
+
<Tooltip.Content>
|
|
152
|
+
<p>
|
|
153
|
+
The Apply Button option changes the visualization when the user clicks "apply". The Filter Change
|
|
154
|
+
option immediately changes the visualization when the selection is changed.
|
|
155
|
+
</p>
|
|
156
|
+
</Tooltip.Content>
|
|
157
|
+
</Tooltip>
|
|
158
|
+
}
|
|
159
|
+
/>
|
|
160
|
+
{vizConfig.filterBehavior === 'Apply Button' && (
|
|
161
|
+
<TextField
|
|
162
|
+
label='Apply Filter Button Text'
|
|
163
|
+
maxLength={20}
|
|
164
|
+
value={vizConfig.applyFiltersButtonText}
|
|
165
|
+
updateField={(_section, _subsection, _key, value) => {
|
|
166
|
+
updateConfig({ ...vizConfig, applyFiltersButtonText: value })
|
|
167
|
+
}}
|
|
168
|
+
/>
|
|
169
|
+
)}
|
|
170
|
+
{vizConfig.filterBehavior === 'Filter Change' && (
|
|
171
|
+
<CheckBox
|
|
172
|
+
label='Auto Load'
|
|
173
|
+
value={vizConfig.autoLoad}
|
|
174
|
+
updateField={(_section, _subsection, _key, value) => {
|
|
175
|
+
updateConfig({ ...vizConfig, autoLoad: value })
|
|
176
|
+
}}
|
|
177
|
+
tooltip={
|
|
178
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
179
|
+
<Tooltip.Target>
|
|
180
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
181
|
+
</Tooltip.Target>
|
|
182
|
+
<Tooltip.Content>
|
|
183
|
+
<p>
|
|
184
|
+
Check if you would like for all URL filters to automatically select a value when a parent filter
|
|
185
|
+
is changed.
|
|
186
|
+
</p>
|
|
187
|
+
</Tooltip.Content>
|
|
188
|
+
</Tooltip>
|
|
189
|
+
}
|
|
190
|
+
/>
|
|
191
|
+
)}
|
|
192
|
+
</AccordionItemPanel>
|
|
193
|
+
</AccordionItem>
|
|
194
|
+
|
|
195
|
+
<AccordionItem>
|
|
196
|
+
<AccordionItemHeading>
|
|
197
|
+
<AccordionItemButton>Filters</AccordionItemButton>
|
|
198
|
+
</AccordionItemHeading>
|
|
199
|
+
<AccordionItemPanel>
|
|
200
|
+
{vizConfig.sharedFilterIndexes.map(index => {
|
|
201
|
+
const filter = sharedFilters[index]
|
|
202
|
+
return (
|
|
203
|
+
<FieldSetWrapper
|
|
204
|
+
key={filter.key + index}
|
|
205
|
+
fieldName={filter.key}
|
|
206
|
+
fieldKey={index}
|
|
207
|
+
fieldType='Dashboard Filter'
|
|
208
|
+
controls={openControls}
|
|
209
|
+
deleteField={() => {
|
|
210
|
+
overlay?.actions.openOverlay(
|
|
211
|
+
<DeleteFilterModal
|
|
212
|
+
removeFilterCompletely={removeFilter}
|
|
213
|
+
removeFilterFromViz={index => {
|
|
214
|
+
updateConfig({
|
|
215
|
+
...vizConfig,
|
|
216
|
+
sharedFilterIndexes: vizConfig.sharedFilterIndexes.filter(i => i !== index)
|
|
217
|
+
})
|
|
218
|
+
}}
|
|
219
|
+
filterIndex={index}
|
|
220
|
+
/>
|
|
221
|
+
)
|
|
222
|
+
}}
|
|
223
|
+
>
|
|
224
|
+
<FilterEditor
|
|
225
|
+
filter={filter}
|
|
226
|
+
filterIndex={index}
|
|
227
|
+
updateFilterProp={(name, value) => {
|
|
228
|
+
updateFilterProp(name, index, value)
|
|
229
|
+
}}
|
|
230
|
+
toggleNestedQueryParameters={checked => {
|
|
231
|
+
toggleNestedQueryParameters(index, checked)
|
|
232
|
+
}}
|
|
233
|
+
config={config}
|
|
234
|
+
/>
|
|
235
|
+
</FieldSetWrapper>
|
|
236
|
+
)
|
|
237
|
+
})}
|
|
238
|
+
<button onClick={addNewFilter} className='btn btn-primary full-width'>
|
|
239
|
+
Add Filter
|
|
240
|
+
</button>
|
|
241
|
+
{canAddExisting ? (
|
|
242
|
+
<label>
|
|
243
|
+
<span className='edit-label column-heading'>
|
|
244
|
+
Select Existing Dashboard Filter
|
|
245
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
246
|
+
<Tooltip.Target>
|
|
247
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
248
|
+
</Tooltip.Target>
|
|
249
|
+
<Tooltip.Content>
|
|
250
|
+
<p>
|
|
251
|
+
This feature is indentended to support legacy functionality. Be advised that any change to the
|
|
252
|
+
filter in this editor will reflect on the whole dashboard.{' '}
|
|
253
|
+
</p>
|
|
254
|
+
</Tooltip.Content>
|
|
255
|
+
</Tooltip>
|
|
256
|
+
</span>
|
|
257
|
+
<select
|
|
258
|
+
value={''}
|
|
259
|
+
onChange={e => {
|
|
260
|
+
updateConfig({
|
|
261
|
+
...vizConfig,
|
|
262
|
+
sharedFilterIndexes: [...vizConfig.sharedFilterIndexes, e.target.value]
|
|
263
|
+
})
|
|
264
|
+
setCanAddExisting(false)
|
|
265
|
+
}}
|
|
266
|
+
>
|
|
267
|
+
{[
|
|
268
|
+
<option key='select' value=''>
|
|
269
|
+
Select
|
|
270
|
+
</option>,
|
|
271
|
+
...existingOptions
|
|
272
|
+
]}
|
|
273
|
+
</select>
|
|
274
|
+
</label>
|
|
275
|
+
) : (
|
|
276
|
+
<button onClick={() => setCanAddExisting(true)} className='btn btn-primary full-width mt-2'>
|
|
277
|
+
Add Existing Dashboard Filter
|
|
278
|
+
</button>
|
|
279
|
+
)}
|
|
280
|
+
</AccordionItemPanel>
|
|
281
|
+
</AccordionItem>
|
|
282
|
+
</Accordion>
|
|
283
|
+
)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export default DashboardFiltersEditor
|