@cdc/dashboard 4.26.2 → 4.26.3
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-vr9HZwRt.es.js +6 -0
- package/dist/cdcdashboard.js +53345 -49681
- package/examples/custom/css/respiratory.css +1 -1
- package/examples/data/data-with-metadata.json +18 -0
- package/examples/default.json +7 -36
- package/examples/private/inline-markup.json +775 -0
- package/examples/private/recent-update.json +1456 -0
- package/examples/private/toggle.json +10137 -0
- package/package.json +9 -9
- package/src/CdcDashboard.tsx +2 -1
- package/src/CdcDashboardComponent.tsx +47 -27
- package/src/_stories/Dashboard.DataSetup.stories.tsx +6 -1
- package/src/_stories/Dashboard.Pages.stories.tsx +22 -0
- package/src/_stories/Dashboard.stories.tsx +4406 -7
- package/src/_stories/_mock/tab-simple-filter.json +153 -0
- package/src/components/DashboardFilters/DashboardFilters.tsx +19 -3
- package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +7 -4
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/APIModal.tsx +1 -1
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +1 -2
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +8 -7
- 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/Header/Header.tsx +27 -5
- package/src/components/Header/index.scss +1 -1
- package/src/components/MultiConfigTabs/multiconfigtabs.styles.css +6 -6
- package/src/components/Row.tsx +21 -0
- package/src/components/Toggle/toggle-style.css +7 -7
- package/src/components/VisualizationRow.tsx +12 -4
- package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +1 -54
- package/src/components/VisualizationsPanel/visualizations-panel-styles.css +2 -2
- package/src/components/Widget/Widget.tsx +2 -2
- package/src/components/Widget/widget.styles.css +12 -12
- package/src/data/initial-state.js +1 -1
- package/src/helpers/addVisualization.ts +71 -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/main.scss +164 -39
- package/src/store/dashboard.reducer.ts +1 -1
- package/src/test/CdcDashboard.test.jsx +2 -2
- package/src/test/CdcDashboardComponent.test.tsx +74 -0
- package/src/types/FilterStyles.ts +2 -1
- 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/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/dashboard",
|
|
3
|
-
"version": "4.26.
|
|
3
|
+
"version": "4.26.3",
|
|
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.3",
|
|
10
|
+
"@cdc/core": "^4.26.3",
|
|
11
|
+
"@cdc/data-bite": "^4.26.3",
|
|
12
|
+
"@cdc/filtered-text": "^4.26.3",
|
|
13
|
+
"@cdc/map": "^4.26.3",
|
|
14
|
+
"@cdc/markup-include": "^4.26.3",
|
|
15
|
+
"@cdc/waffle-chart": "^4.26.3",
|
|
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": "d50e45a074fbefa56cac904917e707d57f237737",
|
|
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}
|
|
@@ -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
|
+
}
|