@cdc/dashboard 4.24.7 → 4.24.9-1

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.
Files changed (41) hide show
  1. package/LICENSE +201 -0
  2. package/dist/cdcdashboard.js +131733 -123191
  3. package/examples/single-state-dashboard-filters.json +421 -0
  4. package/examples/state-level.json +90136 -0
  5. package/examples/state-points.json +10474 -0
  6. package/examples/test-file.json +147 -0
  7. package/examples/testing.json +94456 -0
  8. package/index.html +18 -6
  9. package/package.json +9 -9
  10. package/src/CdcDashboardComponent.tsx +154 -90
  11. package/src/DashboardContext.tsx +7 -1
  12. package/src/_stories/Dashboard.stories.tsx +124 -10
  13. package/src/_stories/_mock/api-filter-map.json +1 -1
  14. package/src/_stories/_mock/bump-chart.json +3554 -0
  15. package/src/_stories/_mock/methodology.json +412 -0
  16. package/src/_stories/_mock/methodologyAPI.ts +90 -0
  17. package/src/_stories/_mock/multi-viz.json +1 -1
  18. package/src/_stories/_mock/single-state-dashboard-filters.json +390 -0
  19. package/src/components/DashboardFilters/DashboardFilters.tsx +39 -17
  20. package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +2 -2
  21. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +141 -31
  22. package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +66 -18
  23. package/src/components/Header/Header.tsx +0 -5
  24. package/src/components/MultiConfigTabs/MultiConfigTabs.tsx +20 -8
  25. package/src/components/Row.tsx +1 -1
  26. package/src/components/VisualizationRow.tsx +98 -17
  27. package/src/components/Widget.tsx +1 -0
  28. package/src/helpers/FilterBehavior.ts +4 -0
  29. package/src/helpers/addValuesToDashboardFilters.ts +49 -0
  30. package/src/helpers/apiFilterHelpers.ts +70 -18
  31. package/src/helpers/changeFilterActive.ts +17 -8
  32. package/src/helpers/getFilteredData.ts +4 -4
  33. package/src/helpers/iconHash.tsx +2 -0
  34. package/src/helpers/loadAPIFilters.ts +74 -0
  35. package/src/helpers/reloadURLHelpers.ts +41 -7
  36. package/src/helpers/tests/addValuesToDashboardFilters.test.ts +44 -0
  37. package/src/helpers/tests/apiFilterHelpers.test.ts +155 -0
  38. package/src/helpers/tests/getFilteredData.test.ts +86 -0
  39. package/src/helpers/tests/loadAPIFiltersWrapper.test.ts +220 -0
  40. package/src/helpers/tests/reloadURLHelpers.test.ts +232 -0
  41. package/src/types/SharedFilter.ts +2 -1
