@cdc/dashboard 4.24.2 → 4.24.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 (52) hide show
  1. package/dist/cdcdashboard.js +128512 -99417
  2. package/examples/chart-data.json +5409 -0
  3. package/examples/full-dash-test.json +14643 -0
  4. package/examples/full-dashboard.json +10036 -0
  5. package/examples/sankey.json +5218 -0
  6. package/index.html +4 -3
  7. package/package.json +11 -10
  8. package/src/CdcDashboard.tsx +129 -124
  9. package/src/CdcDashboardComponent.tsx +316 -441
  10. package/src/DashboardContext.tsx +4 -1
  11. package/src/_stories/Dashboard.stories.tsx +79 -36
  12. package/src/_stories/_mock/api-filter-chart.json +11 -35
  13. package/src/_stories/_mock/api-filter-map.json +17 -31
  14. package/src/_stories/_mock/dashboard-gallery.json +523 -534
  15. package/src/_stories/_mock/multi-viz.json +378 -0
  16. package/src/_stories/_mock/pivot-filter.json +161 -0
  17. package/src/_stories/_mock/standalone-table.json +122 -0
  18. package/src/_stories/_mock/toggle-example.json +4035 -0
  19. package/src/components/DataDesignerModal.tsx +145 -0
  20. package/src/components/EditorWrapper/EditorWrapper.tsx +52 -0
  21. package/src/components/EditorWrapper/editor-wrapper.style.css +13 -0
  22. package/src/components/Filters.tsx +88 -0
  23. package/src/components/Grid.tsx +3 -1
  24. package/src/components/Header/FilterModal.tsx +506 -0
  25. package/src/components/Header/Header.tsx +25 -465
  26. package/src/components/Row.tsx +65 -29
  27. package/src/components/Toggle/Toggle.tsx +36 -0
  28. package/src/components/Toggle/index.tsx +1 -0
  29. package/src/components/Toggle/toggle-style.css +34 -0
  30. package/src/components/VisualizationRow.tsx +174 -0
  31. package/src/components/VisualizationsPanel.tsx +13 -3
  32. package/src/components/Widget.tsx +28 -126
  33. package/src/helpers/filterData.ts +75 -50
  34. package/src/helpers/generateValuesForFilter.ts +2 -12
  35. package/src/helpers/getApiFilterKey.ts +5 -0
  36. package/src/helpers/getFilteredData.ts +39 -0
  37. package/src/helpers/getUpdateConfig.ts +39 -22
  38. package/src/helpers/getVizConfig.ts +31 -0
  39. package/src/helpers/getVizRowColumnLocator.ts +9 -0
  40. package/src/helpers/iconHash.tsx +34 -0
  41. package/src/helpers/tests/filterData.test.ts +149 -0
  42. package/src/images/icon-toggle.svg +1 -0
  43. package/src/scss/grid.scss +10 -3
  44. package/src/scss/main.scss +11 -0
  45. package/src/store/dashboard.actions.ts +35 -3
  46. package/src/store/dashboard.reducer.ts +33 -2
  47. package/src/types/APIFilter.ts +4 -5
  48. package/src/types/ConfigRow.ts +13 -2
  49. package/src/types/DataSet.ts +11 -8
  50. package/src/types/InitialState.ts +2 -1
  51. package/src/types/SharedFilter.ts +6 -3
  52. package/src/types/Tab.ts +1 -0
@@ -1,6 +1,7 @@
1
1
  import { Dispatch, createContext } from 'react'
2
2
  import { DashboardState } from './store/dashboard.reducer'
3
3
  import DashboardActions from './store/dashboard.actions'
4
+ import { Tab } from './types/Tab'
4
5
 
