@cdc/dashboard 4.26.2 → 4.26.4

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 (109) hide show
  1. package/CONFIG.md +172 -0
  2. package/README.md +60 -20
  3. package/dist/cdcdashboard-CY9IcPSi.es.js +6 -0
  4. package/dist/cdcdashboard-DlpiY3fQ.es.js +4 -0
  5. package/dist/cdcdashboard.js +56686 -50281
  6. package/examples/__data__/data-2.json +6 -0
  7. package/examples/__data__/data-with-metadata.json +18 -0
  8. package/examples/__data__/data.json +6 -0
  9. package/examples/default.json +7 -36
  10. package/examples/legend-issue.json +1 -1
  11. package/examples/minimal-example.json +34 -0
  12. package/examples/private/dengue.json +4640 -0
  13. package/examples/private/inline-markup.json +775 -0
  14. package/examples/private/link_to_file.json +16662 -0
  15. package/examples/private/recent-update.json +1456 -0
  16. package/examples/private/toggle.json +10137 -0
  17. package/examples/sankey.json +3 -3
  18. package/examples/test-api-filter-reset.json +4 -4
  19. package/examples/tp5-test.json +86 -4
  20. package/package.json +9 -9
  21. package/src/CdcDashboard.tsx +2 -1
  22. package/src/CdcDashboardComponent.tsx +48 -28
  23. package/src/_stories/Dashboard.DataSetup.stories.tsx +6 -1
  24. package/src/_stories/Dashboard.Pages.smoke.stories.tsx +22 -0
  25. package/src/_stories/Dashboard.smoke.stories.tsx +33 -0
  26. package/src/_stories/Dashboard.stories.tsx +4523 -83
  27. package/src/_stories/_mock/dashboard-data-driven-colors.json +171 -0
  28. package/src/_stories/_mock/tab-simple-filter.json +153 -0
  29. package/src/_stories/_mock/tp5-test.json +86 -5
  30. package/src/components/DashboardEditors.tsx +15 -0
  31. package/src/components/DashboardFilters/DashboardFilters.test.tsx +129 -0
  32. package/src/components/DashboardFilters/DashboardFilters.tsx +29 -10
  33. package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +12 -8
  34. package/src/components/DashboardFilters/DashboardFiltersEditor/components/APIModal.tsx +6 -4
  35. package/src/components/DashboardFilters/DashboardFiltersEditor/components/DeleteFilterModal.tsx +59 -58
  36. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.test.tsx +127 -0
  37. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +29 -6
  38. package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +10 -9
  39. package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +8 -8
  40. package/src/components/DashboardFilters/_stories/DashboardFilters.stories.tsx +1 -1
  41. package/src/components/DashboardFilters/dashboardfilter.styles.css +3 -3
  42. package/src/components/DataDesignerModal.tsx +2 -2
  43. package/src/components/ExpandCollapseButtons.tsx +6 -4
  44. package/src/components/Grid.tsx +4 -3
  45. package/src/components/Header/Header.tsx +27 -5
  46. package/src/components/Header/index.scss +1 -1
  47. package/src/components/MultiConfigTabs/MultiConfigTabs.tsx +141 -140
  48. package/src/components/MultiConfigTabs/multiconfigtabs.styles.css +6 -6
  49. package/src/components/Row.tsx +30 -8
  50. package/src/components/Toggle/toggle-style.css +7 -7
  51. package/src/components/VisualizationRow.tsx +81 -22
  52. package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +2 -55
  53. package/src/components/VisualizationsPanel/visualizations-panel-styles.css +2 -2
  54. package/src/components/Widget/Widget.tsx +7 -6
  55. package/src/components/Widget/widget.styles.css +48 -17
  56. package/src/data/initial-state.js +2 -1
  57. package/src/helpers/addVisualization.ts +73 -0
  58. package/src/helpers/formatConfigBeforeSave.ts +1 -1
  59. package/src/helpers/getVizConfig.ts +13 -3
  60. package/src/helpers/iconHash.tsx +45 -36
  61. package/src/helpers/processDataLegacy.ts +19 -14
  62. package/src/helpers/tests/addVisualization.test.ts +52 -0
  63. package/src/helpers/tests/formatConfigBeforeSave.test.ts +81 -1
  64. package/src/scss/editor-panel.scss +1 -1
  65. package/src/scss/grid.scss +38 -8
  66. package/src/scss/main.scss +237 -40
  67. package/src/store/dashboard.reducer.ts +2 -1
  68. package/src/test/CdcDashboard.test.jsx +26 -2
  69. package/src/test/CdcDashboardComponent.test.tsx +74 -0
  70. package/src/types/FilterStyles.ts +2 -1
  71. package/src/types/SharedFilter.ts +1 -0
  72. package/tests/fixtures/dashboard-config-with-metadata.json +89 -0
  73. package/vite.config.js +2 -2
  74. package/dist/cdcdashboard-Cf9_fbQf.es.js +0 -6
  75. package/examples/DEV-6574.json +0 -2224
  76. package/examples/api-dashboard-data.json +0 -272
  77. package/examples/api-dashboard-years.json +0 -11
  78. package/examples/api-geographies-data.json +0 -11
  79. package/examples/chart-data.json +0 -5409
  80. package/examples/custom/css/respiratory.css +0 -236
  81. package/examples/custom/js/respiratory.js +0 -242
  82. package/examples/default-data.json +0 -368
  83. package/examples/default-filter-control.json +0 -209
  84. package/examples/default-multi-dataset-shared-filter.json +0 -1729
  85. package/examples/default-multi-dataset.json +0 -506
  86. package/examples/ed-visits-county-file.json +0 -402
  87. package/examples/filters/Alabama.json +0 -72
  88. package/examples/filters/Alaska.json +0 -1737
  89. package/examples/filters/Arkansas.json +0 -4713
  90. package/examples/filters/California.json +0 -212
  91. package/examples/filters/Colorado.json +0 -1500
  92. package/examples/filters/Connecticut.json +0 -559
  93. package/examples/filters/Delaware.json +0 -63
  94. package/examples/filters/DistrictofColumbia.json +0 -63
  95. package/examples/filters/Florida.json +0 -4217
  96. package/examples/filters/States.json +0 -146
  97. package/examples/state-level.json +0 -90136
  98. package/examples/state-points.json +0 -10474
  99. package/examples/temp-example-data.json +0 -130
  100. package/examples/test-dashboard-simple.json +0 -503
  101. package/examples/test-example.json +0 -752
  102. package/examples/test-file.json +0 -147
  103. package/examples/test.json +0 -752
  104. package/examples/testing.json +0 -94456
  105. /package/examples/{legend-issue-data.json → __data__/legend-issue-data.json} +0 -0
  106. /package/examples/api-test/{categories.json → __data__/categories.json} +0 -0
  107. /package/examples/api-test/{chart-data.json → __data__/chart-data.json} +0 -0
  108. /package/examples/api-test/{topics.json → __data__/topics.json} +0 -0
  109. /package/examples/api-test/{years.json → __data__/years.json} +0 -0
