@cdc/dashboard 4.25.11 → 4.26.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 (51) hide show
  1. package/Dynamic_Data.md +66 -0
  2. package/dist/cdcdashboard.js +78783 -76370
  3. package/examples/api-dashboard-data.json +272 -0
  4. package/examples/api-dashboard-years.json +11 -0
  5. package/examples/api-geographies-data.json +11 -0
  6. package/examples/private/cat-y.json +1235 -0
  7. package/examples/private/chronic-dash.json +1584 -0
  8. package/examples/private/map-issue.json +2260 -0
  9. package/examples/private/mpinc-state-reports.json +2260 -0
  10. package/examples/private/nwss/rsv.json +1240 -0
  11. package/examples/private/simple-dash.json +490 -0
  12. package/examples/private/test-dash.json +0 -0
  13. package/examples/private/test123.json +491 -0
  14. package/examples/test-dashboard-simple.json +503 -0
  15. package/index.html +24 -25
  16. package/package.json +12 -11
  17. package/src/CdcDashboardComponent.tsx +18 -2
  18. package/src/_stories/Dashboard.DataSetup.stories.tsx +203 -0
  19. package/src/_stories/Dashboard.stories.tsx +385 -1
  20. package/src/_stories/_mock/filter-cascade.json +3350 -0
  21. package/src/_stories/_mock/gallery-data-bite-dashboard.json +3500 -0
  22. package/src/_stories/_mock/nested-parent-child-filters.json +392 -0
  23. package/src/_stories/_mock/parent-child-filters.json +233 -0
  24. package/src/components/DashboardFilters/DashboardFilters.tsx +20 -11
  25. package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +89 -38
  26. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +51 -29
  27. package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +146 -9
  28. package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +11 -7
  29. package/src/components/DataDesignerModal.tsx +6 -1
  30. package/src/components/Header/Header.tsx +51 -20
  31. package/src/components/VisualizationRow.tsx +71 -5
  32. package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +2 -3
  33. package/src/components/Widget/Widget.tsx +1 -1
  34. package/src/data/initial-state.js +1 -0
  35. package/src/helpers/addValuesToDashboardFilters.ts +15 -22
  36. package/src/helpers/changeFilterActive.ts +67 -65
  37. package/src/helpers/formatConfigBeforeSave.ts +6 -5
  38. package/src/helpers/getUpdateConfig.ts +91 -91
  39. package/src/helpers/tests/updatesChildFilters.test.ts +53 -22
  40. package/src/helpers/updateChildFilters.ts +50 -27
  41. package/src/scss/main.scss +141 -1
  42. package/src/test/CdcDashboard.test.jsx +9 -4
  43. package/src/types/Dashboard.ts +1 -0
  44. package/src/types/FilterStyles.ts +8 -7
  45. package/src/types/SharedFilter.ts +13 -0
  46. package/LICENSE +0 -201
  47. package/examples/private/DEV-10538.json +0 -407
  48. package/examples/private/DEV-11072.json +0 -7591
  49. package/examples/private/DEV-11405.json +0 -39112
  50. package/examples/private/delete.json +0 -32919
  51. package/examples/private/pedro.json +0 -1
