@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
@@ -1,14 +1,19 @@
1
- import fetchRemoteData from '@cdc/core/helpers/fetchRemoteData'
2
- import { getFormattedData } from './getFormattedData'
3
-
4
- export const processDataLegacy = async (response: any) => {
5
- let dataset = response.formattedData || response.data
6
-
7
- if (response.dataUrl) {
8
- dataset = await fetchRemoteData(`${response.dataUrl}`)
9
-
10
- dataset = getFormattedData(dataset, response.dataDescription)
11
- }
12
-
13
- return dataset
14
- }
1
+ import fetchRemoteData from '@cdc/core/helpers/fetchRemoteData'
2
+ import { getFormattedData } from './getFormattedData'
3
+
4
+ export const processDataLegacy = async (
5
+ response: any
6
+ ): Promise<{ data: any[]; dataMetadata: Record<string, string> }> => {
7
+ let dataset = response.formattedData || response.data
8
+ let dataMetadata: Record<string, string> = {}
9
+
10
+ if (response.dataUrl) {
11
+ const result = await fetchRemoteData(`${response.dataUrl}`)
12
+ dataset = result.data
13
+ dataMetadata = result.dataMetadata
14
+
15
+ dataset = getFormattedData(dataset, response.dataDescription)
16
+ }
17
+
18
+ return { data: dataset, dataMetadata }
19
+ }
@@ -0,0 +1,52 @@
1
+ import { describe, expect, it, vi } from 'vitest'
2
+ import { addVisualization } from '../addVisualization'
3
+
4
+ describe('addVisualization', () => {
5
+ it('creates chart visual settings with extra theme toggles disabled by default', () => {
6
+ vi.spyOn(Date, 'now').mockReturnValue(12345)
7
+
8
+ const visualization = addVisualization('chart', 'Bar')
9
+
10
+ expect(visualization).toMatchObject({
11
+ uid: 'chart12345',
12
+ type: 'chart',
13
+ visualizationType: 'Bar',
14
+ visual: {
15
+ border: false,
16
+ borderColorTheme: false,
17
+ accent: false,
18
+ background: false,
19
+ hideBackgroundColor: false
20
+ }
21
+ })
22
+ })
23
+
24
+ it('creates map visual settings with extra theme toggles disabled by default', () => {
25
+ vi.spyOn(Date, 'now').mockReturnValue(12345)
26
+
27
+ const visualization = addVisualization('map', 'single-state')
28
+
29
+ expect(visualization).toMatchObject({
30
+ uid: 'map12345',
31
+ type: 'map',
32
+ general: {
33
+ geoType: 'single-state'
34
+ },
35
+ visual: {
36
+ border: false,
37
+ borderColorTheme: false,
38
+ accent: false,
39
+ background: false,
40
+ hideBackgroundColor: false
41
+ }
42
+ })
43
+ })
44
+
45
+ it('preserves visualizationType for data-bite family visualizations', () => {
46
+ vi.spyOn(Date, 'now').mockReturnValue(12345)
47
+
48
+ expect(addVisualization('data-bite')).toMatchObject({ visualizationType: 'data-bite' })
49
+ expect(addVisualization('waffle-chart', 'Waffle')).toMatchObject({ visualizationType: 'Waffle' })
50
+ expect(addVisualization('filtered-text')).toMatchObject({ visualizationType: 'filtered-text' })
51
+ })
52
+ })
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest'
2
- import { cleanSharedFilters } from '../formatConfigBeforeSave'
2
+ import { cleanSharedFilters, stripConfig } from '../formatConfigBeforeSave'
3
3
  import { DashboardConfig } from '../../types/DashboardConfig'
4
4
 
5
5
  describe('cleanSharedFilters', () => {
@@ -67,3 +67,83 @@ describe('cleanSharedFilters', () => {
67
67
  expect(config.dashboard.sharedFilters).toEqual([{ id: 1, type: 'urlfilter' }])
68
68
  })
69
69
  })
