@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.
- package/CONFIG.md +172 -0
- package/README.md +60 -20
- package/dist/cdcdashboard-CY9IcPSi.es.js +6 -0
- package/dist/cdcdashboard-DlpiY3fQ.es.js +4 -0
- package/dist/cdcdashboard.js +56686 -50281
- package/examples/__data__/data-2.json +6 -0
- package/examples/__data__/data-with-metadata.json +18 -0
- package/examples/__data__/data.json +6 -0
- package/examples/default.json +7 -36
- package/examples/legend-issue.json +1 -1
- package/examples/minimal-example.json +34 -0
- package/examples/private/dengue.json +4640 -0
- package/examples/private/inline-markup.json +775 -0
- package/examples/private/link_to_file.json +16662 -0
- package/examples/private/recent-update.json +1456 -0
- package/examples/private/toggle.json +10137 -0
- package/examples/sankey.json +3 -3
- package/examples/test-api-filter-reset.json +4 -4
- package/examples/tp5-test.json +86 -4
- package/package.json +9 -9
- package/src/CdcDashboard.tsx +2 -1
- package/src/CdcDashboardComponent.tsx +48 -28
- package/src/_stories/Dashboard.DataSetup.stories.tsx +6 -1
- package/src/_stories/Dashboard.Pages.smoke.stories.tsx +22 -0
- package/src/_stories/Dashboard.smoke.stories.tsx +33 -0
- package/src/_stories/Dashboard.stories.tsx +4523 -83
- package/src/_stories/_mock/dashboard-data-driven-colors.json +171 -0
- package/src/_stories/_mock/tab-simple-filter.json +153 -0
- package/src/_stories/_mock/tp5-test.json +86 -5
- package/src/components/DashboardEditors.tsx +15 -0
- package/src/components/DashboardFilters/DashboardFilters.test.tsx +129 -0
- package/src/components/DashboardFilters/DashboardFilters.tsx +29 -10
- package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +12 -8
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/APIModal.tsx +6 -4
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/DeleteFilterModal.tsx +59 -58
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.test.tsx +127 -0
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +29 -6
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +10 -9
- package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +8 -8
- package/src/components/DashboardFilters/_stories/DashboardFilters.stories.tsx +1 -1
- package/src/components/DashboardFilters/dashboardfilter.styles.css +3 -3
- package/src/components/DataDesignerModal.tsx +2 -2
- package/src/components/ExpandCollapseButtons.tsx +6 -4
- package/src/components/Grid.tsx +4 -3
- package/src/components/Header/Header.tsx +27 -5
- package/src/components/Header/index.scss +1 -1
- package/src/components/MultiConfigTabs/MultiConfigTabs.tsx +141 -140
- package/src/components/MultiConfigTabs/multiconfigtabs.styles.css +6 -6
- package/src/components/Row.tsx +30 -8
- package/src/components/Toggle/toggle-style.css +7 -7
- package/src/components/VisualizationRow.tsx +81 -22
- package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +2 -55
- package/src/components/VisualizationsPanel/visualizations-panel-styles.css +2 -2
- package/src/components/Widget/Widget.tsx +7 -6
- package/src/components/Widget/widget.styles.css +48 -17
- package/src/data/initial-state.js +2 -1
- package/src/helpers/addVisualization.ts +73 -0
- package/src/helpers/formatConfigBeforeSave.ts +1 -1
- package/src/helpers/getVizConfig.ts +13 -3
- package/src/helpers/iconHash.tsx +45 -36
- package/src/helpers/processDataLegacy.ts +19 -14
- package/src/helpers/tests/addVisualization.test.ts +52 -0
- package/src/helpers/tests/formatConfigBeforeSave.test.ts +81 -1
- package/src/scss/editor-panel.scss +1 -1
- package/src/scss/grid.scss +38 -8
- package/src/scss/main.scss +237 -40
- package/src/store/dashboard.reducer.ts +2 -1
- package/src/test/CdcDashboard.test.jsx +26 -2
- package/src/test/CdcDashboardComponent.test.tsx +74 -0
- package/src/types/FilterStyles.ts +2 -1
- package/src/types/SharedFilter.ts +1 -0
- package/tests/fixtures/dashboard-config-with-metadata.json +89 -0
- package/vite.config.js +2 -2
- package/dist/cdcdashboard-Cf9_fbQf.es.js +0 -6
- package/examples/DEV-6574.json +0 -2224
- package/examples/api-dashboard-data.json +0 -272
- package/examples/api-dashboard-years.json +0 -11
- package/examples/api-geographies-data.json +0 -11
- package/examples/chart-data.json +0 -5409
- package/examples/custom/css/respiratory.css +0 -236
- package/examples/custom/js/respiratory.js +0 -242
- package/examples/default-data.json +0 -368
- package/examples/default-filter-control.json +0 -209
- package/examples/default-multi-dataset-shared-filter.json +0 -1729
- package/examples/default-multi-dataset.json +0 -506
- package/examples/ed-visits-county-file.json +0 -402
- package/examples/filters/Alabama.json +0 -72
- package/examples/filters/Alaska.json +0 -1737
- package/examples/filters/Arkansas.json +0 -4713
- package/examples/filters/California.json +0 -212
- package/examples/filters/Colorado.json +0 -1500
- package/examples/filters/Connecticut.json +0 -559
- package/examples/filters/Delaware.json +0 -63
- package/examples/filters/DistrictofColumbia.json +0 -63
- package/examples/filters/Florida.json +0 -4217
- package/examples/filters/States.json +0 -146
- package/examples/state-level.json +0 -90136
- package/examples/state-points.json +0 -10474
- package/examples/temp-example-data.json +0 -130
- package/examples/test-dashboard-simple.json +0 -503
- package/examples/test-example.json +0 -752
- package/examples/test-file.json +0 -147
- package/examples/test.json +0 -752
- package/examples/testing.json +0 -94456
- /package/examples/{legend-issue-data.json → __data__/legend-issue-data.json} +0 -0
- /package/examples/api-test/{categories.json → __data__/categories.json} +0 -0
- /package/examples/api-test/{chart-data.json → __data__/chart-data.json} +0 -0
- /package/examples/api-test/{topics.json → __data__/topics.json} +0 -0
- /package/examples/api-test/{years.json → __data__/years.json} +0 -0
package/examples/sankey.json
CHANGED
|
@@ -4238,7 +4238,7 @@
|
|
|
4238
4238
|
}
|
|
4239
4239
|
],
|
|
4240
4240
|
"dataFileSize": 72,
|
|
4241
|
-
"dataFileName": "data.json",
|
|
4241
|
+
"dataFileName": "__data__/data.json",
|
|
4242
4242
|
"dataFileSourceType": "file",
|
|
4243
4243
|
"dataFileFormat": "JSON",
|
|
4244
4244
|
"preview": false
|
|
@@ -4251,7 +4251,7 @@
|
|
|
4251
4251
|
}
|
|
4252
4252
|
],
|
|
4253
4253
|
"dataFileSize": 59,
|
|
4254
|
-
"dataFileName": "data-2.json",
|
|
4254
|
+
"dataFileName": "__data__/data-2.json",
|
|
4255
4255
|
"dataFileSourceType": "file",
|
|
4256
4256
|
"dataFileFormat": "JSON",
|
|
4257
4257
|
"preview": false
|
|
@@ -5215,4 +5215,4 @@
|
|
|
5215
5215
|
"type": "dashboard",
|
|
5216
5216
|
"uuid": 1707343065225,
|
|
5217
5217
|
"runtime": {}
|
|
5218
|
-
}
|
|
5218
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "urlfilter",
|
|
8
8
|
"columnName": "category",
|
|
9
9
|
"apiFilter": {
|
|
10
|
-
"apiEndpoint": "/examples/api-test/categories.json",
|
|
10
|
+
"apiEndpoint": "/examples/api-test/__data__/categories.json",
|
|
11
11
|
"valueSelector": "category",
|
|
12
12
|
"textSelector": "category"
|
|
13
13
|
},
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"type": "urlfilter",
|
|
25
25
|
"columnName": "topic",
|
|
26
26
|
"apiFilter": {
|
|
27
|
-
"apiEndpoint": "/examples/api-test/topics.json",
|
|
27
|
+
"apiEndpoint": "/examples/api-test/__data__/topics.json",
|
|
28
28
|
"valueSelector": "topic",
|
|
29
29
|
"textSelector": "topic"
|
|
30
30
|
},
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"type": "urlfilter",
|
|
44
44
|
"columnName": "year",
|
|
45
45
|
"apiFilter": {
|
|
46
|
-
"apiEndpoint": "/examples/api-test/years.json",
|
|
46
|
+
"apiEndpoint": "/examples/api-test/__data__/years.json",
|
|
47
47
|
"valueSelector": "year",
|
|
48
48
|
"textSelector": "year"
|
|
49
49
|
},
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
},
|
|
129
129
|
"datasets": {
|
|
130
130
|
"chartData": {
|
|
131
|
-
"dataUrl": "http://localhost:8080/examples/api-test/chart-data.json"
|
|
131
|
+
"dataUrl": "http://localhost:8080/examples/api-test/__data__/chart-data.json"
|
|
132
132
|
}
|
|
133
133
|
},
|
|
134
134
|
"filterBehavior": "Apply Button",
|
package/examples/tp5-test.json
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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,6 +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
|
}
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/dashboard",
|
|
3
|
-
"version": "4.26.
|
|
3
|
+
"version": "4.26.4",
|
|
4
4
|
"description": "React component for combining multiple visualizations into a single dashboard",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Matthew Pallansch <mpallansch@adittech.com>",
|
|
7
7
|
"bugs": "https://github.com/CDCgov/cdc-open-viz/issues",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@cdc/chart": "^4.26.
|
|
10
|
-
"@cdc/core": "^4.26.
|
|
11
|
-
"@cdc/data-bite": "^4.26.
|
|
12
|
-
"@cdc/filtered-text": "^4.26.
|
|
13
|
-
"@cdc/map": "^4.26.
|
|
14
|
-
"@cdc/markup-include": "^4.26.
|
|
15
|
-
"@cdc/waffle-chart": "^4.26.
|
|
9
|
+
"@cdc/chart": "^4.26.4",
|
|
10
|
+
"@cdc/core": "^4.26.4",
|
|
11
|
+
"@cdc/data-bite": "^4.26.4",
|
|
12
|
+
"@cdc/filtered-text": "^4.26.4",
|
|
13
|
+
"@cdc/map": "^4.26.4",
|
|
14
|
+
"@cdc/markup-include": "^4.26.4",
|
|
15
|
+
"@cdc/waffle-chart": "^4.26.4",
|
|
16
16
|
"js-base64": "^2.5.2",
|
|
17
17
|
"react-accessible-accordion": "^5.0.1",
|
|
18
18
|
"react-dnd": "^16.0.1",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"vite-plugin-css-injected-by-js": "^2.4.0",
|
|
27
27
|
"vite-plugin-svgr": "^4.2.0"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "6097de1ff814001880d9ac64bd66becdc092d63c",
|
|
30
30
|
"main": "dist/cdcdashboard",
|
|
31
31
|
"moduleName": "CdcDashboard",
|
|
32
32
|
"peerDependencies": {
|
package/src/CdcDashboard.tsx
CHANGED
|
@@ -91,11 +91,12 @@ const MultiDashboardWrapper: React.FC<MultiDashboardProps> = ({
|
|
|
91
91
|
return prepareDatasets(newConfig)
|
|
92
92
|
} else {
|
|
93
93
|
const dataKey = newConfig.dataFileName || 'backwards-compatibility'
|
|
94
|
-
const data = await processDataLegacy(config)
|
|
94
|
+
const { data, dataMetadata } = await processDataLegacy(config)
|
|
95
95
|
|
|
96
96
|
const datasetsFull = {}
|
|
97
97
|
datasetsFull[dataKey] = {
|
|
98
98
|
data,
|
|
99
|
+
dataMetadata,
|
|
99
100
|
dataDescription: newConfig.dataDescription
|
|
100
101
|
}
|
|
101
102
|
newConfig.datasets = datasetsFull
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback, useMemo, useReducer, useContext } from 'react'
|
|
1
|
+
import React, { useState, useEffect, useCallback, useMemo, useReducer, useContext, useRef } from 'react'
|
|
2
2
|
import 'whatwg-fetch'
|
|
3
3
|
import ResizeObserver from 'resize-observer-polyfill'
|
|
4
4
|
|
|
@@ -39,7 +39,9 @@ import { type SharedFilter } from './types/SharedFilter'
|
|
|
39
39
|
import { type WCMSProps } from '@cdc/core/types/WCMSProps'
|
|
40
40
|
import { type InitialState } from './types/InitialState'
|
|
41
41
|
import MultiTabs from './components/MultiConfigTabs'
|
|
42
|
-
import
|
|
42
|
+
import cloneDeep from 'lodash/cloneDeep'
|
|
43
|
+
import pick from 'lodash/pick'
|
|
44
|
+
import pickBy from 'lodash/pickBy'
|
|
43
45
|
import EditorContext from '@cdc/core/contexts/EditorContext'
|
|
44
46
|
import { APIFilterDropdowns } from './components/DashboardFilters'
|
|
45
47
|
import { ViewPort } from '@cdc/core/types/ViewPort'
|
|
@@ -47,7 +49,7 @@ import VisualizationRow from './components/VisualizationRow'
|
|
|
47
49
|
import { getVizConfig } from './helpers/getVizConfig'
|
|
48
50
|
import { getFilteredData } from './helpers/getFilteredData'
|
|
49
51
|
import { getVizRowColumnLocator } from './helpers/getVizRowColumnLocator'
|
|
50
|
-
import
|
|
52
|
+
import { Responsive, VisualizationContainer } from '@cdc/core/components/Layout'
|
|
51
53
|
import * as reloadURLHelpers from './helpers/reloadURLHelpers'
|
|
52
54
|
import { addValuesToDashboardFilters } from './helpers/addValuesToDashboardFilters'
|
|
53
55
|
import { DashboardFilters } from './types/DashboardFilters'
|
|
@@ -207,9 +209,9 @@ export default function CdcDashboard({
|
|
|
207
209
|
|
|
208
210
|
setAPILoading(true)
|
|
209
211
|
await fetchRemoteData(dataUrlFinal)
|
|
210
|
-
.then(
|
|
211
|
-
let data: any[] =
|
|
212
|
-
if (
|
|
212
|
+
.then(({ data: fetchedData, dataMetadata }) => {
|
|
213
|
+
let data: any[] = fetchedData
|
|
214
|
+
if (data && dataset.dataDescription) {
|
|
213
215
|
try {
|
|
214
216
|
data = transform.autoStandardize(data)
|
|
215
217
|
data = transform.developerStandardize(data, dataset.dataDescription)
|
|
@@ -219,6 +221,7 @@ export default function CdcDashboard({
|
|
|
219
221
|
}
|
|
220
222
|
}
|
|
221
223
|
newDatasets[datasetKey].data = data
|
|
224
|
+
newDatasets[datasetKey].dataMetadata = dataMetadata
|
|
222
225
|
newDatasets[datasetKey].runtimeDataUrl = dataUrlFinal
|
|
223
226
|
newData[datasetKey] = data
|
|
224
227
|
})
|
|
@@ -236,7 +239,7 @@ export default function CdcDashboard({
|
|
|
236
239
|
}
|
|
237
240
|
}
|
|
238
241
|
|
|
239
|
-
const datasetsWithFiles =
|
|
242
|
+
const datasetsWithFiles = pickBy(newDatasets, dataset => !dataset.dataUrl)
|
|
240
243
|
|
|
241
244
|
if (dataWasFetched || Object.keys(datasetsWithFiles).length) {
|
|
242
245
|
const dataFiles = Object.keys(datasetsWithFiles).reduce((acc, key) => {
|
|
@@ -291,7 +294,7 @@ export default function CdcDashboard({
|
|
|
291
294
|
}
|
|
292
295
|
|
|
293
296
|
const setSharedFilter = (key, datum) => {
|
|
294
|
-
const { config: newConfig, filteredData } =
|
|
297
|
+
const { config: newConfig, filteredData } = cloneDeep(state)
|
|
295
298
|
|
|
296
299
|
for (let i = 0; i < newConfig.dashboard.sharedFilters.length; i++) {
|
|
297
300
|
const filter = newConfig.dashboard.sharedFilters[i]
|
|
@@ -319,7 +322,7 @@ export default function CdcDashboard({
|
|
|
319
322
|
return acc
|
|
320
323
|
}, {})
|
|
321
324
|
const newConfig = { ...state, data: { ...data, ...newDatasets } }
|
|
322
|
-
const newFilteredData = getFilteredData(newConfig,
|
|
325
|
+
const newFilteredData = getFilteredData(newConfig, cloneDeep(filteredData))
|
|
323
326
|
dispatch({ type: 'SET_FILTERED_DATA', payload: newFilteredData })
|
|
324
327
|
dispatch({ type: 'SET_DATA', payload: { ...data, ...newDatasets } })
|
|
325
328
|
} catch (e) {
|
|
@@ -375,14 +378,14 @@ export default function CdcDashboard({
|
|
|
375
378
|
|
|
376
379
|
const updateChildConfig = (visualizationKey, newConfig) => {
|
|
377
380
|
const config = cloneConfig(state.config)
|
|
378
|
-
const updatedConfig =
|
|
381
|
+
const updatedConfig = pick(config, ['visualizations', 'multiDashboards'])
|
|
379
382
|
updatedConfig.visualizations[visualizationKey] = newConfig
|
|
380
383
|
updatedConfig.visualizations[visualizationKey].formattedData = config.visualizations[visualizationKey].formattedData
|
|
381
384
|
if (config.multiDashboards) {
|
|
382
385
|
const activeDashboard = config.activeDashboard
|
|
383
386
|
const multiDashboards = [...config.multiDashboards]
|
|
384
387
|
const label = multiDashboards[activeDashboard].label
|
|
385
|
-
const toSave = { label, visualizations: updatedConfig.visualizations, ...
|
|
388
|
+
const toSave = { label, visualizations: updatedConfig.visualizations, ...pick(config, ['dashboard', 'rows']) }
|
|
386
389
|
multiDashboards[activeDashboard] = toSave
|
|
387
390
|
updatedConfig.multiDashboards = multiDashboards
|
|
388
391
|
}
|
|
@@ -394,17 +397,31 @@ export default function CdcDashboard({
|
|
|
394
397
|
}
|
|
395
398
|
}
|
|
396
399
|
|
|
397
|
-
const
|
|
398
|
-
for (let entry of entries) {
|
|
399
|
-
let newViewport = getViewport(entry.contentRect.width)
|
|
400
|
+
const resizeObserverRef = useRef<ResizeObserver | null>(null)
|
|
400
401
|
|
|
401
|
-
|
|
402
|
+
const outerContainerRef = useCallback(node => {
|
|
403
|
+
if (resizeObserverRef.current) {
|
|
404
|
+
resizeObserverRef.current.disconnect()
|
|
405
|
+
resizeObserverRef.current = null
|
|
402
406
|
}
|
|
403
|
-
})
|
|
404
407
|
|
|
405
|
-
const outerContainerRef = useCallback(node => {
|
|
406
408
|
if (node !== null) {
|
|
407
|
-
|
|
409
|
+
resizeObserverRef.current = new ResizeObserver(entries => {
|
|
410
|
+
for (let entry of entries) {
|
|
411
|
+
const newViewport = getViewport(entry.contentRect.width)
|
|
412
|
+
setCurrentViewport(newViewport)
|
|
413
|
+
}
|
|
414
|
+
})
|
|
415
|
+
resizeObserverRef.current.observe(node)
|
|
416
|
+
}
|
|
417
|
+
}, [])
|
|
418
|
+
|
|
419
|
+
useEffect(() => {
|
|
420
|
+
return () => {
|
|
421
|
+
if (resizeObserverRef.current) {
|
|
422
|
+
resizeObserverRef.current.disconnect()
|
|
423
|
+
resizeObserverRef.current = null
|
|
424
|
+
}
|
|
408
425
|
}
|
|
409
426
|
}, [])
|
|
410
427
|
|
|
@@ -497,7 +514,7 @@ export default function CdcDashboard({
|
|
|
497
514
|
autoDismiss={true}
|
|
498
515
|
/>
|
|
499
516
|
))}
|
|
500
|
-
<
|
|
517
|
+
<Responsive isEditor={isEditor}>
|
|
501
518
|
<div className={`cdc-dashboard-inner-container${isEditor ? ' is-editor' : ''}`}>
|
|
502
519
|
<Title
|
|
503
520
|
title={title}
|
|
@@ -506,7 +523,7 @@ export default function CdcDashboard({
|
|
|
506
523
|
classes={[`dashboard-title`, `${config.dashboard.theme ?? 'theme-blue'}`]}
|
|
507
524
|
/>
|
|
508
525
|
{/* Description */}
|
|
509
|
-
{description && <div className='subtext mb-4'>{parse(description)}</div>}
|
|
526
|
+
{description && <div className='subtext cove-prose mb-4'>{parse(description)}</div>}
|
|
510
527
|
{/* Visualizations */}
|
|
511
528
|
{filteredRows?.map((row, index) => (
|
|
512
529
|
<VisualizationRow
|
|
@@ -640,16 +657,11 @@ export default function CdcDashboard({
|
|
|
640
657
|
})
|
|
641
658
|
.filter(Boolean)}
|
|
642
659
|
</div>
|
|
643
|
-
</
|
|
660
|
+
</Responsive>
|
|
644
661
|
</>
|
|
645
662
|
)
|
|
646
663
|
}
|
|
647
664
|
|
|
648
|
-
const dashboardContainerClasses = ['cdc-open-viz-module', 'type-dashboard', `${currentViewport}`]
|
|
649
|
-
if (isEditor) {
|
|
650
|
-
dashboardContainerClasses.push('isDashboardEditor')
|
|
651
|
-
}
|
|
652
|
-
|
|
653
665
|
return (
|
|
654
666
|
<GlobalContextProvider>
|
|
655
667
|
<DashboardContext.Provider
|
|
@@ -666,9 +678,17 @@ export default function CdcDashboard({
|
|
|
666
678
|
}}
|
|
667
679
|
>
|
|
668
680
|
<DashboardDispatchContext.Provider value={dispatch}>
|
|
669
|
-
<
|
|
681
|
+
<VisualizationContainer
|
|
682
|
+
className={isEditor ? 'is-dashboard-editor' : undefined}
|
|
683
|
+
config={state.config}
|
|
684
|
+
currentViewport={currentViewport}
|
|
685
|
+
imageId={imageId}
|
|
686
|
+
isEditor={false}
|
|
687
|
+
ref={outerContainerRef}
|
|
688
|
+
renderResponsive={false}
|
|
689
|
+
>
|
|
670
690
|
{body}
|
|
671
|
-
</
|
|
691
|
+
</VisualizationContainer>
|
|
672
692
|
<OverlayFrame />
|
|
673
693
|
</DashboardDispatchContext.Provider>
|
|
674
694
|
</DashboardContext.Provider>
|
|
@@ -159,7 +159,12 @@ export const MultiVizConfigurationWorkflow: Story = {
|
|
|
159
159
|
// ========================================================================
|
|
160
160
|
// STEP 11: Click "Vertical Values for map" button
|
|
161
161
|
// ========================================================================
|
|
162
|
-
await
|
|
162
|
+
await waitFor(
|
|
163
|
+
() => {
|
|
164
|
+
expect(canvas.getByRole('button', { name: /vertical values for map/i })).toBeTruthy()
|
|
165
|
+
},
|
|
166
|
+
{ timeout: 5000 }
|
|
167
|
+
)
|
|
163
168
|
|
|
164
169
|
const verticalValuesButton = canvas.getByRole('button', { name: /vertical values for map/i })
|
|
165
170
|
await user.click(verticalValuesButton)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
3
|
+
import Dashboard from '../CdcDashboard'
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Dashboard> = {
|
|
6
|
+
title: 'Pages/NWSS',
|
|
7
|
+
component: Dashboard
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default meta
|
|
11
|
+
type Story = StoryObj<typeof Dashboard>
|
|
12
|
+
|
|
13
|
+
export const FluA_Top_Modules: Story = {
|
|
14
|
+
name: 'FluA Top Modules',
|
|
15
|
+
args: {
|
|
16
|
+
configUrl: 'https://www.cdc.gov/nwss/rv/modules/flua/flua-top-modules.json',
|
|
17
|
+
isEditor: false
|
|
18
|
+
},
|
|
19
|
+
play: async ({ canvasElement }) => {
|
|
20
|
+
await assertVisualizationRendered(canvasElement)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
+
import { expect } from 'storybook/test'
|
|
3
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
4
|
+
import Dashboard from '../CdcDashboard'
|
|
5
|
+
import MinimalExampleConfig from '../../examples/minimal-example.json'
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof Dashboard> = {
|
|
8
|
+
title: 'Components/Pages/Dashboard',
|
|
9
|
+
component: Dashboard
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default meta
|
|
13
|
+
type Story = StoryObj<typeof Dashboard>
|
|
14
|
+
|
|
15
|
+
export const Dashboard_Minimal_Config: Story = {
|
|
16
|
+
args: {
|
|
17
|
+
config: MinimalExampleConfig,
|
|
18
|
+
isEditor: false
|
|
19
|
+
},
|
|
20
|
+
parameters: {
|
|
21
|
+
docs: {
|
|
22
|
+
description: {
|
|
23
|
+
story:
|
|
24
|
+
'Minimum working consumer config. This story validates the source-of-truth minimal example used by the package README and CONFIG reference.'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
play: async ({ canvasElement }) => {
|
|
29
|
+
await assertVisualizationRendered(canvasElement)
|
|
30
|
+
expect(canvasElement.textContent).toContain('Dashboard Example')
|
|
31
|
+
expect(canvasElement.textContent).toContain('Minimal dashboard example')
|
|
32
|
+
}
|
|
33
|
+
}
|