@@ -0,0 +1,390 @@
1
+ {
2
+ "dashboard": {
3
+ "theme": "theme-blue",
4
+ "sharedFilters": [
5
+ {
6
+ "key": "New Dashboard Filter 1",
7
+ "showDropdown": true,
8
+ "values": [
9
+ "Florida",
10
+ "California"
11
+ ],
12
+ "type": "datafilter",
13
+ "columnName": "State",
14
+ "tier": 1,
15
+ "usedBy": [
16
+ "map1721943918271"
17
+ ]
18
+ }
19
+ ]
20
+ },
21
+ "rows": [
22
+ {
23
+ "columns": [
24
+ {
25
+ "width": 12,
26
+ "widget": "dashboardFilters1721943964161"
27
+ }
28
+ ],
29
+ "uuid": 1721943975299
30
+ },
31
+ {
32
+ "uuid": 1721943975299,
33
+ "columns": [
34
+ {
35
+ "width": 12,
36
+ "widget": "map1721943918271"
37
+ },
38
+ {},
39
+ {}
40
+ ]
41
+ }
42
+ ],
43
+ "visualizations": {
44
+ "map1721943918271": {
45
+ "annotations": [],
46
+ "general": {
47
+ "geoType": "single-state",
48
+ "annotationDropdownText": "Annotations",
49
+ "geoBorderColor": "darkGray",
50
+ "headerColor": "theme-blue",
51
+ "title": "",
52
+ "showTitle": true,
53
+ "showSidebar": true,
54
+ "showDownloadButton": true,
55
+ "showDownloadMediaButton": false,
56
+ "displayAsHex": false,
57
+ "displayStateLabels": false,
58
+ "territoriesLabel": "Territories",
59
+ "territoriesAlwaysShow": false,
60
+ "language": "en",
61
+ "geoLabelOverride": "",
62
+ "hasRegions": false,
63
+ "fullBorder": false,
64
+ "type": "data",
65
+ "convertFipsCodes": true,
66
+ "palette": {
67
+ "isReversed": false
68
+ },
69
+ "allowMapZoom": true,
70
+ "hideGeoColumnInTooltip": false,
71
+ "hidePrimaryColumnInTooltip": false,
72
+ "expandDataTable": false,
73
+ "filterControlsStatePicked": "State",
74
+ "statePicked": {
75
+ "fipsCode": "01",
76
+ "stateName": "Alabama"
77
+ }
78
+ },
79
+ "type": "map",
80
+ "color": "pinkpurple",
81
+ "columns": {
82
+ "geo": {
83
+ "name": "FIPS Codes",
84
+ "label": "Location",
85
+ "tooltip": false,
86
+ "dataTable": true
87
+ },
88
+ "primary": {
89
+ "dataTable": true,
90
+ "tooltip": true,
91
+ "prefix": "",
92
+ "suffix": "",
93
+ "name": "Insured Rate",
94
+ "label": "",
95
+ "roundToPlace": 0
96
+ },
97
+ "navigate": {
98
+ "name": ""
99
+ },
100
+ "latitude": {
101
+ "name": "Latitude"
102
+ },
103
+ "longitude": {
104
+ "name": "Longitude"
105
+ }
106
+ },
107
+ "legend": {
108
+ "descriptions": {},
109
+ "specialClasses": [],
110
+ "unified": false,
111
+ "singleColumn": false,
112
+ "singleRow": false,
113
+ "verticalSorted": false,
114
+ "showSpecialClassesLast": false,
115
+ "dynamicDescription": false,
116
+ "type": "equalnumber",
117
+ "numberOfItems": 3,
118
+ "position": "side",
119
+ "title": "Legend"
120
+ },
121
+ "filters": [],
122
+ "table": {
123
+ "wrapColumns": false,
124
+ "label": "Data Table",
125
+ "expanded": false,
126
+ "limitHeight": false,
127
+ "height": "",
128
+ "caption": "",
129
+ "showDownloadUrl": false,
130
+ "showDataTableLink": true,
131
+ "showFullGeoNameInCSV": false,
132
+ "forceDisplay": true,
133
+ "download": true,
134
+ "indexLabel": ""
135
+ },
136
+ "tooltips": {
137
+ "appearanceType": "hover",
138
+ "linkLabel": "Learn More",
139
+ "capitalizeLabels": true,
140
+ "opacity": 90
141
+ },
142
+ "visual": {
143
+ "minBubbleSize": 1,
144
+ "maxBubbleSize": 20,
145
+ "extraBubbleBorder": false,
146
+ "cityStyle": "circle",
147
+ "cityStyleLabel": "",
148
+ "showBubbleZeros": false,
149
+ "additionalCityStyles": [],
150
+ "geoCodeCircleSize": "2"
151
+ },
152
+ "mapPosition": {
153
+ "coordinates": [
154
+ 0,
155
+ 30
156
+ ],
157
+ "zoom": 1
158
+ },
159
+ "map": {
160
+ "layers": [],
161
+ "patterns": []
162
+ },
163
+ "hexMap": {
164
+ "type": "",
165
+ "shapeGroups": [
166
+ {
167
+ "legendTitle": "",
168
+ "legendDescription": "",
169
+ "items": [
170
+ {
171
+ "key": "",
172
+ "shape": "Arrow Up",
173
+ "column": "",
174
+ "operator": "=",
175
+ "value": ""
176
+ }
177
+ ]
178
+ }
179
+ ]
180
+ },
181
+ "filterBehavior": "Filter Change",
182
+ "openModal": true,
183
+ "uid": "map1721943918271",
184
+ "dataDescription": {
185
+ "horizontal": false,
186
+ "series": false
187
+ },
188
+ "dataKey": "test-single-county-file.json",
189
+ "editing": false,
190
+ "originalFormattedData": [
191
+ {
192
+ "Insured Rate": 8,
193
+ "Coverage Status": "Insured",
194
+ "FIPS Codes": "12057",
195
+ "Year (Good filter option)": "2010",
196
+ "link": "",
197
+ "Latitude": "",
198
+ "Longitude": "",
199
+ "State": "Florida"
200
+ },
201
+ {
202
+ "Insured Rate": 25,
203
+ "Coverage Status": "Insured",
204
+ "FIPS Codes": "55005",
205
+ "Year (Good filter option)": "2010",
206
+ "link": "",
207
+ "Latitude": "",
208
+ "Longitude": "",
209
+ "State": "California"
210
+ },
211
+ {
212
+ "Insured Rate": 25,
213
+ "Coverage Status": "Insured",
214
+ "FIPS Codes": "12103",
215
+ "Year (Good filter option)": "2010",
216
+ "link": "",
217
+ "Latitude": "",
218
+ "Longitude": "",
219
+ "State": "Florida"
220
+ },
221
+ {
222
+ "Insured Rate": 25,
223
+ "Coverage Status": "Insured",
224
+ "FIPS Codes": "32005",
225
+ "Year (Good filter option)": "2010",
226
+ "link": "",
227
+ "Latitude": "",
228
+ "Longitude": "",
229
+ "State": "California"
230
+ },
231
+ {
232
+ "Insured Rate": 18,
233
+ "Coverage Status": "Insured",
234
+ "FIPS Codes": "06075",
235
+ "Year (Good filter option)": "2010",
236
+ "link": "",
237
+ "Latitude": "",
238
+ "Longitude": "",
239
+ "State": "California"
240
+ },
241
+ {
242
+ "Insured Rate": 3,
243
+ "Coverage Status": "Insured",
244
+ "FIPS Codes": "06027",
245
+ "Year (Good filter option)": "2010",
246
+ "link": "",
247
+ "Latitude": "",
248
+ "Longitude": "",
249
+ "State": "California"
250
+ },
251
+ {
252
+ "Insured Rate": 25,
253
+ "Coverage Status": "Insured",
254
+ "FIPS Codes": "06029",
255
+ "Year (Good filter option)": "2010",
256
+ "link": "",
257
+ "Latitude": "",
258
+ "Longitude": "",
259
+ "State": "California"
260
+ },
261
+ {
262
+ "Insured Rate": 60,
263
+ "Coverage Status": "Insured",
264
+ "FIPS Codes": "Yosemite",
265
+ "Year (Good filter option)": "2010",
266
+ "link": "",
267
+ "Latitude": "37.865101",
268
+ "Longitude": "-119.538330",
269
+ "State": "California"
270
+ }
271
+ ],
272
+ "version": "4.24.9"
273
+ },
274
+ "dashboardFilters1721943964161": {
275
+ "filters": [],
276
+ "filterBehavior": "Filter Change",
277
+ "newViz": true,
278
+ "openModal": true,
279
+ "uid": "dashboardFilters1721943964161",
280
+ "type": "dashboardFilters",
281
+ "sharedFilterIndexes": [
282
+ 0
283
+ ],
284
+ "visualizationType": "dashboardFilters",
285
+ "editing": false
286
+ }
287
+ },
288
+ "table": {
289
+ "label": "Data Table",
290
+ "show": true,
291
+ "showDownloadUrl": false,
292
+ "showVertical": true
293
+ },
294
+ "newViz": true,
295
+ "datasets": {
296
+ "test-single-county-file.json": {
297
+ "data": [
298
+ {
299
+ "Insured Rate": 8,
300
+ "Coverage Status": "Insured",
301
+ "FIPS Codes": "12057",
302
+ "Year (Good filter option)": "2010",
303
+ "link": "",
304
+ "Latitude": "",
305
+ "Longitude": "",
306
+ "State": "Florida"
307
+ },
308
+ {
309
+ "Insured Rate": 25,
310
+ "Coverage Status": "Insured",
311
+ "FIPS Codes": "55005",
312
+ "Year (Good filter option)": "2010",
313
+ "link": "",
314
+ "Latitude": "",
315
+ "Longitude": "",
316
+ "State": "California"
317
+ },
318
+ {
319
+ "Insured Rate": 25,
320
+ "Coverage Status": "Insured",
321
+ "FIPS Codes": "12103",
322
+ "Year (Good filter option)": "2010",
323
+ "link": "",
324
+ "Latitude": "",
325
+ "Longitude": "",
326
+ "State": "Florida"
327
+ },
328
+ {
329
+ "Insured Rate": 25,
330
+ "Coverage Status": "Insured",
331
+ "FIPS Codes": "32005",
332
+ "Year (Good filter option)": "2010",
333
+ "link": "",
334
+ "Latitude": "",
335
+ "Longitude": "",
336
+ "State": "California"
337
+ },
338
+ {
339
+ "Insured Rate": 18,
340
+ "Coverage Status": "Insured",
341
+ "FIPS Codes": "06075",
342
+ "Year (Good filter option)": "2010",
343
+ "link": "",
344
+ "Latitude": "",
345
+ "Longitude": "",
346
+ "State": "California"
347
+ },
348
+ {
349
+ "Insured Rate": 3,
350
+ "Coverage Status": "Insured",
351
+ "FIPS Codes": "06027",
352
+ "Year (Good filter option)": "2010",
353
+ "link": "",
354
+ "Latitude": "",
355
+ "Longitude": "",
356
+ "State": "California"
357
+ },
358
+ {
359
+ "Insured Rate": 25,
360
+ "Coverage Status": "Insured",
361
+ "FIPS Codes": "06029",
362
+ "Year (Good filter option)": "2010",
363
+ "link": "",
364
+ "Latitude": "",
365
+ "Longitude": "",
366
+ "State": "California"
367
+ },
368
+ {
369
+ "Insured Rate": 60,
370
+ "Coverage Status": "Insured",
371
+ "FIPS Codes": "Yosemite",
372
+ "Year (Good filter option)": "2010",
373
+ "link": "",
374
+ "Latitude": "37.865101",
375
+ "Longitude": "-119.538330",
376
+ "State": "California"
377
+ }
378
+ ],
379
+ "dataFileSize": 1764,
380
+ "dataFileName": "test-single-county-file.json",
381
+ "dataFileSourceType": "file",
382
+ "dataFileFormat": "JSON",
383
+ "preview": true
384
+ }
385
+ },
386
+ "type": "dashboard",
387
+ "runtime": {},
388
+ "version": "4.24.9",
389
+ "uuid": 1721943961122
390
+ }
@@ -1,3 +1,4 @@
1
+ import MultiSelect from '@cdc/core/components/MultiSelect'
1
2
  import { SharedFilter } from '../../types/SharedFilter'