@@ -0,0 +1,171 @@
1
+ {
2
+ "type": "dashboard",
3
+ "title": "COVID-19 County Case Tracker",
4
+ "description": "Select a state to view COVID-19 case counts by county. Background colors reflect the current alert status.",
5
+ "datasets": {
6
+ "covid-counties": {
7
+ "data": [
8
+ {
9
+ "State": "California",
10
+ "County1": "Los Angeles", "Cases1": "12847", "Status1": "Critical",
11
+ "County2": "San Diego", "Cases2": "4521", "Status2": "High",
12
+ "County3": "Sacramento", "Cases3": "1893", "Status3": "Medium"
13
+ },
14
+ {
15
+ "State": "Texas",
16
+ "County1": "Harris", "Cases1": "9734", "Status1": "High",
17
+ "County2": "Dallas", "Cases2": "7218", "Status2": "High",
18
+ "County3": "Travis", "Cases3": "2105", "Status3": "Medium"
19
+ },
20
+ {
21
+ "State": "New York",
22
+ "County1": "Kings", "Cases1": "3842", "Status1": "Medium",
23
+ "County2": "Queens", "Cases2": "3156", "Status2": "Medium",
24
+ "County3": "Erie", "Cases3": "987", "Status3": "Low"
25
+ },
26
+ {
27
+ "State": "Florida",
28
+ "County1": "Miami-Dade", "Cases1": "11203", "Status1": "Critical",
29
+ "County2": "Broward", "Cases2": "6890", "Status2": "High",
30
+ "County3": "Hillsborough", "Cases3": "3214", "Status3": "Medium"
31
+ },
32
+ {
33
+ "State": "Ohio",
34
+ "County1": "Franklin", "Cases1": "1542", "Status1": "Low",
35
+ "County2": "Cuyahoga", "Cases2": "1321", "Status2": "Low",
36
+ "County3": "Hamilton", "Cases3": "876", "Status3": "Low"
37
+ }
38
+ ]
39
+ }
40
+ },
41
+ "dashboard": {
42
+ "theme": "theme-blue",
43
+ "sharedFilters": [
44
+ {
45
+ "key": "State Filter",
46
+ "label": "Select State",
47
+ "columnName": "State",
48
+ "showDropdown": true,
49
+ "active": "California",
50
+ "values": ["California", "Florida", "New York", "Ohio", "Texas"],
51
+ "usedBy": ["bite-county-1", "bite-county-2", "bite-county-3"],
52
+ "tier": 1,
53
+ "type": "datafilter"
54
+ }
55
+ ]
56
+ },
57
+ "rows": [
58
+ [
59
+ { "width": 4, "widget": "bite-county-1" },
60
+ { "width": 4, "widget": "bite-county-2" },
61
+ { "width": 4, "widget": "bite-county-3" }
62
+ ]
63
+ ],
64
+ "visualizations": {
65
+ "bite-county-1": {
66
+ "uid": "bite-county-1",
67
+ "type": "data-bite",
68
+ "title": "County 1",
69
+ "biteStyle": "tp5",
70
+ "dataKey": "covid-counties",
71
+ "dataColumn": "Cases1",
72
+ "dataFunction": "Pass Through",
73
+ "biteBody": "confirmed cases",
74
+ "subtext": "",
75
+ "dataFormat": {
76
+ "roundToPlace": 0,
77
+ "commas": true,
78
+ "prefix": "",
79
+ "suffix": ""
80
+ },
81
+ "filters": [],
82
+ "theme": "theme-blue",
83
+ "visual": {
84
+ "border": false,
85
+ "accent": false,
86
+ "background": false,
87
+ "hideBackgroundColor": false,
88
+ "borderColorTheme": false
89
+ },
90
+ "dataColors": {
91
+ "column": "Status1",
92
+ "mappings": [
93
+ { "sourceValue": "Low", "color": "#d7f2ed" },
94
+ { "sourceValue": "Medium", "color": "#b8e5ac" },
95
+ { "sourceValue": "High", "color": "#fea82f" },
96
+ { "sourceValue": "Critical", "color": "#a03169" }
97
+ ]
98
+ }
99
+ },
100
+ "bite-county-2": {
101
+ "uid": "bite-county-2",
102
+ "type": "data-bite",
103
+ "title": "County 2",
104
+ "biteStyle": "tp5",
105
+ "dataKey": "covid-counties",
106
+ "dataColumn": "Cases2",
107
+ "dataFunction": "Pass Through",
108
+ "biteBody": "confirmed cases",
109
+ "subtext": "",
110
+ "dataFormat": {
111
+ "roundToPlace": 0,
112
+ "commas": true,
113
+ "prefix": "",
114
+ "suffix": ""
115
+ },
116
+ "filters": [],
117
+ "theme": "theme-blue",
118
+ "visual": {
119
+ "border": false,
120
+ "accent": false,
121
+ "background": false,
122
+ "hideBackgroundColor": false,
123
+ "borderColorTheme": false
124
+ },
125
+ "dataColors": {
126
+ "column": "Status2",
127
+ "mappings": [
128
+ { "sourceValue": "Low", "color": "#d7f2ed" },
129
+ { "sourceValue": "Medium", "color": "#b8e5ac" },
130
+ { "sourceValue": "High", "color": "#fea82f" },
131
+ { "sourceValue": "Critical", "color": "#a03169" }
132
+ ]
133
+ }
134
+ },
135
+ "bite-county-3": {
136
+ "uid": "bite-county-3",
137
+ "type": "data-bite",
138
+ "title": "County 3",
139
+ "biteStyle": "tp5",
140
+ "dataKey": "covid-counties",
141
+ "dataColumn": "Cases3",
142
+ "dataFunction": "Pass Through",
143
+ "biteBody": "confirmed cases",
144
+ "subtext": "",
145
+ "dataFormat": {
146
+ "roundToPlace": 0,
147
+ "commas": true,
148
+ "prefix": "",
149
+ "suffix": ""
150
+ },
151
+ "filters": [],
152
+ "theme": "theme-blue",
153
+ "visual": {
154
+ "border": false,
155
+ "accent": false,
156
+ "background": false,
157
+ "hideBackgroundColor": false,
158
+ "borderColorTheme": false
159
+ },
160
+ "dataColors": {
161
+ "column": "Status3",
162
+ "mappings": [
163
+ { "sourceValue": "Low", "color": "#d7f2ed" },
164
+ { "sourceValue": "Medium", "color": "#b8e5ac" },
165
+ { "sourceValue": "High", "color": "#fea82f" },
166
+ { "sourceValue": "Critical", "color": "#a03169" }
167
+ ]
168
+ }
169
+ }
170
+ }
171
+ }
@@ -0,0 +1,153 @@
1
+ {
2
+ "dashboard": {
3
+ "theme": "theme-blue",
4
+ "sharedFilters": [
5
+ {
6
+ "key": "category",
7
+ "showDropdown": true,
8
+ "filterStyle": "tab-simple",
9
+ "values": ["Category A", "Category B", "Category C"],
10
+ "orderedValues": ["Category A", "Category B", "Category C"],
11
+ "type": "datafilter",
12
+ "columnName": "category",
13
+ "tier": 1,
14
+ "order": "cust",
15
+ "defaultValue": "Category A"
16
+ }
17
+ ]
18
+ },
19
+ "rows": [
20
+ {
21
+ "columns": [
22
+ {
23
+ "width": 12,
24
+ "widget": "dashboardFilters1"
25
+ }
26
+ ]
27
+ },
28
+ {
29
+ "columns": [
30
+ {
31
+ "width": 12,
32
+ "widget": "chart1"
33
+ }
34
+ ]
35
+ }
36
+ ],
37
+ "visualizations": {
38
+ "dashboardFilters1": {
39
+ "filters": [],
40
+ "filterBehavior": "Filter Change",
41
+ "newViz": true,
42
+ "uid": "dashboardFilters1",
43
+ "type": "dashboardFilters",
44
+ "sharedFilterIndexes": [0],
45
+ "visualizationType": "dashboardFilters"
46
+ },
47
+ "chart1": {
48
+ "filters": [],
49
+ "filterBehavior": "Filter Change",
50
+ "uid": "chart1",
51
+ "type": "chart",
52
+ "visualizationType": "Bar",
53
+ "title": "Sales by Category",
54
+ "showTitle": true,
55
+ "theme": "theme-blue",
56
+ "animate": false,
57
+ "dataKey": "./tab-simple-data.json",
58
+ "dataDescription": {
59
+ "horizontal": false,
60
+ "series": false
61
+ },
62
+ "xAxis": {
63
+ "dataKey": "product",
64
+ "type": "categorical",
65
+ "hideAxis": false,
66
+ "hideLabel": false,
67
+ "hideTicks": false,
68
+ "size": 75,
69
+ "tickRotation": 0,
70
+ "labelColor": "#1c1d1f",
71
+ "tickLabelColor": "#1c1d1f",
72
+ "tickColor": "#1c1d1f",
73
+ "axisPadding": 200,
74
+ "padding": 5,
75
+ "sortDates": false,
76
+ "anchors": []
77
+ },
78
+ "yAxis": {
79
+ "hideAxis": false,
80
+ "hideLabel": false,
81
+ "hideTicks": false,
82
+ "size": 50,
83
+ "gridLines": false,
84
+ "labelColor": "#1c1d1f",
85
+ "tickLabelColor": "#1c1d1f",
86
+ "tickColor": "#1c1d1f",
87
+ "anchors": [],
88
+ "categories": []
89
+ },
90
+ "series": [
91
+ {
92
+ "dataKey": "sales",
93
+ "type": "Bar",
94
+ "axis": "Left",
95
+ "tooltip": true
96
+ }
97
+ ],
98
+ "orientation": "vertical",
99
+ "general": {
100
+ "showZeroValueData": true,
101
+ "palette": {
102
+ "name": "qualitative_bold",
103
+ "version": "1.0"
104
+ }
105
+ },
106
+ "columns": {},
107
+ "legend": {
108
+ "hide": true
109
+ },
110
+ "table": {
111
+ "label": "Data Table",
112
+ "show": false,
113
+ "sharedFilterColumns": ["category"]
114
+ },
115
+ "heights": {
116
+ "vertical": 300,
117
+ "horizontal": 750
118
+ },
119
+ "visual": {
120
+ "border": true,
121
+ "accent": true,
122
+ "background": true
123
+ },
124
+ "tooltips": {
125
+ "opacity": 90,
126
+ "singleSeries": false
127
+ },
128
+ "barThickness": 0.35
129
+ }
130
+ },
131
+ "datasets": {
132
+ "./tab-simple-data.json": {
133
+ "data": [
134
+ { "category": "Category A", "product": "Widget", "sales": "120" },
135
+ { "category": "Category A", "product": "Gadget", "sales": "85" },
136
+ { "category": "Category A", "product": "Doohickey", "sales": "210" },
137
+ { "category": "Category B", "product": "Widget", "sales": "95" },
138
+ { "category": "Category B", "product": "Gadget", "sales": "150" },
139
+ { "category": "Category B", "product": "Doohickey", "sales": "60" },
140
+ { "category": "Category C", "product": "Widget", "sales": "175" },
141
+ { "category": "Category C", "product": "Gadget", "sales": "110" },
142
+ { "category": "Category C", "product": "Doohickey", "sales": "140" }
143
+ ],
144
+ "dataFileSize": 500,
145
+ "dataFileName": "./tab-simple-data.json",
146
+ "dataFileSourceType": "file",
147
+ "dataFileFormat": "JSON",
148
+ "preview": true
149
+ }
150
+ },
151
+ "type": "dashboard",
152
+ "version": "4.26.1"
153
+ }
@@ -40,13 +40,23 @@
40
40
  { "width": 4, "widget": "gauge1" },