5
6
  type ConfigCTX = DashboardState & {
6
7
  outerContainerRef: (node: any) => void
@@ -8,12 +9,14 @@ type ConfigCTX = DashboardState & {
8
9
  isDebug: boolean
9
10
  }
10
11
 
12
+ const firstTab: Tab = 'Dashboard Description'
13
+
11
14
  export const initialState = {
12
15
  data: {},
13
16
  loading: false,
14
17
  filteredData: {},
15
18
  preview: false,
16
- tabSelected: 0
19
+ tabSelected: firstTab
17
20
  }
18
21
 
19
22
  const initialContext: ConfigCTX = {
@@ -1,13 +1,19 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react'
2
+ import { faker } from '@faker-js/faker'
2
3
  import APIFiltersMapData from './_mock/api-filter-map.json'
3
4
  import APIFiltersChartData from './_mock/api-filter-chart.json'
4
5
  import ExampleConfig_1 from './_mock/dashboard-gallery.json'
5
6
  import ExampleConfig_2 from './_mock/dashboard-2.json'
6
7
  import ExampleConfig_3 from './_mock/dashboard_no_filter.json'
7
8
  import Dashboard_Filter from './_mock/dashboard-filter.json'
8
- import Dashboard from '../CdcDashboardComponent'
9
+ import MultiVizConfig from './_mock/multi-viz.json'
10
+ import Dashboard from '../CdcDashboard'
11
+ import StandaloneTable from './_mock/standalone-table.json'
12
+ import PivotFitlerConfig from './_mock/pivot-filter.json'
9
13
  import { type DashboardConfig as Config } from '../types/DashboardConfig'
10
14
  import { userEvent, within } from '@storybook/testing-library'
15
+ import ToggleExampleConfig from './_mock/toggle-example.json'
16
+ import _ from 'lodash'
11
17
 
12
18
  const meta: Meta<typeof Dashboard> = {
13
19
  title: 'Components/Pages/Dashboard',
@@ -18,25 +24,78 @@ type Story = StoryObj<typeof Dashboard>
18
24
 
19
25
  export const Example_1: Story = {
20
26
  args: {
21
- config: ExampleConfig_1 as unknown as Config
27
+ config: ExampleConfig_1,
28
+ isEditor: false
22
29
  }
23
30
  }
24
31
 
25
32
  export const Example_2: Story = {
26
33
  args: {
27
- config: ExampleConfig_2 as unknown as Config
34
+ config: ExampleConfig_2,
35
+ isEditor: false
28
36
  }
29
37
  }
30
38
 
31
39
  export const Example_3: Story = {
32
40
  args: {
33
- config: ExampleConfig_3 as unknown as Config
41
+ config: ExampleConfig_3,
42
+ isEditor: false
34
43
  }
35
44
  }
36
45
 
37
46
  export const Dashboard_Filters: Story = {
38
47
  args: {
39
- config: Dashboard_Filter as unknown as Config
48
+ config: Dashboard_Filter,
49
+ isEditor: false
50
+ }
51
+ }
52
+
53
+ export const StandAloneTable: Story = {
54
+ args: {
55
+ config: StandaloneTable,
56
+ isEditor: false
57
+ }
58
+ }
59
+
60
+ export const ToggleExample: Story = {
61
+ args: {
62
+ config: ToggleExampleConfig,
63
+ isEditor: false
64
+ }
65
+ }
66
+
67
+ export const PivotFilter: Story = {
68
+ args: {
69
+ config: PivotFitlerConfig,
70
+ isEditor: false
71
+ }
72
+ }
73
+
74
+ faker.seed(123)
75
+
76
+ const countries = _.times(5, faker.location.country)
77
+ const categories = _.times(3, val => `category-${val + 1}`)
78
+
79
+ const data = []
80
+ countries.forEach((country, i) => {
81
+ categories.forEach((category, j) => {
82
+ if ((i + j) % 3 === 0) return
83
+ data.push({
84
+ Country: country,
85
+ 'Sample Categories': category,
86
+ Data: faker.number.int({ min: 5, max: 50 })
87
+ })
88
+ })
89
+ })
90
+
91
+ const multiVizData = {
92
+ 'valid-world-data.json': { data }
93
+ }
94
+
95
+ export const MultiVisualization: Story = {
96
+ args: {
97
+ config: { ...MultiVizConfig, datasets: multiVizData },
98
+ isEditor: false
40
99
  }
41
100
  }
42
101
 
@@ -66,35 +125,18 @@ const fetchMock = {
66
125
  body: [{ IndicatorID: 'indicatorID', Indicator: 'Some Indicator' }]
67
126
  }
68
127
  },
69
- {
70
- matcher: {
71
- name: 'filters',
72
- url: 'path:/api/POC/Filters'
73
- },
74
- response: {
75
- status: 200,
76
- body: {
77
- Years: [{ Year: 1999 }],
78
- DataValueTypes: [{ DataValueType: 'Some Data Value Type', DataValueTypeId: 'dataValueTypeId' }],
79
- StratificationCategories: [{ StratificationCategoryId: 'stratCategoryId', StratificationCategory: 'Some Strat Category' }]
128
+ ...['Year', 'DataValueType', 'StratificationCategory', 'Stratification'].map(filter => {
129
+ return {
130
+ matcher: {
131
+ name: 'filters' + filter,
132
+ url: 'path:/api/POC/Filters/' + filter
133
+ },
134
+ response: {
135
+ status: 200,
136
+ body: _.times(5, i => ({ [filter]: `Some ${filter} ${i}` }))
80
137
  }
81
138
  }
82
- },
83
- {
84
- matcher: {
85
- name: 'stratifications',
86
- url: 'path:/api/POC/stratifications'
87
- },
88
- response: {
89
- status: 200,
90
- body: [
91
- {
92
- StratificationId: 'stratId',
93
- Stratification: 'Some Strat'
94
- }
95
- ]
96
- }
97
- },
139
+ }),
98
140
  {
99
141
  matcher: {
100
142
  name: 'locations',
@@ -163,11 +205,11 @@ export const APIFiltersMap: Story = {
163
205
  const indicatorsFilter = canvas.getByLabelText('Indicator', { selector: 'select' })
164
206
  await user.selectOptions(indicatorsFilter, ['indicatorID'])
165
207
  const yearsFilter = canvas.getByLabelText('Year', { selector: 'select' })
166
- await user.selectOptions(yearsFilter, ['1999'])
208
+ await user.selectOptions(yearsFilter, ['Some Year 0'])
167
209
  const stratCategoryFilter = canvas.getByLabelText('View By', { selector: 'select' })
168
- await user.selectOptions(stratCategoryFilter, ['stratCategoryId'])
210
+ await user.selectOptions(stratCategoryFilter, ['Some StratificationCategory 0'])
169
211
  const stratFilter = canvas.getByLabelText('Stratification', { selector: 'select' })
170
- await user.selectOptions(stratFilter, ['stratId'])
212
+ await user.selectOptions(stratFilter, ['Some Stratification 0'])
171
213
  await user.click(canvas.getByText('GO!'))
172
214
  }
173
215
  }
@@ -193,8 +235,9 @@ export const APIFiltersChart: Story = {
193
235
  const indicatorsFilter = canvas.getByLabelText('Indicator', { selector: 'select' })
194
236
  await user.selectOptions(indicatorsFilter, ['indicatorID'])
195
237
  await user.click(canvas.getByText('GO!'))
238
+ await sleep(1000)
196
239
  const yearFilter = canvas.getByLabelText('Year', { selector: 'select' })
197
- await user.selectOptions(yearFilter, ['1999'])
240
+ await user.selectOptions(yearFilter, ['Some Year 1'])
198
241
  }
199
242
  }
200
243
 
@@ -4,9 +4,6 @@
4
4
  "sharedFilters": [
5
5
  {
6
6
  "key": "Location",
7
- "usedBy": [
8
- "chart1"
9
- ],
10
7
  "type": "urlfilter",
11
8
  "apiFilter": {
12
9
  "apiEndpoint": "http://test.gov/api/poc/locations",
@@ -19,9 +16,6 @@
19
16
  },
20
17
  {
21
18
  "key": "Category",
22
- "usedBy": [
23
- "chart1"
24
- ],
25
19
  "type": "urlfilter",
26
20
  "apiFilter": {
27
21
  "apiEndpoint": "http://test.gov/api/poc/topics",
@@ -34,9 +28,6 @@
34
28
  },
35
29
  {
36
30
  "key": "Indicator",
37
- "usedBy": [
38
- "chart1"
39
- ],
40
31
  "type": "urlfilter",
41
32
  "apiFilter": {
42
33
  "apiEndpoint": "http://test.gov/api/poc/indicators",
@@ -50,15 +41,11 @@
50
41
  },
51
42
  {
52
43
  "key": "Year",
53
- "usedBy": [
54
- "chart1"
55
- ],
56
44
  "type": "urlfilter",
57
45
  "apiFilter": {
58
- "apiEndpoint": "http://test.gov/api/POC/Filters",
46
+ "apiEndpoint": "http://test.gov/api/POC/Filters/Year",
59
47
  "valueSelector": "Year",
60
- "textSelector": "Year",
61
- "heirarchyLookup": "Years"
48
+ "textSelector": "Year"
62
49
  },
63
50
  "queryParameter": "year",
64
51
  "showDropdown": true,
@@ -66,15 +53,11 @@
66
53
  },
67
54
  {
68
55
  "key": "View By",
69
- "usedBy": [
70
- "chart1"
71
- ],
72
56
  "type": "urlfilter",
73
57
  "apiFilter": {
74
- "apiEndpoint": "http://test.gov/api/POC/Filters",
75
- "valueSelector": "StratificationCategoryId",
58
+ "apiEndpoint": "http://test.gov/api/POC/Filters/StratificationCategory",
59
+ "valueSelector": "StratificationCategory",
76
60
  "textSelector": "StratificationCategory",
77
- "heirarchyLookup": "StratificationCategories",
78
61
  "defaultValue": "AGE"
79
62
  },
80
63
  "queryParameter": "stratificationcategoryid",
@@ -83,16 +66,11 @@
83
66
  },
84
67
  {
85
68
  "key": "Data Type",
86
- "usedBy": [
87
- "chart1"
88
- ],
89
69
  "type": "urlfilter",
90
70
  "apiFilter": {
91
- "apiEndpoint": "http://test.gov/api/POC/Filters",
92
- "valueSelector": "DataValueTypeId",
93
- "textSelector": "DataValueType",
94
- "heirarchyLookup": "DataValueTypes"
95
-
71
+ "apiEndpoint": "http://test.gov/api/POC/Filters/DataValueType",
72
+ "valueSelector": "DataValueType",
73
+ "textSelector": "DataValueType"
96
74
  },
97
75
  "queryParameter": "datavaluetypeid",
98
76
  "showDropdown": true,
@@ -130,7 +108,7 @@
130
108
  "filters": {
131
109
  "type": "filter-dropdowns",
132
110
  "visualizationType": "filter-dropdowns",
133
- "hide": [ 3, 4, 5 ]
111
+ "hide": [3, 4, 5]
134
112
  },
135
113
  "header": {
136
114
  "type": "markup-include",
@@ -141,7 +119,7 @@
141
119
  "subfilters": {
142
120
  "type": "filter-dropdowns",
143
121
  "visualizationType": "filter-dropdowns",
144
- "hide": [ 0, 1, 2 ],
122
+ "hide": [0, 1, 2],
145
123
  "autoLoad": true
146
124
  },
147
125
  "chart1": {
@@ -341,9 +319,7 @@
341
319
  },
342
320
  "validated": 4.23,
343
321
  "dynamicMarginTop": 0,
344
- "regions": [
345
- {}
346
- ]
322
+ "regions": [{}]
347
323
  }
348
324
  },
349
325
  "type": "dashboard",
@@ -355,4 +331,4 @@
355
331
  "filterBehavior": "Apply Button",
356
332
  "runtime": {},
357
333
  "uuid": 1684783370106
358
- }
334
+ }
@@ -3,9 +3,7 @@
3
3
  "sharedFilters": [
4
4
  {
5
5
  "key": "Category",
6
- "usedBy": [
7
- "map1"
8
- ],
6
+ "usedBy": ["map1"],
9
7
  "type": "urlfilter",
10
8
  "apiFilter": {
11
9
  "apiEndpoint": "http://test.gov/api/poc/topics",
@@ -18,9 +16,7 @@
18
16
  },
19
17
  {
20
18
  "key": "Indicator",
21
- "usedBy": [
22
- "chart1"
23
- ],
19
+ "usedBy": ["chart1"],
24
20
  "type": "urlfilter",
25
21
  "apiFilter": {
26
22
  "apiEndpoint": "http://test.gov/api/poc/indicators",
@@ -34,15 +30,12 @@
34
30
  },
35
31
  {
36
32
  "key": "Year",
37
- "usedBy": [
38
- "map1"
39
- ],
33
+ "usedBy": ["map1"],
40
34
  "type": "urlfilter",
41
35
  "apiFilter": {
42
- "apiEndpoint": "http://test.gov/api/POC/Filters",
36
+ "apiEndpoint": "http://test.gov/api/POC/Filters/Year",
43
37
  "valueSelector": "Year",
44
- "textSelector": "Year",
45
- "heirarchyLookup": "Years"
38
+ "textSelector": "Year"
46
39
  },
47
40
  "queryParameter": "year",
48
41
  "resetLabel": "- Select -",
@@ -51,15 +44,12 @@
51
44
  },
52
45
  {
53
46
  "key": "View By",
54
- "usedBy": [
55
- "map1"
56
- ],
47
+ "usedBy": ["map1"],
57
48
  "type": "urlfilter",
58
49
  "apiFilter": {
59
- "apiEndpoint": "http://test.gov/api/POC/Filters",
60
- "valueSelector": "StratificationCategoryId",
61
- "textSelector": "StratificationCategory",
62
- "heirarchyLookup": "StratificationCategories"
50
+ "apiEndpoint": "http://test.gov/api/POC/Filters/StratificationCategory",
51
+ "valueSelector": "StratificationCategory",
52
+ "textSelector": "StratificationCategory"
63
53
  },
64
54
  "resetLabel": "- Select -",
65
55
  "queryParameter": "stratificationcategoryid",
@@ -68,13 +58,11 @@
68
58
  },
69
59
  {
70
60
  "key": "Stratification",
71
- "usedBy": [
72
- "map1"
73
- ],
61
+ "usedBy": ["map1"],
74
62
  "type": "urlfilter",
75
63
  "apiFilter": {
76
- "apiEndpoint": "http://test.gov/api/POC/stratifications",
77
- "valueSelector": "StratificationId",
64
+ "apiEndpoint": "http://test.gov/api/POC/Filters/Stratification",
65
+ "valueSelector": "Stratification",
78
66
  "textSelector": "Stratification"
79
67
  },
80
68
  "resetLabel": "- Select -",
@@ -149,8 +137,8 @@
149
137
  "suffix": "%",
150
138
  "name": "LowConfidenceLimit",
151
139
  "tooltip": true
152
- },
153
- "additionalColumn2": {
140
+ },
141
+ "additionalColumn2": {
154
142
  "label": "High Confidence Limit",
155
143
  "dataTable": true,
156
144
  "tooltips": false,
@@ -158,7 +146,7 @@
158
146
  "suffix": "%",
159
147
  "name": "HighConfidenceLimit",
160
148
  "tooltip": true
161
- },
149
+ },
162
150
  "navigate": {
163
151
  "name": "link",
164
152
  "tooltip": false,
@@ -173,9 +161,7 @@
173
161
  },
174
162
  "legend": {
175
163
  "descriptions": {},
176
- "specialClasses": [
177
- "NA"
178
- ],
164
+ "specialClasses": ["NA"],
179
165
  "unified": false,
180
166
  "singleColumn": false,
181
167
  "dynamicDescription": false,
@@ -196,4 +182,4 @@
196
182
  "filterBehavior": "Apply Button",
197
183
  "runtime": {},
198
184
  "uuid": 1684783370106
199
- }
185
+ }