@cdc/dashboard 4.24.12 → 4.25.2-25

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 (60) hide show
  1. package/dist/cdcdashboard.js +74365 -72646
  2. package/examples/all-components.json +529 -4607
  3. package/examples/dashboard-gallery.json +397 -397
  4. package/examples/private/DEV-10120.json +1294 -0
  5. package/examples/private/DEV-10527.json +564 -0
  6. package/examples/private/DEV-10586.json +54319 -0
  7. package/examples/private/DEV-10856.json +54319 -0
  8. package/examples/private/DEV-9989.json +229 -0
  9. package/examples/private/art-dashboard.json +2 -2
  10. package/examples/private/bird-flu-2.json +440 -0
  11. package/examples/private/bird-flu.json +413 -0
  12. package/examples/private/dashboard-config-ehdi.json +29915 -0
  13. package/examples/private/dashboard-map-filter.json +815 -0
  14. package/examples/private/dashboard-margins.js +15 -0
  15. package/examples/private/dataset.json +1452 -0
  16. package/examples/private/dev-10856-2.json +1348 -0
  17. package/examples/private/ehdi-data.json +29502 -0
  18. package/examples/private/exposure-source-h5-data.csv +26 -0
  19. package/examples/private/feelings.json +1 -0
  20. package/examples/private/nhis.json +1792 -0
  21. package/examples/private/workforce.json +2041 -0
  22. package/index.html +5 -8
  23. package/package.json +9 -9
  24. package/src/CdcDashboard.tsx +5 -8
  25. package/src/CdcDashboardComponent.tsx +70 -60
  26. package/src/_stories/Dashboard.stories.tsx +63 -0
  27. package/src/_stories/_mock/dashboard-filter-asc.json +551 -0
  28. package/src/_stories/_mock/data-bite-dash-test.json +1 -0
  29. package/src/_stories/_mock/data-bite-dash-test_1.json +1 -0
  30. package/src/_stories/_mock/data-bite-dash-test_1_1.json +1 -0
  31. package/src/_stories/_mock/data-bite-dash-test_1_1_1.json +1 -0
  32. package/src/components/CollapsibleVisualizationRow.tsx +3 -3
  33. package/src/components/Column.tsx +12 -1
  34. package/src/components/DashboardFilters/DashboardFilters.tsx +14 -9
  35. package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +23 -8
  36. package/src/components/DashboardFilters/DashboardFiltersEditor/components/DeleteFilterModal.tsx +13 -3
  37. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +130 -41
  38. package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +10 -7
  39. package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +11 -12
  40. package/src/components/DashboardFilters/dashboardfilter.styles.css +2 -2
  41. package/src/components/ExpandCollapseButtons.tsx +1 -1
  42. package/src/components/Header/Header.tsx +1 -2
  43. package/src/components/MultiConfigTabs/MultiConfigTabs.tsx +2 -2
  44. package/src/components/MultiConfigTabs/MultiTabs.tsx +1 -1
  45. package/src/components/VisualizationRow.tsx +13 -3
  46. package/src/components/Widget.tsx +9 -3
  47. package/src/helpers/addValuesToDashboardFilters.ts +6 -5
  48. package/src/helpers/apiFilterHelpers.ts +11 -6
  49. package/src/helpers/changeFilterActive.ts +17 -4
  50. package/src/helpers/getFilteredData.ts +13 -4
  51. package/src/helpers/getUpdateConfig.ts +11 -4
  52. package/src/helpers/loadAPIFilters.ts +6 -4
  53. package/src/helpers/tests/updatesChildFilters.test.ts +56 -0
  54. package/src/helpers/updateChildFilters.ts +50 -0
  55. package/src/index.tsx +1 -0
  56. package/src/scss/main.scss +1 -15
  57. package/src/store/dashboard.actions.ts +2 -2
  58. package/src/store/dashboard.reducer.ts +60 -29
  59. package/src/types/DashboardConfig.ts +2 -0
  60. package/src/types/SharedFilter.ts +1 -1
package/index.html CHANGED
@@ -17,24 +17,21 @@
17
17
  }
18
18
  </style>
19
19
  <link rel="stylesheet prefetch" href="examples/custom/css/respiratory.css" />
