@cdc/dashboard 4.24.5 → 4.24.7

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 (70) hide show
  1. package/dist/cdcdashboard.js +122872 -112065
  2. package/examples/custom/css/respiratory.css +236 -0
  3. package/examples/custom/js/respiratory.js +242 -0
  4. package/examples/default-multi-dataset-shared-filter.json +1729 -0
  5. package/examples/ed-visits-county-file.json +618 -0
  6. package/examples/filtered-dash.json +6 -21
  7. package/index.html +10 -1
  8. package/package.json +12 -11
  9. package/src/CdcDashboard.tsx +5 -1
  10. package/src/CdcDashboardComponent.tsx +165 -306
  11. package/src/DashboardContext.tsx +9 -1
  12. package/src/_stories/Dashboard.stories.tsx +38 -34
  13. package/src/_stories/_mock/api-filter-chart.json +11 -35
  14. package/src/_stories/_mock/api-filter-map.json +17 -31
  15. package/src/_stories/_mock/multi-viz.json +2 -3
  16. package/src/_stories/_mock/pivot-filter.json +14 -12
  17. package/src/components/CollapsibleVisualizationRow.tsx +44 -0
  18. package/src/components/Column.tsx +1 -1
  19. package/src/components/DashboardFilters/DashboardFilters.tsx +80 -0
  20. package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +218 -0
  21. package/src/components/DashboardFilters/DashboardFiltersEditor/components/DeleteFilterModal.tsx +48 -0
  22. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +367 -0
  23. package/src/components/DashboardFilters/DashboardFiltersEditor/index.ts +1 -0
  24. package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +143 -0
  25. package/src/components/DashboardFilters/index.ts +3 -0
  26. package/src/components/DataDesignerModal.tsx +9 -9
  27. package/src/components/ExpandCollapseButtons.tsx +20 -0
  28. package/src/components/Header/Header.tsx +1 -97
  29. package/src/components/MultiConfigTabs/MultiConfigTabs.tsx +4 -4
  30. package/src/components/Row.tsx +52 -19
  31. package/src/components/Toggle/Toggle.tsx +2 -4
  32. package/src/components/VisualizationRow.tsx +82 -24
  33. package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +116 -0
  34. package/src/components/VisualizationsPanel/index.ts +1 -0
  35. package/src/components/VisualizationsPanel/visualizations-panel-styles.css +12 -0
  36. package/src/components/Widget.tsx +26 -90
  37. package/src/helpers/apiFilterHelpers.ts +51 -0
  38. package/src/helpers/changeFilterActive.ts +30 -0
  39. package/src/helpers/filterData.ts +10 -48
  40. package/src/helpers/generateValuesForFilter.ts +1 -1
  41. package/src/helpers/getAutoLoadVisualization.ts +11 -0
  42. package/src/helpers/getFilteredData.ts +4 -2
  43. package/src/helpers/getVizConfig.ts +23 -2
  44. package/src/helpers/getVizRowColumnLocator.ts +2 -1
  45. package/src/helpers/hasDashboardApplyBehavior.ts +5 -0
  46. package/src/helpers/iconHash.tsx +3 -3
  47. package/src/helpers/mapDataToConfig.ts +29 -0
  48. package/src/helpers/processData.ts +2 -3
  49. package/src/helpers/reloadURLHelpers.ts +68 -0
  50. package/src/helpers/tests/filterData.test.ts +1 -93
  51. package/src/scss/editor-panel.scss +1 -1
  52. package/src/scss/grid.scss +34 -27
  53. package/src/scss/main.scss +41 -3
  54. package/src/scss/variables.scss +4 -0
  55. package/src/store/dashboard.actions.ts +12 -4
  56. package/src/store/dashboard.reducer.ts +30 -4
  57. package/src/types/APIFilter.ts +1 -5
  58. package/src/types/ConfigRow.ts +2 -0
  59. package/src/types/Dashboard.ts +1 -1
  60. package/src/types/DashboardConfig.ts +2 -4
  61. package/src/types/DashboardFilters.ts +7 -0
  62. package/src/types/InitialState.ts +1 -1
  63. package/src/types/MultiDashboard.ts +2 -2
  64. package/src/types/SharedFilter.ts +2 -5
  65. package/src/types/Tab.ts +1 -1
  66. package/LICENSE +0 -201
  67. package/src/components/Filters.tsx +0 -88
  68. package/src/components/Header/FilterModal.tsx +0 -510
  69. package/src/components/VisualizationsPanel.tsx +0 -95
  70. package/src/helpers/getApiFilterKey.ts +0 -5