70
+
71
+ describe('stripConfig', () => {
72
+ it('removes inline data for non-dashboard URL-backed configs when isEditor is false', () => {
73
+ const config = {
74
+ type: 'bar',
75
+ dataUrl: '/api/data.csv',
76
+ data: [{ value: 10 }],
77
+ runtime: { loaded: true },
78
+ formattedData: [{ value: 10 }]
79
+ }
80
+
81
+ const stripped = stripConfig(config)
82
+
83
+ expect(stripped.data).toBeUndefined()
84
+ expect(stripped.dataUrl).toBe('/api/data.csv')
85
+ expect(stripped.runtime).toBeUndefined()
86
+ expect(stripped.formattedData).toBeUndefined()
87
+ })
88
+
89
+ it('preserves inline data for non-dashboard URL-backed configs when isEditor is true', () => {
90
+ const config = {
91
+ type: 'bar',
92
+ dataUrl: '/api/data.csv',
93
+ data: [{ value: 10 }],
94
+ runtime: { loaded: true },
95
+ formattedData: [{ value: 10 }]
96
+ }
97
+
98
+ const stripped = stripConfig(config, true)
99
+
100
+ expect(stripped.data).toEqual([{ value: 10 }])
101
+ expect(stripped.dataUrl).toBe('/api/data.csv')
102
+ expect(stripped.runtime).toBeUndefined()
103
+ expect(stripped.formattedData).toBeUndefined()
104
+ })
105
+
106
+ it('removes dashboard dataset data when dataset has dataUrl and isEditor is false', () => {
107
+ const config = {
108
+ type: 'dashboard',
109
+ dashboard: { sharedFilters: [] },
110
+ datasets: {
111
+ data_1: {
112
+ dataUrl: '/api/dashboard.csv',
113
+ data: [{ a: 1 }],
114
+ formattedData: [{ a: 1 }]
115
+ }
116
+ },
117
+ visualizations: {},
118
+ rows: []
119
+ } as any
120
+
121
+ const stripped = stripConfig(config)
122
+
123
+ expect(stripped.datasets.data_1.data).toBeUndefined()
124
+ expect(stripped.datasets.data_1.formattedData).toBeUndefined()
125
+ expect(stripped.datasets.data_1.dataUrl).toBe('/api/dashboard.csv')
126
+ })
127
+
128
+ it('preserves dashboard dataset data when dataset has dataUrl and isEditor is true', () => {
129
+ const config = {
130
+ type: 'dashboard',
131
+ dashboard: { sharedFilters: [] },
132
+ datasets: {
133
+ data_1: {
134
+ dataUrl: '/api/dashboard.csv',
135
+ data: [{ a: 1 }],
136
+ formattedData: [{ a: 1 }]
137
+ }
138
+ },
139
+ visualizations: {},
140
+ rows: []
141
+ } as any
142
+
143
+ const stripped = stripConfig(config, true)
144
+
145
+ expect(stripped.datasets.data_1.data).toEqual([{ a: 1 }])
146
+ expect(stripped.datasets.data_1.formattedData).toBeUndefined()
147
+ expect(stripped.datasets.data_1.dataUrl).toBe('/api/dashboard.csv')
148
+ })
149
+ })
@@ -4,7 +4,7 @@
4
4
  // Shift down for top level Dashboard bar when in edit mode
5
5
  .layout-container,
6
6
  .editor-panel + .cdc-dashboard-inner-container,
7
- .editor-heading + .cdc-open-viz-module {
7
+ .editor-heading + .cove-visualization {
8
8
  position: relative;
9
9
  min-height: 80vh;
10
10
  }
@@ -102,17 +102,29 @@ $red: #f74242;
102
102
  }
103
103
 
104
104
  .row-menu__btn {
105
+ align-items: center;
105
106
  background-color: #c2c2c2;
106
107
  border-radius: 0.2em 0.2em 0 0;
108
+ justify-content: center;
109
+ min-height: 0;
107
110
  outline: none;
108
111
  transition: background-color 300ms cubic-bezier(0.16, 1, 0.3, 1);
109
112
  padding: 0.2em 0.3em;
110
113
  display: flex;
111
114
  fill: #fff;
115
+ box-shadow: none;
116
+ transform: none;
117
+ line-height: 1;
112
118
 
113
119
  + .row-menu__btn {
114
120
  margin-left: 0.2em;
115
121
  }
122
+
123
+ &:hover:not(:disabled),
124
+ &:active:not(:disabled) {
125
+ box-shadow: none;
126
+ transform: none;
127
+ }
116
128
  }
117
129
 
118
130
  .row-menu__btn-disabled {
@@ -276,21 +288,32 @@ $red: #f74242;
276
288
  }
277
289
  }
278
290
 
279
- .btn--fluid {
280
- @extend .btn;
281
- width: 100%;
282
- text-align: center;
283
- }
284
-
285
291
  .builder-row {
286
292
  position: relative;
287
293
 
288
294
  .btn-configure-row {
289
- background: none;
290
- display: block;
295
+ align-items: center;
296
+ background: transparent !important;
297
+ border: 0;
298
+ border-radius: 0;
299
+ box-shadow: none;
300
+ color: var(--blue);
301
+ display: inline-flex;
302
+ justify-content: center;
303
+ min-height: 32px;
304
+ min-width: 32px;
305
+ padding: 0.375rem;
291
306
  position: absolute;
292
307
  right: 1em;
293
308
  top: 0;
309
+ transform: none;
310
+
311
+ &:hover:not(:disabled),
312
+ &:active:not(:disabled) {
313
+ background: transparent !important;
314
+ box-shadow: none;
315
+ transform: none;
316
+ }
294
317
  }
295
318
 
296
319
  .footnotes {
@@ -351,3 +374,10 @@ $red: #f74242;
351
374
  border-color: var(--blue);
352
375
  }
353
376
  }
377
+
378
+ .row-menu__btn svg,
379
+ .builder-row .btn-configure-row svg {
380
+ margin-bottom: 0;
381
+ top: 0;
382
+ vertical-align: middle;
383
+ }