@@ -0,0 +1,392 @@
1
+ {
2
+ "dashboard": {
3
+ "theme": "theme-blue",
4
+ "title": "Nested Dropdown with Parent-Child Demo",
5
+ "description": "Demonstrates nested dropdown filters (year/quarter) with parent-child relationships",
6
+ "sharedFilters": [
7
+ {
8
+ "key": "Region",
9
+ "showDropdown": true,
10
+ "values": [
11
+ "North",
12
+ "South",
13
+ "East",
14
+ "West"
15
+ ],
16
+ "type": "datafilter",
17
+ "orderedValues": [
18
+ "North",
19
+ "South",
20
+ "East",
21
+ "West"
22
+ ],
23
+ "columnName": "region",
24
+ "tier": 1,
25
+ "defaultValue": "North"
26
+ },
27
+ {
28
+ "key": "Year and Quarter",
29
+ "showDropdown": true,
30
+ "values": [
31
+ "2022",
32
+ "2023",
33
+ "2024"
34
+ ],
35
+ "type": "datafilter",
36
+ "orderedValues": [
37
+ "2022",
38
+ "2023",
39
+ "2024"
40
+ ],
41
+ "columnName": "year",
42
+ "filterStyle": "nested-dropdown",
43
+ "tier": 2,
44
+ "parents": [
45
+ "Region"
46
+ ],
47
+ "defaultValue": "2023",
48
+ "subGrouping": {
49
+ "columnName": "quarter",
50
+ "defaultValue": "Q2",
51
+ "valuesLookup": {
52
+ "2022": {
53
+ "values": [
54
+ "Q1",
55
+ "Q2",
56
+ "Q3",
57
+ "Q4"
58
+ ],
59
+ "orderedValues": [
60
+ "Q1",
61
+ "Q2",
62
+ "Q3",
63
+ "Q4"
64
+ ]
65
+ },
66
+ "2023": {
67
+ "values": [
68
+ "Q1",
69
+ "Q2",
70
+ "Q3",
71
+ "Q4"
72
+ ],
73
+ "orderedValues": [
74
+ "Q1",
75
+ "Q2",
76
+ "Q3",
77
+ "Q4"
78
+ ]
79
+ },
80
+ "2024": {
81
+ "values": [
82
+ "Q1",
83
+ "Q2",
84
+ "Q3",
85
+ "Q4"
86
+ ],
87
+ "orderedValues": [
88
+ "Q1",
89
+ "Q2",
90
+ "Q3",
91
+ "Q4"
92
+ ]
93
+ }
94
+ }
95
+ }
96
+ }
97
+ ]
98
+ },
99
+ "rows": [
100
+ {
101
+ "columns": [
102
+ {
103
+ "width": 12,
104
+ "widget": "dashboardFilters1"
105
+ }
106
+ ]
107
+ },
108
+ {
109
+ "columns": [
110
+ {
111
+ "width": 12,
112
+ "widget": "chart1"
113
+ }
114
+ ]
115
+ }
116
+ ],
117
+ "visualizations": {
118
+ "dashboardFilters1": {
119
+ "filters": [],
120
+ "filterBehavior": "Filter Change",
121
+ "uid": "dashboardFilters1",
122
+ "type": "dashboardFilters",
123
+ "sharedFilterIndexes": [
124
+ 0,
125
+ 1
126
+ ],
127
+ "visualizationType": "dashboardFilters"
128
+ },
129
+ "chart1": {
130
+ "filters": [],
131
+ "filterBehavior": "Filter Change",
132
+ "uid": "chart1",
133
+ "type": "chart",
134
+ "visualizationType": "Line",
135
+ "dataDescription": {
136
+ "horizontal": false,
137
+ "series": false
138
+ },
139
+ "dataKey": "nested-parent-child-data.json",
140
+ "title": "Sales by Quarter",
141
+ "showTitle": true,
142
+ "xAxis": {
143
+ "label": "Quarter",
144
+ "dataKey": "quarter"
145
+ },
146
+ "yAxis": {
147
+ "label": "Sales ($)",
148
+ "dataKey": "sales",
149
+ "numTicks": 5
150
+ }
151
+ }
152
+ },
153
+ "datasets": {
154
+ "nested-parent-child-data.json": {
155
+ "data": [
156
+ {
157
+ "region": "North",
158
+ "year": "2022",
159
+ "quarter": "Q1",
160
+ "sales": 125000
161
+ },
162
+ {
163
+ "region": "North",
164
+ "year": "2022",
165
+ "quarter": "Q2",
166
+ "sales": 135000
167
+ },
168
+ {
169
+ "region": "North",
170
+ "year": "2022",
171
+ "quarter": "Q3",
172
+ "sales": 145000
173
+ },
174
+ {
175
+ "region": "North",
176
+ "year": "2022",
177
+ "quarter": "Q4",
178
+ "sales": 155000
179
+ },
180
+ {
181
+ "region": "North",
182
+ "year": "2023",
183
+ "quarter": "Q1",
184
+ "sales": 165000
185
+ },
186
+ {
187
+ "region": "North",
188
+ "year": "2023",
189
+ "quarter": "Q2",
190
+ "sales": 175000
191
+ },
192
+ {
193
+ "region": "North",
194
+ "year": "2023",
195
+ "quarter": "Q3",
196
+ "sales": 185000
197
+ },
198
+ {
199
+ "region": "North",
200
+ "year": "2023",
201
+ "quarter": "Q4",
202
+ "sales": 195000
203
+ },
204
+ {
205
+ "region": "North",
206
+ "year": "2024",
207
+ "quarter": "Q1",
208
+ "sales": 205000
209
+ },
210
+ {
211
+ "region": "North",
212
+ "year": "2024",
213
+ "quarter": "Q2",
214
+ "sales": 215000
215
+ },
216
+ {
217
+ "region": "North",
218
+ "year": "2024",
219
+ "quarter": "Q3",
220
+ "sales": 225000
221
+ },
222
+ {
223
+ "region": "North",
224
+ "year": "2024",
225
+ "quarter": "Q4",
226
+ "sales": 235000
227
+ },
228
+ {
229
+ "region": "South",
230
+ "year": "2022",
231
+ "quarter": "Q1",
232
+ "sales": 95000
233
+ },
234
+ {
235
+ "region": "South",
236
+ "year": "2022",
237
+ "quarter": "Q2",
238
+ "sales": 105000
239
+ },
240
+ {
241
+ "region": "South",
242
+ "year": "2022",
243
+ "quarter": "Q3",
244
+ "sales": 115000
245
+ },
246
+ {
247
+ "region": "South",
248
+ "year": "2022",
249
+ "quarter": "Q4",
250
+ "sales": 125000
251
+ },
252
+ {
253
+ "region": "South",
254
+ "year": "2023",
255
+ "quarter": "Q1",
256
+ "sales": 135000
257
+ },
258
+ {
259
+ "region": "South",
260
+ "year": "2023",
261
+ "quarter": "Q2",
262
+ "sales": 145000
263
+ },
264
+ {
265
+ "region": "South",
266
+ "year": "2023",
267
+ "quarter": "Q3",
268
+ "sales": 155000
269
+ },
270
+ {
271
+ "region": "South",
272
+ "year": "2023",
273
+ "quarter": "Q4",
274
+ "sales": 165000
275
+ },
276
+ {
277
+ "region": "South",
278
+ "year": "2024",
279
+ "quarter": "Q1",
280
+ "sales": 175000
281
+ },
282
+ {
283
+ "region": "South",
284
+ "year": "2024",
285
+ "quarter": "Q2",
286
+ "sales": 185000
287
+ },
288
+ {
289
+ "region": "South",
290
+ "year": "2024",
291
+ "quarter": "Q3",
292
+ "sales": 195000
293
+ },
294
+ {
295
+ "region": "South",
296
+ "year": "2024",
297
+ "quarter": "Q4",
298
+ "sales": 205000
299
+ },
300
+ {
301
+ "region": "East",
302
+ "year": "2023",
303
+ "quarter": "Q1",
304
+ "sales": 145000
305
+ },
306
+ {
307
+ "region": "East",
308
+ "year": "2023",
309
+ "quarter": "Q2",
310
+ "sales": 155000
311
+ },
312
+ {
313
+ "region": "East",
314
+ "year": "2023",
315
+ "quarter": "Q3",
316
+ "sales": 165000
317
+ },
318
+ {
319
+ "region": "East",
320
+ "year": "2023",
321
+ "quarter": "Q4",
322
+ "sales": 175000
323
+ },
324
+ {
325
+ "region": "East",
326
+ "year": "2024",
327
+ "quarter": "Q1",
328
+ "sales": 185000
329
+ },
330
+ {
331
+ "region": "East",
332
+ "year": "2024",
333
+ "quarter": "Q2",
334
+ "sales": 195000
335
+ },
336
+ {
337
+ "region": "East",
338
+ "year": "2024",
339
+ "quarter": "Q3",
340
+ "sales": 205000
341
+ },
342
+ {
343
+ "region": "East",
344
+ "year": "2024",
345
+ "quarter": "Q4",
346
+ "sales": 215000
347
+ },
348
+ {
349
+ "region": "West",
350
+ "year": "2023",
351
+ "quarter": "Q3",
352
+ "sales": 125000
353
+ },
354
+ {
355
+ "region": "West",
356
+ "year": "2023",
357
+ "quarter": "Q4",
358
+ "sales": 135000
359
+ },
360
+ {
361
+ "region": "West",
362
+ "year": "2024",
363
+ "quarter": "Q1",
364
+ "sales": 145000
365
+ },
366
+ {
367
+ "region": "West",
368
+ "year": "2024",
369
+ "quarter": "Q2",
370
+ "sales": 155000
371
+ },
372
+ {
373
+ "region": "West",
374
+ "year": "2024",
375
+ "quarter": "Q3",
376
+ "sales": 165000
377
+ },
378
+ {
379
+ "region": "West",
380
+ "year": "2024",
381
+ "quarter": "Q4",
382
+ "sales": 175000
383
+ }
384
+ ],
385
+ "dataFileSize": 2345,
386
+ "dataFileName": "nested-parent-child-data.json",
387
+ "dataFileSourceType": "file",
388
+ "dataFileFormat": "JSON",
389
+ "preview": true
390
+ }
391
+ }
392
+ }
@@ -0,0 +1,233 @@
1
+ {
2
+ "dashboard": {
3
+ "theme": "theme-blue",
4
+ "title": "Parent-Child Filter Demo",
5
+ "description": "Demonstrates hierarchical filter relationships with defaultValue support",
6
+ "sharedFilters": [
7
+ {
8
+ "key": "State",
9
+ "showDropdown": true,
10
+ "values": [
11
+ "California",
12
+ "Texas",
13
+ "New York"
14
+ ],
15
+ "type": "datafilter",
16
+ "orderedValues": [
17
+ "California",
18
+ "Texas",
19
+ "New York"
20
+ ],
21
+ "columnName": "state",
22
+ "tier": 1,
23
+ "defaultValue": "California"
24
+ },
25
+ {
26
+ "key": "County",
27
+ "showDropdown": true,
28
+ "values": [],
29
+ "type": "datafilter",
30
+ "orderedValues": [],
31
+ "columnName": "county",
32
+ "tier": 2,
33
+ "parents": [
34
+ "State"
35
+ ],
36
+ "defaultValue": "Los Angeles"
37
+ },
38
+ {
39
+ "key": "City",
40
+ "showDropdown": true,
41
+ "values": [],
42
+ "type": "datafilter",
43
+ "orderedValues": [],
44
+ "columnName": "city",
45
+ "tier": 3,
46
+ "parents": [
47
+ "County"
48
+ ],
49
+ "defaultValue": "Los Angeles"
50
+ }
51
+ ]
52
+ },
53
+ "rows": [
54
+ {
55
+ "columns": [
56
+ {
57
+ "width": 12,
58
+ "widget": "dashboardFilters1"
59
+ }
60
+ ]
61
+ },
62
+ {
63
+ "columns": [
64
+ {
65
+ "width": 12,
66
+ "widget": "chart1"
67
+ }
68
+ ]
69
+ }
70
+ ],
71
+ "visualizations": {
72
+ "dashboardFilters1": {
73
+ "filters": [],
74
+ "filterBehavior": "Filter Change",
75
+ "uid": "dashboardFilters1",
76
+ "type": "dashboardFilters",
77
+ "sharedFilterIndexes": [
78
+ 0,
79
+ 1,
80
+ 2
81
+ ],
82
+ "visualizationType": "dashboardFilters"
83
+ },
84
+ "chart1": {
85
+ "filters": [],
86
+ "filterBehavior": "Filter Change",
87
+ "uid": "chart1",
88
+ "type": "chart",
89
+ "visualizationType": "Bar",
90
+ "dataDescription": {
91
+ "horizontal": false,
92
+ "series": false
93
+ },
94
+ "dataKey": "parent-child-data.json",
95
+ "title": "Population by City",
96
+ "showTitle": true,
97
+ "xAxis": {
98
+ "label": "City",
99
+ "dataKey": "city"
100
+ },
101
+ "yAxis": {
102
+ "label": "Population",
103
+ "dataKey": "population",
104
+ "numTicks": 5
105
+ }
106
+ }
107
+ },
108
+ "datasets": {
109
+ "parent-child-data.json": {
110
+ "data": [
111
+ {
112
+ "state": "California",
113
+ "county": "Los Angeles",
114
+ "city": "Los Angeles",
115
+ "population": 3979576
116
+ },
117
+ {
118
+ "state": "California",
119
+ "county": "Los Angeles",
120
+ "city": "Long Beach",
121
+ "population": 466742
122
+ },
123
+ {
124
+ "state": "California",
125
+ "county": "Los Angeles",
126
+ "city": "Pasadena",
127
+ "population": 138699
128
+ },
129
+ {
130
+ "state": "California",
131
+ "county": "San Diego",
132
+ "city": "San Diego",
133
+ "population": 1423851
134
+ },
135
+ {
136
+ "state": "California",
137
+ "county": "San Diego",
138
+ "city": "Chula Vista",
139
+ "population": 275487
140
+ },
141
+ {
142
+ "state": "California",
143
+ "county": "Orange",
144
+ "city": "Anaheim",
145
+ "population": 346824
146
+ },
147
+ {
148
+ "state": "California",
149
+ "county": "Orange",
150
+ "city": "Santa Ana",
151
+ "population": 310227
152
+ },
153
+ {
154
+ "state": "California",
155
+ "county": "Orange",
156
+ "city": "Irvine",
157
+ "population": 307670
158
+ },
159
+ {
160
+ "state": "Texas",
161
+ "county": "Harris",
162
+ "city": "Houston",
163
+ "population": 2320268
164
+ },
165
+ {
166
+ "state": "Texas",
167
+ "county": "Harris",
168
+ "city": "Pasadena",
169
+ "population": 151950
170
+ },
171
+ {
172
+ "state": "Texas",
173
+ "county": "Dallas",
174
+ "city": "Dallas",
175
+ "population": 1304379
176
+ },
177
+ {
178
+ "state": "Texas",
179
+ "county": "Dallas",
180
+ "city": "Irving",
181
+ "population": 256684
182
+ },
183
+ {
184
+ "state": "Texas",
185
+ "county": "Bexar",
186
+ "city": "San Antonio",
187
+ "population": 1547253
188
+ },
189
+ {
190
+ "state": "Texas",
191
+ "county": "Travis",
192
+ "city": "Austin",
193
+ "population": 978908
194
+ },
195
+ {
196
+ "state": "New York",
197
+ "county": "New York",
198
+ "city": "Manhattan",
199
+ "population": 1694251
200
+ },
201
+ {
202
+ "state": "New York",
203
+ "county": "Kings",
204
+ "city": "Brooklyn",
205
+ "population": 2736074
206
+ },
207
+ {
208
+ "state": "New York",
209
+ "county": "Queens",
210
+ "city": "Queens",
211
+ "population": 2405464
212
+ },
213
+ {
214
+ "state": "New York",
215
+ "county": "Bronx",
216
+ "city": "Bronx",
217
+ "population": 1472654
218
+ },
219
+ {
220
+ "state": "New York",
221
+ "county": "Richmond",
222
+ "city": "Staten Island",
223
+ "population": 495747
224
+ }
225
+ ],
226
+ "dataFileSize": 1234,
227
+ "dataFileName": "parent-child-data.json",
228
+ "dataFileSourceType": "file",
229
+ "dataFileFormat": "JSON",
230
+ "preview": true
231
+ }
232
+ }
233
+ }
@@ -1,10 +1,12 @@
1
1
  import React from 'react'