20
- <link
21
- rel="stylesheet prefetch"
22
- href="https://www.cdc.gov/TemplatePackage/contrib/libs/bootstrap/latest/css/bootstrap.min.css?_=39423"
23
- />
24
- <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/4.0/assets/css/app.min.css?_=39423" />
20
+ <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/5.0/css/app.min.css?_=71669" />
25
21
  </head>
26
22
 
27
23
  <body>
28
- <!-- <div class="react-container" data-config="/examples/chart-data-2.json"></div> -->
24
+ <div class="react-container" data-config="/examples/private/nhis.json"></div>
25
+ <!-- <div class="react-container" data-config="/examples/private/bird-flu.json"></div> -->
29
26
  <!-- <div class="react-container" data-config="/examples/bump-chart.json"></div> -->
30
27
  <!-- <div class="react-container" data-config="/examples/full-dashboard.json"></div> -->
31
- <!-- <div class="react-container" data-config="/examples/dashboard-gallery.json"></div> -->
28
+ <div class="react-container" data-config="/examples/dashboard-gallery.json"></div>
32
29
  <!-- <div class="react-container" data-config="/examples/dev-8332.json"></div> -->
33
30
  <!-- <div class="react-container" data-config="/examples/default-multi-dataset.json"></div> -->
34
31
  <!-- <div class="react-container" data-config="/examples/dev-8332.json"></div> -->
35
32
  <!-- <div class="react-container" data-config="/examples/dashboard-gallery.json"></div> -->
36
33
  <!-- <div class="react-container" data-config="/examples/filtered-dash.json"></div> -->
37
- <div class="react-container" data-config="/examples/all-components.json"></div>
34
+ <!-- <div class="react-container" data-config="/examples/private/art-dashboard.json"></div> -->
38
35
  <!-- <div class="react-container" data-config="/examples/sankey.json"></div> -->
39
36
  <!-- <div class="react-container" data-config="/examples/DEV-6574.json"></div> -->
40
37
  <!-- <div class="react-container" data-config="/examples/default-multi-dataset-2.json"></div> -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/dashboard",
3
- "version": "4.24.12",
3
+ "version": "4.25.2-25",
4
4
  "description": "React component for combining multiple visualizations into a single dashboard",
5
5
  "moduleName": "CdcDashboard",
6
6
  "main": "dist/cdcdashboard",
@@ -27,13 +27,13 @@
27
27
  },
28
28
  "license": "Apache-2.0",
29
29
  "dependencies": {
30
- "@cdc/chart": "^4.24.12",
31
- "@cdc/core": "^4.24.12",
32
- "@cdc/data-bite": "^4.24.12",
33
- "@cdc/filtered-text": "^4.24.12",
34
- "@cdc/map": "^4.24.12",
35
- "@cdc/markup-include": "^4.24.12",
36
- "@cdc/waffle-chart": "^4.24.12",
30
+ "@cdc/chart": "^4.25.2-25",
31
+ "@cdc/core": "^4.25.2-25",
32
+ "@cdc/data-bite": "^4.25.2-25",
33
+ "@cdc/filtered-text": "^4.25.2-25",
34
+ "@cdc/map": "^4.25.2-25",
35
+ "@cdc/markup-include": "^4.25.2-25",
36
+ "@cdc/waffle-chart": "^4.25.2-25",
37
37
  "html-react-parser": "^3.0.8",
38
38
  "js-base64": "^2.5.2",
39
39
  "papaparse": "^5.3.0",
@@ -49,5 +49,5 @@
49
49
  "react": "^18.2.0",
50
50
  "react-dom": "^18.2.0"
51
51
  },
52
- "gitHead": "347414f1da4b0e9bf2f22a7b59335deccf0b2d9c"
52
+ "gitHead": "f00bd8a0fc746def7cc23b91ef49a03a3ceac65e"
53
53
  }
@@ -1,4 +1,4 @@
1
- import { useEffect, useState } from 'react'
1
+ import { useContext, useEffect, useState } from 'react'
2
2
  import CdcDashboard from './CdcDashboardComponent'
3
3
  import { MultiDashboardConfig } from './types/MultiDashboard'
4
4
  import Loading from '@cdc/core/components/Loading'