@@ -2,17 +2,22 @@ import { Dispatch, createContext } from 'react'
2
2
  import { DashboardState } from './store/dashboard.reducer'
3
3
  import DashboardActions from './store/dashboard.actions'
4
4
  import { Tab } from './types/Tab'
5
+ import { MultiDashboardConfig } from './types/MultiDashboard'
6
+ import { SharedFilter } from './types/SharedFilter'
7
+ import { APIFilterDropdowns } from './components/DashboardFilters'
5
8
 
6
9
  type ConfigCTX = DashboardState & {
7
10
  outerContainerRef: (node: any) => void
8
11
  setParentConfig: any
9
12
  isDebug: boolean
13
+ reloadURLData: (newFilters?: SharedFilter[]) => void
14
+ loadAPIFilters: (sharedFilters: SharedFilter[], dropdowns?: APIFilterDropdowns, recursiveLimit?: number) => Promise<SharedFilter[]>
10
15
  }
11
16
 
12
17
  const firstTab: Tab = 'Dashboard Description'
13
18
 
14
19
  export const initialState = {
15
- data: {},
20
+ data: {} as Record<string, any[]>,
16
21
  loading: false,
17
22
  filteredData: {},
18
23
  preview: false,
@@ -22,7 +27,10 @@ export const initialState = {
22
27
  const initialContext: ConfigCTX = {
23
28
  outerContainerRef: () => {},
24
29
  setParentConfig: () => {},
30
+ reloadURLData: () => {},
31
+ loadAPIFilters: () => Promise.resolve([]),
25
32
  isDebug: false,
33
+ config: {} as MultiDashboardConfig,
26
34
  ...initialState
27
35
  }
28
36
 
@@ -15,6 +15,9 @@ import { type DashboardConfig as Config } from '../types/DashboardConfig'
15
15
  import { userEvent, within } from '@storybook/testing-library'
16
16
  import ToggleExampleConfig from './_mock/toggle-example.json'
17
17
  import _ from 'lodash'
18
+ import { footnotesSymbols } from '@cdc/core/helpers/footnoteSymbols'
19
+ import FootnotesConfig from '@cdc/core/types/Footnotes'
20
+ import { ConfigRow } from '../types/ConfigRow'
18
21
 
19
22
  const meta: Meta<typeof Dashboard> = {
20
23
  title: 'Components/Pages/Dashboard',
@@ -89,8 +92,13 @@ countries.forEach((country, i) => {
89
92
  })
90
93
  })
91
94
 
95
+ const footnoteData = countries.map((country, i) => {
96
+ return { Country: country, symbol: footnotesSymbols[i][0], text: faker.lorem.sentence() }
97
+ })
98
+
92
99
  const multiVizData = {
93
- 'valid-world-data.json': { data }
100
+ 'valid-world-data.json': { data },
101
+ 'footnote-data.json': { data: footnoteData }
94
102
  }
95
103
 
96
104
  export const MultiVisualization: Story = {
@@ -107,6 +115,16 @@ export const MultiDashboard: Story = {
107
115
  }
108
116
  }
109
117
 
118
+ const FNrows: ConfigRow[] = [{ ...MultiVizConfig.rows[0], footnotesId: 'footnote123' }]
119
+ const footnoteConfig: Partial<FootnotesConfig> = { dataKey: 'footnote-data.json', dynamicFootnotes: { symbolColumn: 'symbol', textColumn: 'text' }, staticFootnotes: [{ symbol: '**', text: 'This is a static Footnote' }] }
120
+ const FNViz = { ...MultiVizConfig.visualizations, footnote123: footnoteConfig }
121
+ export const Footnotes: Story = {
122
+ args: {
123
+ config: { ...MultiVizConfig, datasets: multiVizData, rows: FNrows, visualizations: FNViz },
124
+ isEditor: false
125
+ }
126
+ }
127
+
110
128
  const sleep = ms => {
111
129
  return new Promise(r => setTimeout(r, ms))
112
130
  }
@@ -133,35 +151,18 @@ const fetchMock = {
133
151
  body: [{ IndicatorID: 'indicatorID', Indicator: 'Some Indicator' }]
134
152
  }
135
153
  },