41
41
  { "width": 4, "widget": "gauge2" },
42
42
  { "width": 4, "widget": "gauge3" }
43
+ ],
44
+ [
45
+ { "width": 4, "widget": "markup1" },
46
+ { "width": 4, "widget": "markup2" },
47
+ { "width": 4, "widget": "markup3" }
48
+ ],
49
+ [
50
+ { "width": 4, "widget": "waffle2" },
51
+ { "width": 4, "widget": "bite3" },
52
+ { "width": 4, "widget": "markup2" }
43
53
  ]
44
54
  ],
45
55
  "visualizations": {
46
56
  "waffle1": {
47
57
  "uid": "waffle1",
48
58
  "type": "waffle-chart",
49
- "title": "Vaccination Coverage",
59
+ "title": "Vaccination",
50
60
  "visualizationType": "TP5 Waffle",
51
61
  "visualizationSubType": "linear",
52
62
  "showPercent": true,
@@ -71,7 +81,7 @@
71
81
  "waffle2": {
72
82
  "uid": "waffle2",
73
83
  "type": "waffle-chart",
74
- "title": "Health Insurance Coverage Rate",
84
+ "title": "Health",
75
85
  "visualizationType": "TP5 Waffle",
76
86
  "visualizationSubType": "linear",
77
87
  "showPercent": true,
@@ -96,7 +106,7 @@
96
106
  "waffle3": {
97
107
  "uid": "waffle3",
98
108
  "type": "waffle-chart",
99
- "title": "Cancer Screening Completion",
109
+ "title": "Cancer",
100
110
  "visualizationType": "TP5 Waffle",
101
111
  "visualizationSubType": "linear",
102
112
  "showPercent": true,
@@ -245,7 +255,7 @@
245
255
  "bite3": {
246
256
  "uid": "bite3",
247
257
  "type": "data-bite",
248
- "title": "Cancer Screening Completion",
258
+ "title": "Cancer Screening Completion, and a little something else to make the title taller",
249
259
  "biteStyle": "tp5",
250
260
  "dataColumn": "Screening Rate",
251
261
  "dataFunction": "Mean (Average)",
@@ -261,7 +271,78 @@
261
271
  "visual": {
262
272
  "hideBackgroundColor": false
263
273
  }
274
+ },
275
+ "markup1": {
276
+ "uid": "markup1",
277
+ "type": "markup-include",
278
+ "title": "",
279
+ "theme": "theme-blue",
280
+ "contentEditor": {
281
+ "style": "tp5",
282
+ "title": "TP5 Markup Include",
283
+ "titleStyle": "small",
284
+ "useInlineHTML": true,
285
+ "inlineHTML": "<p><strong>68.5%</strong> of adults were vaccinated against seasonal flu in this sample dataset.</p>",
286
+ "srcUrl": "#example",
287
+ "showHeader": true,
288
+ "showNoDataMessage": false,
289
+ "noDataMessageText": "No Data Available"
290
+ },
291
+ "visual": {
292
+ "border": true,
293
+ "accent": false,
294
+ "whiteBackground": false,
295
+ "hideBackgroundColor": false,
296
+ "borderColorTheme": false
297
+ }
298
+ },
299
+ "markup2": {
300
+ "uid": "markup2",
301
+ "type": "markup-include",
302
+ "title": "",
303
+ "theme": "theme-teal",
304
+ "contentEditor": {
305
+ "style": "tp5",
306
+ "title": "White Background TP5",
307
+ "titleStyle": "small",
308
+ "useInlineHTML": true,
309
+ "inlineHTML": "<p>This TP5 markup include uses white-background styling with border enabled for comparison.</p>",
310
+ "srcUrl": "#example",
311
+ "showHeader": true,
312
+ "showNoDataMessage": false,
313
+ "noDataMessageText": "No Data Available"
314
+ },
315
+ "visual": {
316
+ "border": true,
317
+ "accent": false,
318
+ "whiteBackground": true,
319
+ "hideBackgroundColor": false,
320
+ "borderColorTheme": false
321
+ }
322
+ },
323
+ "markup3": {
324
+ "uid": "markup3",
325
+ "type": "markup-include",
326
+ "title": "",
327
+ "theme": "theme-purple",
328
+ "contentEditor": {
329
+ "style": "tp5",
330
+ "title": "TP5 Markup Include (No White BG)",
331
+ "titleStyle": "small",
332
+ "useInlineHTML": true,
333
+ "inlineHTML": "<p>This TP5 markup include uses the standard background and border settings for side-by-side alignment testing.</p>",
334
+ "srcUrl": "#example",
335
+ "showHeader": true,
336
+ "showNoDataMessage": false,
337
+ "noDataMessageText": "No Data Available"
338
+ },
339
+ "visual": {
340
+ "border": true,
341
+ "accent": false,
342
+ "whiteBackground": false,
343
+ "hideBackgroundColor": false,
344
+ "borderColorTheme": false
345
+ }
264
346
  }
265
347
  }
266
348
  }
267
-
@@ -77,6 +77,11 @@ const DashboardEditors: React.FC<DashboardEditorProps> = ({
77
77
  <CdcDataBite
78
78
  key={visualizationKey}
79
79
  config={{ ...visualizationConfig, newViz: true }}
80
+ rawData={
81
+ state.data?.[visualizationConfig.dataKey] ||
82
+ state.config.datasets?.[visualizationConfig.dataKey]?.data ||
83
+ []
84
+ }
80
85
  isEditor={true}
81
86
  setConfig={_updateConfig}
82
87
  isDashboard={true}
@@ -89,6 +94,11 @@ const DashboardEditors: React.FC<DashboardEditorProps> = ({
89
94
  <CdcWaffleChart
90
95
  key={visualizationKey}
91
96
  config={visualizationConfig}
97
+ rawData={
98
+ state.data?.[visualizationConfig.dataKey] ||
99
+ state.config.datasets?.[visualizationConfig.dataKey]?.data ||
100
+ []
101
+ }
92
102
  isEditor={true}
93
103
  setConfig={_updateConfig}
94
104
  isDashboard={true}
@@ -101,6 +111,11 @@ const DashboardEditors: React.FC<DashboardEditorProps> = ({
101
111
  <CdcMarkupInclude
102
112
  key={visualizationKey}
103
113
  config={visualizationConfig}
114
+ rawData={
115
+ state.data?.[visualizationConfig.dataKey] ||
116
+ state.config.datasets?.[visualizationConfig.dataKey]?.data ||
117
+ []
118
+ }
104
119
  isEditor={true}
105
120
  setConfig={_updateConfig}
106
121
  isDashboard={true}
@@ -0,0 +1,129 @@
1
+ import { fireEvent, render } from '@testing-library/react'
2
+ import { describe, expect, it, vi } from 'vitest'
3
+ import DashboardFilters from './DashboardFilters'
4
+
5
+ vi.mock('@cdc/core/components/ui/Icon', () => ({
6
+ default: props => <span data-testid='mock-icon' {...props} />
7
+ }))
8
+
9
+ const createDataBackedFilter = (displaySubgroupingOnly = false) =>
10
+ ({
11
+ key: 'Year and Quarter',
12
+ type: 'datafilter',
13
+ filterStyle: 'nested-dropdown',
14
+ showDropdown: true,
15
+ values: ['2023', '2024'],
16
+ columnName: 'year',
17
+ id: 0,
18
+ parents: [],
19
+ order: 'asc',
20
+ active: '2023',
21
+ displaySubgroupingOnly,
22
+ subGrouping: {
23
+ columnName: 'quarter',
24
+ active: 'Q2',
25
+ valuesLookup: {
26
+ '2023': { values: ['Q1', 'Q2'] },
27
+ '2024': { values: ['Q3', 'Q4'] }
28
+ }
29
+ }
30
+ } as any)
31
+
32
+ const createApiBackedFilter = (displaySubgroupingOnly = false) =>
33
+ ({
34
+ key: 'API Year and Quarter',
35
+ type: 'urlfilter',
36
+ filterStyle: 'nested-dropdown',
37
+ showDropdown: true,
38
+ values: [],
39
+ columnName: 'year',
40
+ id: 0,
41
+ parents: [],
42
+ order: 'asc',
43
+ active: '2023',
44
+ displaySubgroupingOnly,
45
+ apiFilter: {
46
+ apiEndpoint: '/api/nested-options',
47
+ valueSelector: 'year',
48
+ subgroupValueSelector: 'quarter'
49
+ },
50
+ subGrouping: {
51
+ columnName: 'quarter',
52
+ active: 'Q2',
53
+ valuesLookup: {}
54
+ }
55
+ } as any)
56
+
57
+ const apiFilterDropdowns = {
58
+ '/api/nested-options': [
59
+ {
60
+ value: '2023',
61
+ text: '2023',
62
+ subOptions: [
63
+ { value: 'Q1', text: 'Q1' },
64
+ { value: 'Q2', text: 'Q2' }
65
+ ]
66
+ },
67
+ {
68
+ value: '2024',
69
+ text: '2024',
70
+ subOptions: [
71
+ { value: 'Q3', text: 'Q3' },
72
+ { value: 'Q4', text: 'Q4' }
73
+ ]
74
+ }
75
+ ]
76
+ }
77
+
78
+ describe('DashboardFilters nested dropdown display', () => {
79
+ it.each([
80
+ ['data-backed', createDataBackedFilter(false), {}, '2023 - Q2'],
81
+ ['data-backed subgroup only', createDataBackedFilter(true), {}, 'Q2'],
82
+ ['api-backed', createApiBackedFilter(false), apiFilterDropdowns, '2023 - Q2'],
83
+ ['api-backed subgroup only', createApiBackedFilter(true), apiFilterDropdowns, 'Q2']
84
+ ])('shows the expected closed text for %s filters', (_label, filter, dropdowns, expectedValue) => {
85
+ const { container } = render(
86
+ <DashboardFilters
87
+ applyFilters={vi.fn()}
88
+ apiFilterDropdowns={dropdowns as any}
89
+ filters={[filter]}
90
+ handleOnChange={vi.fn()}
91
+ show={[0]}
92
+ showSubmit={false}
93
+ />
94
+ )
95
+
96
+ const input = container.querySelector('.nested-dropdown input')
97
+ expect(input).toHaveValue(expectedValue)
98
+ })
99
+
100
+ it.each([
101
+ ['data-backed', createDataBackedFilter(false), {}],
102
+ ['data-backed subgroup only', createDataBackedFilter(true), {}],
103
+ ['api-backed', createApiBackedFilter(false), apiFilterDropdowns],
104
+ ['api-backed subgroup only', createApiBackedFilter(true), apiFilterDropdowns]
105
+ ])('keeps nested dropdown selection behavior unchanged for %s filters', (_label, filter, dropdowns) => {
106
+ const handleOnChange = vi.fn()
107
+ const { container, getByText, queryByText } = render(
108
+ <DashboardFilters
109
+ applyFilters={vi.fn()}
110
+ apiFilterDropdowns={dropdowns as any}
111
+ filters={[filter]}
112
+ handleOnChange={handleOnChange}
113
+ show={[0]}
114
+ showSubmit={false}
115
+ />
116
+ )
117
+
118
+ const input = container.querySelector('.nested-dropdown input') as HTMLInputElement
119
+ fireEvent.focus(input)
120
+ fireEvent.change(input, { target: { value: 'Q3' } })
121
+
122
+ expect(getByText('2024')).toBeInTheDocument()
123
+ expect(queryByText('2023')).not.toBeInTheDocument()
124
+
125
+ fireEvent.click(getByText('Q3'))
126
+
127
+ expect(handleOnChange).toHaveBeenCalledWith(0, ['2024', 'Q3'])
128
+ })
129
+ })