2
2
  import MultiSelect from '@cdc/core/components/MultiSelect'
3
+ import ComboBox from '@cdc/core/components/ComboBox'
3
4
  import { SharedFilter } from '../../types/SharedFilter'
4
5
  import { APIFilterDropdowns, DropdownOptions } from './DashboardFiltersWrapper'
5
6
  import { FILTER_STYLE } from '../../types/FilterStyles'
6
7
  import { NestedOptions, ValueTextPair } from '@cdc/core/components/NestedDropdown/nestedDropdownHelpers'
7
8
  import NestedDropdown from '@cdc/core/components/NestedDropdown'
9
+ import { getNestedOptions } from '@cdc/core/components/Filters/helpers/getNestedOptions'
8
10
  import { MouseEventHandler } from 'react'
9
11
  import Loader from '@cdc/core/components/Loader'
10
12
  import _ from 'lodash'
@@ -56,14 +58,12 @@ const DashboardFilters: React.FC<DashboardFilterProps> = ({
56
58
 
57
59
  return (
58
60
  <form className='d-flex flex-wrap'>
59
- {sharedFilters.map((filter, filterIndex) => {
61
+ {show.map(filterIndex => {
62
+ const filter = sharedFilters[filterIndex]
60
63
  const urlFilterType = filter.type === 'urlfilter'
61
64
  const label = stripDuplicateLabelIncrement(filter.key || '')
62
65
 
63
- if (
64
- (!urlFilterType && !filter.showDropdown && filter.filterStyle !== FILTER_STYLE.nestedDropdown) ||
65
- (show && !show.includes(filterIndex))
66
- )
66
+ if (!urlFilterType && !filter.showDropdown && filter.filterStyle !== FILTER_STYLE.nestedDropdown)
67
67
  return <React.Fragment key={`${filter.key}-filtersection-${filterIndex}-option`} />
68
68
  const values: JSX.Element[] = []
69
69
 
@@ -71,12 +71,11 @@ const DashboardFilters: React.FC<DashboardFilterProps> = ({
71
71
  const loading = apiFilterDropdowns[_key] === null
72
72
 
73
73
  const multiValues: { value; label }[] = []
74
- const nestedOptions: NestedOptions = Object.entries(filter?.subGrouping?.valuesLookup || {}).map(
75
- ([key, data]) => [
76
- [key, key], // Main option: [value, text]
77
- Array.isArray(data?.values) ? data.values.map(value => [value, value]) : [] // Ensure `values` is an array
78
- ]
79
- )
74
+ const nestedOptions: NestedOptions = getNestedOptions({
75
+ orderedValues: filter.orderedValues,
76
+ values: filter.values,
77
+ subGrouping: filter.subGrouping
78
+ })
80
79
 
81
80
  if (_key && apiFilterDropdowns[_key]) {
82
81
  // URL Filter
@@ -154,6 +153,16 @@ const DashboardFilters: React.FC<DashboardFilterProps> = ({
154
153
  handleSelectedItems={value => updateField(null, null, filterIndex, value)}
155
154
  loading={loading}
156
155
  />
156
+ ) : filter.filterStyle === FILTER_STYLE.combobox ? (
157
+ <ComboBox
158
+ options={multiValues}
159
+ fieldName={filterIndex}
160
+ updateField={updateField}
161
+ selected={(filter.queuedActive || filter.active) as string}
162
+ label={label}
163
+ loading={loading}
164
+ placeholder={filter.resetLabel || '- Select -'}
165
+ />
157
166
  ) : (
158
167
  <>
159
168
  <select