136
- {
137
- matcher: {
138
- name: 'filters',
139
- url: 'path:/api/POC/Filters'
140
- },
141
- response: {
142
- status: 200,
143
- body: {
144
- Years: [{ Year: 1999 }],
145
- DataValueTypes: [{ DataValueType: 'Some Data Value Type', DataValueTypeId: 'dataValueTypeId' }],
146
- StratificationCategories: [{ StratificationCategoryId: 'stratCategoryId', StratificationCategory: 'Some Strat Category' }]
154
+ ...['Year', 'DataValueType', 'StratificationCategory', 'Stratification'].map(filter => {
155
+ return {
156
+ matcher: {
157
+ name: 'filters' + filter,
158
+ url: 'path:/api/POC/Filters/' + filter
159
+ },
160
+ response: {
161
+ status: 200,
162
+ body: _.times(5, i => ({ [filter]: `Some ${filter} ${i}` }))
147
163
  }
148
164
  }
149
- },
150
- {
151
- matcher: {
152
- name: 'stratifications',
153
- url: 'path:/api/POC/stratifications'
154
- },
155
- response: {
156
- status: 200,
157
- body: [
158
- {
159
- StratificationId: 'stratId',
160
- Stratification: 'Some Strat'
161
- }
162
- ]
163
- }
164
- },
165
+ }),
165
166
  {
166
167
  matcher: {
167
168
  name: 'locations',
@@ -213,7 +214,8 @@ const fetchMock = {
213
214
 
214
215
  export const APIFiltersMap: Story = {
215
216
  args: {
216
- config: APIFiltersMapData as unknown as Config
217
+ config: APIFiltersMapData as unknown as Config,
218
+ isEditor: false
217
219
  },
218
220
  parameters: {
219
221
  fetchMock
@@ -230,18 +232,19 @@ export const APIFiltersMap: Story = {
230
232
  const indicatorsFilter = canvas.getByLabelText('Indicator', { selector: 'select' })
231
233
  await user.selectOptions(indicatorsFilter, ['indicatorID'])
232
234
  const yearsFilter = canvas.getByLabelText('Year', { selector: 'select' })
233
- await user.selectOptions(yearsFilter, ['1999'])
235
+ await user.selectOptions(yearsFilter, ['Some Year 0'])
234
236
  const stratCategoryFilter = canvas.getByLabelText('View By', { selector: 'select' })
235
- await user.selectOptions(stratCategoryFilter, ['stratCategoryId'])
237
+ await user.selectOptions(stratCategoryFilter, ['Some StratificationCategory 0'])
236
238
  const stratFilter = canvas.getByLabelText('Stratification', { selector: 'select' })
237
- await user.selectOptions(stratFilter, ['stratId'])
239
+ await user.selectOptions(stratFilter, ['Some Stratification 0'])
238
240
  await user.click(canvas.getByText('GO!'))
239
241
  }
240
242
  }
241
243
 
242
244
  export const APIFiltersChart: Story = {
243
245
  args: {
244
- config: APIFiltersChartData as unknown as Config
246
+ config: APIFiltersChartData as unknown as Config,
247
+ isEditor: false
245
248
  },
246
249
  parameters: {
247
250
  fetchMock
@@ -260,8 +263,9 @@ export const APIFiltersChart: Story = {
260
263
  const indicatorsFilter = canvas.getByLabelText('Indicator', { selector: 'select' })
261
264
  await user.selectOptions(indicatorsFilter, ['indicatorID'])
262
265
  await user.click(canvas.getByText('GO!'))
266
+ await sleep(1000)
263
267
  const yearFilter = canvas.getByLabelText('Year', { selector: 'select' })
264
- await user.selectOptions(yearFilter, ['1999'])
268
+ await user.selectOptions(yearFilter, ['Some Year 1'])
265
269
  }
266
270
  }
267
271
 
@@ -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
+ }
@@ -164,7 +164,7 @@
164
164
  },
165
165
  "table": {
166
166
  "label": "Data Table",
167
- "expanded": true,
167
+ "expanded": false,
168
168
  "limitHeight": false,
169
169
  "height": "",
170
170
  "caption": "",
@@ -366,11 +366,10 @@
366
366
  },
367
367
  "table": {
368
368
  "label": "Data Table",
369
- "show": true,
369
+ "show": false,
370
370
  "showDownloadUrl": false,
371
371
  "showVertical": true
372
372
  },
373
- "newViz": true,
374
373
  "datasets": {},
375
374
  "type": "dashboard",
376
375
  "runtime": {},
@@ -1,16 +1,7 @@
1
1
  {
2
2
  "dashboard": {
3
3
  "theme": "theme-blue",
4
- "sharedFilters": [
5
- {
6
- "key": "Race",
7
- "type": "datafilter",
8
- "showDropdown": true,
9
- "columnName": "Race",
10
- "pivot": "Age-adjusted rate",
11
- "usedBy": ["table1707935263149"]
12
- }
13
- ]
4
+ "sharedFilters": []
14
5
  },
15
6
  "rows": [
16
7
  [
@@ -32,7 +23,11 @@
32
23
  "show": true,
33
24
  "showDownloadUrl": false,
34
25
  "showVertical": true,
35
- "expanded": true
26
+ "expanded": true,
27
+ "pivot": {
28
+ "columnName": "Race",
29
+ "valueColumn": "Age-adjusted rate"
30
+ }
36
31
  },
37
32
  "columns": {},
38
33
  "dataFormat": {},
@@ -41,7 +36,14 @@
41
36
  "horizontal": false,
42
37
  "series": false
43
38
  },
44
- "filters": [],
39
+ "filters": [
40
+ {
41
+ "filterStyle": "multi-select",
42
+ "label": "Race",
43
+ "columnName": "Race",
44
+ "showDropdown": true
45
+ }
46
+ ],
45
47
  "filterBehavior": "Filter Change",
46
48
  "formattedData": [
47
49
  {
@@ -0,0 +1,44 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import Icon from '../../../core/components/ui/Icon'
3
+
4
+ type CollapsableVizRow = {
5
+ allExpanded: boolean
6
+ children: React.ReactNode
7
+ fontSize: string
8
+ groupName: string
9
+ currentViewport: string
10
+ }
11
+ const CollapsibleVisualizationRow: React.FC<CollapsableVizRow> = ({ allExpanded, fontSize, groupName, currentViewport, children }) => {
12
+ const [isExpanded, setIsExpanded] = useState(allExpanded)
13
+ const fontSizes = { small: 16, medium: 18, large: 20 }
14
+ const titleFontSize = ['sm', 'xs', 'xxs'].includes(currentViewport) ? '13px' : `${fontSizes[fontSize]}px`
15
+
16
+ useEffect(() => {
17
+ setIsExpanded(allExpanded)
18
+ }, [allExpanded])
19
+
20
+ return (
21
+ <>
22
+ <div
23
+ style={{ fontSize: titleFontSize }}
24
+ role='button'
25
+ className={`multi-visualiation-heading${isExpanded ? '' : ' collapsed'} h4`}
26
+ onClick={() => {
27
+ setIsExpanded(!isExpanded)
28
+ }}
29
+ tabIndex={0}
30
+ onKeyDown={e => {
31
+ if (e.keyCode === 13) {
32
+ setIsExpanded(!isExpanded)
33
+ }
34
+ }}
35
+ >
36
+ <Icon display={isExpanded ? 'minus' : 'plus'} base />
37
+ {groupName}
38
+ </div>
39
+ {isExpanded && children}
40
+ </>
41
+ )
42
+ }
43
+
44
+ export default CollapsibleVisualizationRow
@@ -40,7 +40,7 @@ const Column = ({ data, rowIdx, colIdx }) => {
40
40
  return (
41
41
  <div className={classNames.join(' ')} ref={drop}>
42
42
  {widget ? (
43
- <Widget data={{ rowIdx, colIdx, ...widget }} type={widget.visualizationType ?? widget.general?.geoType} />
43
+ <Widget widgetConfig={{ rowIdx, colIdx, ...widget }} type={widget.visualizationType ?? widget.general?.geoType} />
44
44
  ) : (
45
45
  <p className='builder-column__text'>
46
46
  Drag and drop <br /> visualization
@@ -0,0 +1,80 @@
1
+ import { SharedFilter } from '../../types/SharedFilter'
2
+ import { APIFilterDropdowns } from './DashboardFiltersWrapper'
3
+
4
+ type DashboardFilterProps = {
5
+ show: number[]
6
+ filters: SharedFilter[]
7
+ apiFilterDropdowns: APIFilterDropdowns
8
+ handleOnChange: Function
9
+ }
10
+
11
+ const DashboardFilters: React.FC<DashboardFilterProps> = ({ show, filters, apiFilterDropdowns, handleOnChange }) => {
12
+ const nullVal = (singleFilter: SharedFilter) => {
13
+ const val = singleFilter.queuedActive || singleFilter.active
14
+ return val === null || val === undefined || val === ''
15
+ }
16
+ return (
17
+ <>
18
+ {filters.map((singleFilter, filterIndex) => {
19
+ if ((singleFilter.type !== 'urlfilter' && !singleFilter.showDropdown) || (show && !show.includes(filterIndex))) return <></>
20
+ const values: JSX.Element[] = []
21
+ const multiValues = []
22
+ if (singleFilter.resetLabel) {
23
+ values.push(
24
+ <option key={`${singleFilter.resetLabel}-option`} value={singleFilter.resetLabel}>
25
+ {singleFilter.resetLabel}
26
+ </option>
27
+ )
28
+ }
29
+ const _key = singleFilter.apiFilter?.apiEndpoint
30
+ if (_key && apiFilterDropdowns[_key]) {
31
+ // URL Filter
32
+ apiFilterDropdowns[_key].forEach(({ text, value }, index) => {
33
+ values.push(
34
+ <option key={`${value}-option-${index}`} value={value}>
35
+ {text}
36
+ </option>
37
+ )
38
+ })
39
+ } else {
40
+ // Data Filter
41
+ singleFilter.values?.forEach((filterOption, index) => {
42
+ const labeledOpt = singleFilter.labels && singleFilter.labels[filterOption]
43
+ values.push(
44
+ <option key={`${singleFilter.key}-option-${index}`} value={filterOption}>
45
+ {labeledOpt || filterOption}
46
+ </option>
47
+ )
48
+ multiValues.push({ value: filterOption, label: labeledOpt || filterOption })
49
+ })
50
+ }
51
+
52
+ return (
53
+ <div className='cove-dashboard-filters' key={`${singleFilter.key}-filtersection-${filterIndex}`}>
54
+ <section className='dashboard-filters-section'>
55
+ <label htmlFor={`filter-${filterIndex}`}>{singleFilter.key}</label>
56
+ <select
57
+ id={`filter-${filterIndex}`}
58
+ className='filter-select'
59
+ data-index='0'
60
+ value={singleFilter.queuedActive || singleFilter.active}
61
+ onChange={val => {
62
+ handleOnChange(filterIndex, val.target.value)
63
+ }}
64
+ >
65
+ {nullVal(singleFilter) && !singleFilter.resetLabel && (
66
+ <option value='' key='select'>
67
+ {'-Select-'}
68
+ </option>
69
+ )}
70
+ {values}
71
+ </select>
72
+ </section>
73
+ </div>
74
+ )
75
+ })}
76
+ </>
77
+ )
78
+ }
79
+
80
+ export default DashboardFilters