@@ -13,19 +13,16 @@ import { DashboardConfig } from './types/DashboardConfig'
13
13
  import { coveUpdateWorker } from '@cdc/core/helpers/coveUpdateWorker'
14
14
  import _ from 'lodash'
15
15
  import { getQueryParams } from '@cdc/core/helpers/queryStringUtils'
16
+ import EditorContext from '../../editor/src/ConfigContext'
16
17
 
17
18
  type MultiDashboardProps = Omit<WCMSProps, 'configUrl'> & {
18
19
  configUrl?: string
19
20
  config?: MultiDashboardConfig
20
21
  }
21
22
 
22
- const MultiDashboardWrapper: React.FC<MultiDashboardProps> = ({
23
- configUrl,
24
- config: editorConfig,
25
- isEditor,
26
- isDebug
27
- }) => {
23
+ const MultiDashboardWrapper: React.FC<MultiDashboardProps> = ({ configUrl, isEditor, isDebug, config }) => {
28
24
  const [initial, setInitial] = useState<InitialState>(undefined)
25
+ const editorContext = useContext(EditorContext)
29
26
 
30
27
  const getSelectedConfig = (config: MultiDashboardConfig): number | null => {
31
28
  if (!config.multiDashboards) return null
@@ -48,7 +45,7 @@ const MultiDashboardWrapper: React.FC<MultiDashboardProps> = ({
48
45
  }
49
46
 
50
47
  const loadConfig = async () => {
51
- const _config: MultiDashboardConfig = editorConfig || (await (await fetch(configUrl)).json())
48
+ const _config: MultiDashboardConfig = config || editorContext.config || (await (await fetch(configUrl)).json())
52
49
  const selected = getSelectedConfig(_config)
53
50
 
54
51
  const { newConfig, datasets } =
@@ -19,7 +19,7 @@ import Loading from '@cdc/core/components/Loading'
19
19
  import { DataTransform } from '@cdc/core/helpers/DataTransform'
20
20
  import getViewport from '@cdc/core/helpers/getViewport'
21
21
 
22
- import CdcChart from '@cdc/chart/src/CdcChart'
22
+ import CdcChart from '@cdc/chart/src/CdcChartComponent'
23
23
  import CdcDataBite from '@cdc/data-bite/src/CdcDataBite'
24
24
  import CdcMap from '@cdc/map/src/CdcMap'
25
25
  import CdcWaffleChart from '@cdc/waffle-chart/src/CdcWaffleChart'
@@ -228,7 +228,15 @@ export default function CdcDashboard({ initialState, isEditor = false, isDebug =
228
228
  )
229
229
  dispatch({ type: 'SET_FILTERED_DATA', payload: filteredData })
230
230
  const visualizations = reloadURLHelpers.getVisualizationsWithFormattedData(config.visualizations, newData)
231
- dispatch({ type: 'SET_CONFIG', payload: { dashboard: dashboardConfig, datasets: newDatasets, visualizations } })
231
+ dispatch({
232
+ type: 'SET_CONFIG',
233
+ payload: {
234
+ dashboard: dashboardConfig,
235
+ datasets: newDatasets,
236
+ visualizations,
237
+ activeDashboard: config.activeDashboard
238
+ }
239
+ })
232
240
  setAPILoading(false)
233
241
  }
234
242
  }
@@ -268,7 +276,7 @@ export default function CdcDashboard({ initialState, isEditor = false, isDebug =
268
276
  const loadAllFilters = shouldLoadAllFilters(config, isEditor && !isPreview)
269
277
  const sharedFiltersWithValues = addValuesToDashboardFilters(config.dashboard.sharedFilters, state.data)
270
278
 
271
- loadAPIFilters(sharedFiltersWithValues, apiFilterDropdowns, loadAllFilters).then(newFilters => {
279
+ loadAPIFilters(sharedFiltersWithValues, apiFilterDropdowns, loadAllFilters)?.then(newFilters => {
272
280
  const allValuesSelected = newFilters.every(filter => {
273
281
  return filter.type === 'datafilter' || filter.active
274
282
  })
@@ -513,6 +521,8 @@ export default function CdcDashboard({ initialState, isEditor = false, isDebug =
513
521
  const { config } = state
514
522
  const { title, description } = config.dashboard || {}
515
523
 
524
+ const filteredRows = config.rows && config.rows.filter(row => row.columns.filter(col => col.widget).length !== 0)
525
+
516
526
  body = (
517
527
  <>
518
528
  {isEditor && <Header />}
@@ -534,64 +544,64 @@ export default function CdcDashboard({ initialState, isEditor = false, isDebug =
534
544
  classes={[`dashboard-title`, `${config.dashboard.theme ?? 'theme-blue'}`]}
535
545
  />
536
546
  {/* Description */}
537
- {description && <div className='subtext'>{parse(description)}</div>}
547
+ {description && <div className='subtext mb-3'>{parse(description)}</div>}
538
548
  {/* Visualizations */}
539
- {config.rows &&
540
- config.rows
541
- .filter(row => row.columns.filter(col => col.widget).length !== 0)
542
- .map((row, index) => {
543
- if (row.multiVizColumn && (isPreview || !isEditor)) {
544
- const filteredData = getFilteredData(state, _.cloneDeep(state.data))
545
- const data = filteredData[index] ?? row.formattedData
546
- const dataGroups = {}
547
- data.forEach(d => {
548
- const groupKey = d[row.multiVizColumn]
549
- if (!dataGroups[groupKey]) dataGroups[groupKey] = []
550
- dataGroups[groupKey].push(d)
551
- })
552
- return (
553
- <>
554
- {/* Expand/Collapse All */}
555
- {!inNoDataState && row.expandCollapseAllButtons === true && (
556
- <ExpandCollapseButtons setAllExpanded={setAllExpanded} />
557
- )}
558
- {Object.keys(dataGroups).map(groupName => {
559
- const dataValue = dataGroups[groupName]
560
- return (
561
- <VisualizationRow
562
- key={`row__${index}__${groupName}`}
563
- allExpanded={allExpanded}
564
- filteredDataOverride={dataValue}
565
- groupName={groupName}
566
- row={row}
567
- rowIndex={index}
568
- setSharedFilter={setSharedFilter}
569
- updateChildConfig={updateChildConfig}
570
- apiFilterDropdowns={apiFilterDropdowns}
571
- currentViewport={currentViewport}
572
- inNoDataState={inNoDataState}
573
- />
574
- )
575
- })}
576
- </>
577
- )
578
- } else {
579
- return (
580
- <VisualizationRow
581
- key={`row__${index}`}
582
- allExpanded={false}
583
- groupName={''}
584
- row={row}
585
- rowIndex={index}
586
- setSharedFilter={setSharedFilter}
587
- updateChildConfig={updateChildConfig}
588
- apiFilterDropdowns={apiFilterDropdowns}
589
- currentViewport={currentViewport}
590
- inNoDataState={inNoDataState}
591
- />
592
- )
593
- }
594
- })}
549
+ {filteredRows &&
550
+ filteredRows.map((row, index) => {
551
+ if (row.multiVizColumn && (isPreview || !isEditor)) {
552
+ const filteredData = getFilteredData(state, _.cloneDeep(state.data))
553
+ const data = filteredData[index] ?? row.formattedData
554
+ const dataGroups = {}
555
+ data.forEach(d => {
556
+ const groupKey = d[row.multiVizColumn]
557
+ if (!dataGroups[groupKey]) dataGroups[groupKey] = []
558
+ dataGroups[groupKey].push(d)
559
+ })
560
+ return (
561
+ <>
562
+ {/* Expand/Collapse All */}
563
+ {!inNoDataState && row.expandCollapseAllButtons === true && (
564
+ <ExpandCollapseButtons setAllExpanded={setAllExpanded} />
565
+ )}
566
+ {Object.keys(dataGroups).map(groupName => {
567
+ const dataValue = dataGroups[groupName]
568
+ return (
569
+ <VisualizationRow
570
+ key={`row__${index}__${groupName}`}
571
+ allExpanded={allExpanded}
572
+ filteredDataOverride={dataValue}
573
+ groupName={groupName}
574
+ row={row}
575
+ rowIndex={index}
576
+ setSharedFilter={setSharedFilter}
577
+ updateChildConfig={updateChildConfig}
578
+ apiFilterDropdowns={apiFilterDropdowns}
579
+ currentViewport={currentViewport}
580
+ inNoDataState={inNoDataState}
581
+ isLastRow={index === filteredRows.length - 1}
582
+ />
583
+ )
584
+ })}
585
+ </>
586
+ )
587
+ } else {
588
+ return (
589
+ <VisualizationRow
590
+ key={`row__${index}`}
591
+ allExpanded={false}
592
+ groupName={''}
593
+ row={row}
594
+ rowIndex={index}
595
+ setSharedFilter={setSharedFilter}
596
+ updateChildConfig={updateChildConfig}
597
+ apiFilterDropdowns={apiFilterDropdowns}
598
+ currentViewport={currentViewport}
599
+ inNoDataState={inNoDataState}
600
+ isLastRow={index === filteredRows.length - 1}
601
+ />
602
+ )
603
+ }
604
+ })}
595
605
 
596
606
  {inNoDataState ? <div className='mt-5'>Please complete your selection to continue.</div> : <></>}
597
607
 
@@ -24,6 +24,20 @@ import { ConfigRow } from '../types/ConfigRow'
24
24
  import BumpChartConfig from './_mock/bump-chart.json'
25
25
  import MethodologyConfig from './_mock/methodology.json'
26
26
  import methodologyAPI from './_mock/methodologyAPI'
27
+ import TopSpacing_1 from './_mock/data-bite-dash-test.json'
28
+ import TopSpacing_2 from './_mock/data-bite-dash-test_1.json'
29
+ import TopSpacing_3 from './_mock/data-bite-dash-test_1_1.json'
30
+ import TopSpacing_4 from './_mock/data-bite-dash-test_1_1_1.json'
31
+
32
+ // Dashboard Filter Updates for Ascending, Descending, and Custom Order
33
+ import DashboardFilterAsc from './_mock/dashboard-filter-asc.json'
34
+ const DashboardFilterDesc = _.cloneDeep(DashboardFilterAsc)
35
+ const DashboardFilterCust = _.cloneDeep(DashboardFilterAsc)
36
+ DashboardFilterDesc.dashboard.sharedFilters[0].order = 'desc'
37
+ DashboardFilterCust.dashboard.sharedFilters[0].order = 'cust'
38
+
39
+ // On DashboardFilterCust change the sharedFilters[0].values and orderedValues to be in a custom order
40
+ const customOrder = ['American Samoa', 'Alaska', 'Alabama', 'Arizona', 'Arkansas']
27
41
 
28
42
  const meta: Meta<typeof Dashboard> = {
29
43
  title: 'Components/Pages/Dashboard',
@@ -32,6 +46,27 @@ const meta: Meta<typeof Dashboard> = {
32
46
 
33
47
  type Story = StoryObj<typeof Dashboard>
34
48
 
49
+ export const Dashboard_Filter_Asc: Story = {
50
+ args: {
51
+ config: DashboardFilterAsc,
52
+ isEditor: false
53
+ }
54
+ }
55
+
56
+ export const Dashboard_Filter_Desc: Story = {
57
+ args: {
58
+ config: DashboardFilterDesc,
59
+ isEditor: false
60
+ }
61
+ }
62
+
63
+ export const Dashboard_Filter_Cust: Story = {
64
+ args: {
65
+ config: DashboardFilterCust,
66
+ isEditor: false
67
+ }
68
+ }
69
+
35
70
  export const Example_1: Story = {
36
71
  args: {
37
72
  config: ExampleConfig_1,
@@ -403,4 +438,32 @@ export const RegressionMultiVisualization: Story = {
403
438
  }
404
439
  }
405
440
 
441
+ export const Top_Spacing_1: Story = {
442
+ args: {
443
+ config: TopSpacing_1,
444
+ isEditor: false
445
+ }
446
+ }
447
+
448
+ export const Top_Spacing_2: Story = {
449
+ args: {
450
+ config: TopSpacing_2,
451
+ isEditor: false
452
+ }
453
+ }
454
+
455
+ export const Top_Spacing_3: Story = {
456
+ args: {
457
+ config: TopSpacing_3,
458
+ isEditor: false
459
+ }
460
+ }
461
+
462
+ export const Top_Spacing_4: Story = {
463
+ args: {
464
+ config: TopSpacing_4,
465
+ isEditor: false
466
+ }
467
+ }
468
+
406
469
  export default meta