2
3
  import { APIFilterDropdowns } from './DashboardFiltersWrapper'
3
4
 
@@ -8,25 +9,35 @@ type DashboardFilterProps = {
8
9
  handleOnChange: Function
9
10
  }
10
11
 
11
- const DashboardFilters: React.FC<DashboardFilterProps> = ({ show, filters, apiFilterDropdowns, handleOnChange }) => {
12
- const nullVal = (singleFilter: SharedFilter) => {
13
- const val = singleFilter.queuedActive || singleFilter.active
12
+ const DashboardFilters: React.FC<DashboardFilterProps> = ({
13
+ show,
14
+ filters: sharedFilters,
15
+ apiFilterDropdowns,
16
+ handleOnChange
17
+ }) => {
18
+ const nullVal = (filter: SharedFilter) => {
19
+ const val = filter.queuedActive || filter.active
14
20
  return val === null || val === undefined || val === ''
15
21
  }
22
+
23
+ const updateField = (_section, _subsection, fieldName, value) => {
24
+ handleOnChange(fieldName, value)
25
+ }
26
+
16
27
  return (
17
28
  <>
18
- {filters.map((singleFilter, filterIndex) => {
19
- if ((singleFilter.type !== 'urlfilter' && !singleFilter.showDropdown) || (show && !show.includes(filterIndex))) return <></>
29
+ {sharedFilters.map((filter, filterIndex) => {
30
+ if (filter.showDropdown === false || (show && !show.includes(filterIndex))) return <></>
20
31
  const values: JSX.Element[] = []
21
32
  const multiValues = []
22
- if (singleFilter.resetLabel) {
33
+ if (filter.resetLabel) {
23
34
  values.push(
24
- <option key={`${singleFilter.resetLabel}-option`} value={singleFilter.resetLabel}>
25
- {singleFilter.resetLabel}
35
+ <option key={`${filter.resetLabel}-option`} value={filter.resetLabel}>
36
+ {filter.resetLabel}
26
37
  </option>
27
38
  )
28
39
  }
29
- const _key = singleFilter.apiFilter?.apiEndpoint
40
+ const _key = filter.apiFilter?.apiEndpoint
30
41
  if (_key && apiFilterDropdowns[_key]) {
31
42
  // URL Filter
32
43
  apiFilterDropdowns[_key].forEach(({ text, value }, index) => {
@@ -35,13 +46,14 @@ const DashboardFilters: React.FC<DashboardFilterProps> = ({ show, filters, apiFi
35
46
  {text}
36
47
  </option>
37
48
  )
49
+ multiValues.push({ value, label: text })
38
50
  })
39
51
  } else {
40
52
  // Data Filter
41
- singleFilter.values?.forEach((filterOption, index) => {
42
- const labeledOpt = singleFilter.labels && singleFilter.labels[filterOption]
53
+ filter.values?.forEach((filterOption, index) => {
54
+ const labeledOpt = filter.labels && filter.labels[filterOption]
43
55
  values.push(
44
- <option key={`${singleFilter.key}-option-${index}`} value={filterOption}>
56
+ <option key={`${filter.key}-option-${index}`} value={filterOption}>
45
57
  {labeledOpt || filterOption}
46
58
  </option>
47
59
  )
@@ -49,20 +61,30 @@ const DashboardFilters: React.FC<DashboardFilterProps> = ({ show, filters, apiFi
49
61
  })
50
62
  }
51
63
 
52
- return (
53
- <div className='cove-dashboard-filters' key={`${singleFilter.key}-filtersection-${filterIndex}`}>
64
+ return filter.multiSelect ? (
65
+ <MultiSelect
66
+ key={`${filter.key}-filtersection-${filterIndex}`}
67
+ label={filter.key}
68
+ options={multiValues}
69
+ fieldName={filterIndex}
70
+ updateField={updateField}
71
+ selected={filter.active as string[]}
72
+ limit={filter.selectLimit || 5}
73
+ />
74
+ ) : (
75
+ <div className='cove-dashboard-filters' key={`${filter.key}-filtersection-${filterIndex}`}>
54
76
  <section className='dashboard-filters-section'>
55
- <label htmlFor={`filter-${filterIndex}`}>{singleFilter.key}</label>
77
+ <label htmlFor={`filter-${filterIndex}`}>{filter.key}</label>
56
78
  <select
57
79
  id={`filter-${filterIndex}`}
58
80
  className='filter-select'
59
81
  data-index='0'
60
- value={singleFilter.queuedActive || singleFilter.active}
82
+ value={filter.queuedActive || filter.active}
61
83
  onChange={val => {
62
84
  handleOnChange(filterIndex, val.target.value)
63
85
  }}
64
86
  >
65
- {nullVal(singleFilter) && !singleFilter.resetLabel && (
87
+ {nullVal(filter) && !filter.resetLabel && (
66
88
  <option value='' key='select'>
67
89
  {'-Select-'}
68
90
  </option>
@@ -10,9 +10,9 @@ import { DashboardContext, DashboardDispatchContext } from '../../../DashboardCo
10
10
  import _ from 'lodash'
11
11
  import { DashboardFilters } from '../../../types/DashboardFilters'
12
12
  import { SharedFilter } from '../../../types/SharedFilter'
13
- import { addValuesToFilters } from '@cdc/core/helpers/addValuesToFilters'
14
13
  import { useGlobalContext } from '@cdc/core/components/GlobalContext'
15
14
  import DeleteFilterModal from './components/DeleteFilterModal'
15
+ import { addValuesToDashboardFilters } from '../../../helpers/addValuesToDashboardFilters'
16
16
 
17
17
  type DashboardFitlersEditorProps = {
18
18
  vizConfig: DashboardFilters
@@ -47,7 +47,7 @@ const DashboardFiltersEditor: React.FC<DashboardFitlersEditorProps> = ({ vizConf
47
47
  newSharedFilters[index][prop] = value
48
48
  if (prop === 'columnName') {
49
49
  // changing a data column and want to load the data into the preview options
50
- const sharedFiltersWithValues = addValuesToFilters<SharedFilter>(newSharedFilters, data)
50
+ const sharedFiltersWithValues = addValuesToDashboardFilters(newSharedFilters, data)
51
51
  dispatch({ type: 'SET_SHARED_FILTERS', payload: sharedFiltersWithValues })
52
52
  } else if (prop === 'apiFilter' && value.apiEndpoint && value.valueSelector && apiFilterChanged) {
53
53
  // changing a api filter and want to load the api data into the preview.