@cdc/dashboard 4.24.4 → 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.
- package/dist/cdcdashboard.js +179228 -141419
- package/examples/custom/css/respiratory.css +236 -0
- package/examples/custom/js/respiratory.js +242 -0
- package/examples/default-multi-dataset-shared-filter.json +1729 -0
- package/examples/ed-visits-county-file.json +618 -0
- package/examples/filtered-dash.json +6 -21
- package/index.html +12 -3
- package/package.json +12 -11
- package/src/CdcDashboard.tsx +5 -1
- package/src/CdcDashboardComponent.tsx +156 -334
- package/src/DashboardContext.tsx +9 -1
- package/src/_stories/Dashboard.stories.tsx +31 -3
- package/src/_stories/_mock/dashboard-gallery.json +534 -523
- package/src/_stories/_mock/markup-include.json +78 -0
- package/src/_stories/_mock/multi-dashboards.json +914 -0
- package/src/_stories/_mock/multi-viz.json +2 -3
- package/src/_stories/_mock/pivot-filter.json +15 -11
- package/src/_stories/_mock/standalone-table.json +2 -0
- package/src/components/CollapsibleVisualizationRow.tsx +44 -0
- package/src/components/Column.tsx +1 -1
- package/src/components/DashboardFilters/DashboardFilters.tsx +80 -0
- package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +218 -0
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/DeleteFilterModal.tsx +48 -0
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +367 -0
- package/src/components/DashboardFilters/DashboardFiltersEditor/index.ts +1 -0
- package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +143 -0
- package/src/components/DashboardFilters/index.ts +3 -0
- package/src/components/DataDesignerModal.tsx +9 -9
- package/src/components/ExpandCollapseButtons.tsx +20 -0
- package/src/components/Header/Header.tsx +1 -97
- package/src/components/MultiConfigTabs/MultiConfigTabs.tsx +4 -4
- package/src/components/MultiConfigTabs/MultiTabs.tsx +3 -2
- package/src/components/Row.tsx +52 -19
- package/src/components/Toggle/Toggle.tsx +2 -4
- package/src/components/VisualizationRow.tsx +96 -29
- package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +116 -0
- package/src/components/VisualizationsPanel/index.ts +1 -0
- package/src/components/VisualizationsPanel/visualizations-panel-styles.css +12 -0
- package/src/components/Widget.tsx +26 -90
- package/src/helpers/apiFilterHelpers.ts +51 -0
- package/src/helpers/changeFilterActive.ts +30 -0
- package/src/helpers/filterData.ts +16 -56
- package/src/helpers/generateValuesForFilter.ts +1 -1
- package/src/helpers/getAutoLoadVisualization.ts +11 -0
- package/src/helpers/getFilteredData.ts +4 -2
- package/src/helpers/getVizConfig.ts +23 -2
- package/src/helpers/getVizRowColumnLocator.ts +2 -1
- package/src/helpers/hasDashboardApplyBehavior.ts +5 -0
- package/src/helpers/iconHash.tsx +3 -3
- package/src/helpers/mapDataToConfig.ts +29 -0
- package/src/helpers/processData.ts +2 -3
- package/src/helpers/reloadURLHelpers.ts +68 -0
- package/src/helpers/tests/filterData.test.ts +1 -93
- package/src/scss/editor-panel.scss +1 -1
- package/src/scss/grid.scss +34 -27
- package/src/scss/main.scss +41 -3
- package/src/scss/variables.scss +4 -0
- package/src/store/dashboard.actions.ts +9 -10
- package/src/store/dashboard.reducer.ts +41 -13
- package/src/types/APIFilter.ts +1 -4
- package/src/types/ConfigRow.ts +2 -0
- package/src/types/Dashboard.ts +1 -1
- package/src/types/DashboardConfig.ts +2 -4
- package/src/types/DashboardFilters.ts +7 -0
- package/src/types/InitialState.ts +1 -1
- package/src/types/MultiDashboard.ts +2 -2
- package/src/types/SharedFilter.ts +2 -5
- package/src/types/Tab.ts +1 -1
- package/LICENSE +0 -201
- package/src/components/EditorWrapper/EditorWrapper.tsx +0 -52
- package/src/components/EditorWrapper/editor-wrapper.style.css +0 -13
- package/src/components/Filters.tsx +0 -88
- package/src/components/Header/FilterModal.tsx +0 -506
- package/src/components/VisualizationsPanel.tsx +0 -72
- package/src/helpers/getApiFilterKey.ts +0 -5
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
1
2
|
import { SharedFilter } from '../../types/SharedFilter'
|
|
2
3
|
import { filterData } from '../filterData'
|
|
3
4
|
|
|
@@ -36,48 +37,6 @@ describe('filterData', () => {
|
|
|
36
37
|
expect(result).toEqual([{ name: 'John', age: 30 }])
|
|
37
38
|
})
|
|
38
39
|
|
|
39
|
-
it('causes sideEffects to filters', () => {
|
|
40
|
-
// the side effect is not desired, but current functionality depends on the sideEffect.
|
|
41
|
-
// hopefully the side effect will be refactored in the future to be a returned value.
|
|
42
|
-
const filters = [
|
|
43
|
-
{ columnName: 'name', active: 'John', queuedActive: 'John', fileName: 'abc', key: 'name' },
|
|
44
|
-
{ columnName: 'age', fileName: 'abc', key: 'age' },
|
|
45
|
-
{ columnName: 'color', fileName: 'abc', key: 'color', parents: ['age'] }
|
|
46
|
-
] as SharedFilter[]
|
|
47
|
-
const data = [
|
|
48
|
-
{ name: 'John', age: 30, color: 'blue' },
|
|
49
|
-
{ name: 'Jane', age: 25, color: 'red' },
|
|
50
|
-
{ name: 'John', age: 35, color: 'yellow' },
|
|
51
|
-
{ name: 'Jane', age: 30, color: 'green' }
|
|
52
|
-
]
|
|
53
|
-
|
|
54
|
-
const result = filterData(filters, data)
|
|
55
|
-
|
|
56
|
-
expect(result).toEqual([{ name: 'John', age: 30, color: 'blue' }])
|
|
57
|
-
|
|
58
|
-
const sideEffectOfFiltering = [
|
|
59
|
-
{
|
|
60
|
-
columnName: 'name',
|
|
61
|
-
active: 'John',
|
|
62
|
-
queuedActive: 'John',
|
|
63
|
-
fileName: 'abc',
|
|
64
|
-
key: 'name',
|
|
65
|
-
tier: 1
|
|
66
|
-
},
|
|
67
|
-
{ columnName: 'age', fileName: 'abc', key: 'age', tier: 1 },
|
|
68
|
-
{
|
|
69
|
-
columnName: 'color',
|
|
70
|
-
fileName: 'abc',
|
|
71
|
-
key: 'color',
|
|
72
|
-
parents: ['age'],
|
|
73
|
-
tier: 2,
|
|
74
|
-
values: ['blue', 'yellow'],
|
|
75
|
-
active: 'blue'
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
expect(filters).toEqual(sideEffectOfFiltering)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
40
|
it('should not include data that does not meet the filter criteria', () => {
|
|
82
41
|
const filters = [
|
|
83
42
|
//{ columnName: 'apple', fileName: 'abc', key: 'banana' },
|
|
@@ -95,55 +54,4 @@ describe('filterData', () => {
|
|
|
95
54
|
const result = filterData(filters, data)
|
|
96
55
|
expect(result).toEqual([{ name: 'John', age: 25, color: 'red' }])
|
|
97
56
|
})
|
|
98
|
-
|
|
99
|
-
it('should pivot data based on the provided filters', () => {
|
|
100
|
-
const filters = [{ key: 'Race', type: 'datafilter', showDropdown: true, columnName: 'Race', pivot: 'Age-adjusted rate', usedBy: ['table1707935263149'] }] as SharedFilter[]
|
|
101
|
-
const data = [
|
|
102
|
-
{
|
|
103
|
-
Race: 'Hispanic or Latino',
|
|
104
|
-
'Age-adjusted rate': '644.2',
|
|
105
|
-
Year: '2016'
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
Race: 'Non-Hispanic American Indian',
|
|
109
|
-
'Age-adjusted rate': '636.1',
|
|
110
|
-
Year: '2016'
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
Race: 'Non-Hispanic Black',
|
|
114
|
-
'Age-adjusted rate': '563.7',
|
|
115
|
-
Year: '2016'
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
Race: 'Hispanic or Latino',
|
|
119
|
-
'Age-adjusted rate': '644.2',
|
|
120
|
-
Year: '2017'
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
Race: 'Non-Hispanic American Indian',
|
|
124
|
-
'Age-adjusted rate': '636.1',
|
|
125
|
-
Year: '2017'
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
Race: 'Non-Hispanic Black',
|
|
129
|
-
'Age-adjusted rate': '563.7',
|
|
130
|
-
Year: '2017'
|
|
131
|
-
}
|
|
132
|
-
]
|
|
133
|
-
|
|
134
|
-
expect(filterData(filters, data)).toEqual([
|
|
135
|
-
{
|
|
136
|
-
'Hispanic or Latino': '644.2',
|
|
137
|
-
'Non-Hispanic American Indian': '636.1',
|
|
138
|
-
'Non-Hispanic Black': '563.7',
|
|
139
|
-
Year: '2016'
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
'Hispanic or Latino': '644.2',
|
|
143
|
-
'Non-Hispanic American Indian': '636.1',
|
|
144
|
-
'Non-Hispanic Black': '563.7',
|
|
145
|
-
Year: '2017'
|
|
146
|
-
}
|
|
147
|
-
])
|
|
148
|
-
})
|
|
149
57
|
})
|
package/src/scss/grid.scss
CHANGED
|
@@ -7,15 +7,6 @@ $red: #f74242;
|
|
|
7
7
|
margin-left: calc($editorWidth + 1em);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
.visualizations-panel {
|
|
11
|
-
background-color: #fff;
|
|
12
|
-
padding: 1em;
|
|
13
|
-
width: $editorWidth;
|
|
14
|
-
border-right: #c7c7c7 1px solid;
|
|
15
|
-
z-index: 1;
|
|
16
|
-
overflow-y: scroll;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
10
|
.hidden.editor-panel + .builder-grid {
|
|
20
11
|
margin-left: 0 !important;
|
|
21
12
|
}
|
|
@@ -30,30 +21,16 @@ $red: #f74242;
|
|
|
30
21
|
padding: 5em 3em 3em;
|
|
31
22
|
}
|
|
32
23
|
|
|
33
|
-
.column-container {
|
|
34
|
-
display: flex;
|
|
35
|
-
flex-flow: row;
|
|
36
|
-
width: 100%;
|
|
37
|
-
position: relative;
|
|
38
|
-
padding: 2em 1em 1em;
|
|
39
|
-
border: 1px solid #c2c2c2;
|
|
40
|
-
transition: border 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
41
|
-
background-color: #f2f2f2;
|
|
42
|
-
user-select: none;
|
|
43
|
-
|
|
44
|
-
&.can-drop {
|
|
45
|
-
border-color: $blue-light;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
24
|
.row-menu {
|
|
50
25
|
display: flex;
|
|
51
26
|
align-items: flex-start;
|
|
52
27
|
transition: opacity 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
53
28
|
user-select: none;
|
|
54
|
-
position:
|
|
29
|
+
position: absolute;
|
|
55
30
|
z-index: 1;
|
|
56
|
-
|
|
31
|
+
top: -27px;
|
|
32
|
+
width: 100%;
|
|
33
|
+
left: 0;
|
|
57
34
|
|
|
58
35
|
> li:not(.spacer) + li:not(.spacer) {
|
|
59
36
|
margin-left: 0.3em;
|
|
@@ -337,6 +314,35 @@ $red: #f74242;
|
|
|
337
314
|
top: 0;
|
|
338
315
|
}
|
|
339
316
|
|
|
317
|
+
.footnotes {
|
|
318
|
+
margin: 0.5rem;
|
|
319
|
+
margin-bottom: 0;
|
|
320
|
+
width: calc(100% - 1rem);
|
|
321
|
+
border: 1px solid #c2c2c2;
|
|
322
|
+
transition: background-color 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
323
|
+
background-color: #c2c2c2;
|
|
324
|
+
&:hover {
|
|
325
|
+
border-color: $blue;
|
|
326
|
+
background-color: $blue;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
padding: 2em 1em 1em;
|
|
331
|
+
border: 1px solid #c2c2c2;
|
|
332
|
+
transition: border 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
333
|
+
background-color: #f2f2f2;
|
|
334
|
+
user-select: none;
|
|
335
|
+
|
|
336
|
+
&.can-drop {
|
|
337
|
+
border-color: $blue-light;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.column-container {
|
|
341
|
+
display: flex;
|
|
342
|
+
flex-flow: row;
|
|
343
|
+
width: 100%;
|
|
344
|
+
}
|
|
345
|
+
|
|
340
346
|
.widget__content {
|
|
341
347
|
padding: 0 2em;
|
|
342
348
|
|
|
@@ -369,5 +375,6 @@ $red: #f74242;
|
|
|
369
375
|
.column-container {
|
|
370
376
|
border-color: $blue;
|
|
371
377
|
}
|
|
378
|
+
border-color: $blue;
|
|
372
379
|
}
|
|
373
380
|
}
|
package/src/scss/main.scss
CHANGED
|
@@ -156,6 +156,13 @@
|
|
|
156
156
|
z-index: -1;
|
|
157
157
|
position: relative;
|
|
158
158
|
}
|
|
159
|
+
|
|
160
|
+
// Expand and Collapse Buttons for Multiviz Dashboard
|
|
161
|
+
&.expand-collapse-buttons {
|
|
162
|
+
background-color: var(--lightestGray);
|
|
163
|
+
border: 1px var(--lightGray) solid;
|
|
164
|
+
color: black;
|
|
165
|
+
}
|
|
159
166
|
}
|
|
160
167
|
|
|
161
168
|
.warning-icon {
|
|
@@ -181,6 +188,40 @@
|
|
|
181
188
|
}
|
|
182
189
|
}
|
|
183
190
|
|
|
191
|
+
.collapsable-multiviz-container {
|
|
192
|
+
position: relative;
|
|
193
|
+
border: $lightGray 1px solid;
|
|
194
|
+
clear: both;
|
|
195
|
+
margin-bottom: 20px;
|
|
196
|
+
.multi-visualiation-heading {
|
|
197
|
+
position: relative;
|
|
198
|
+
background: var(--lightestGray);
|
|
199
|
+
padding: 0.5em 0.7em;
|
|
200
|
+
cursor: pointer;
|
|
201
|
+
svg {
|
|
202
|
+
position: absolute;
|
|
203
|
+
height: 100%;
|
|
204
|
+
width: 15px;
|
|
205
|
+
top: 0;
|
|
206
|
+
right: 1em;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
&:focus {
|
|
210
|
+
z-index: 2;
|
|
211
|
+
position: relative;
|
|
212
|
+
}
|
|
213
|
+
@include breakpoint(xs) {
|
|
214
|
+
font-size: $font-small + 0.2em;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
.data-table-heading {
|
|
218
|
+
display: none;
|
|
219
|
+
}
|
|
220
|
+
.table-container {
|
|
221
|
+
margin: 0 1em;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
184
225
|
.dashboard-download-link {
|
|
185
226
|
font-size: 14px;
|
|
186
227
|
}
|
|
@@ -205,9 +246,6 @@
|
|
|
205
246
|
margin-left: 0;
|
|
206
247
|
margin-right: 0;
|
|
207
248
|
}
|
|
208
|
-
&.hidden-toggle {
|
|
209
|
-
display: none;
|
|
210
|
-
}
|
|
211
249
|
}
|
|
212
250
|
|
|
213
251
|
.dashboard-col-12 {
|
package/src/scss/variables.scss
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import type { DashboardConfig as Config } from '../types/DashboardConfig'
|
|
2
2
|
import { type Action } from '@cdc/core/types/Action'
|
|
3
3
|
import { Tab } from '../types/Tab'
|
|
4
|
-
<<<<<<< HEAD
|
|
5
|
-
import { ConfigureData } from '@cdc/core/types/ConfigureData'
|
|
6
4
|
import { ConfigRow } from '../types/ConfigRow'
|
|
7
|
-
|
|
5
|
+
import { AnyVisualization } from '@cdc/core/types/Visualization'
|
|
6
|
+
import Footnotes from '@cdc/core/types/Footnotes'
|
|
8
7
|
import { SharedFilter } from '../types/SharedFilter'
|
|
9
|
-
>>>>>>> 35436844 (fixed api dropdowns)
|
|
10
8
|
|
|
9
|
+
type ADD_FOOTNOTE = Action<'ADD_FOOTNOTE', { id: string; rowIndex: number; config: Footnotes }>
|
|
10
|
+
type APPLY_CONFIG = Action<'APPLY_CONFIG', [Config, Object?]>
|
|
11
11
|
type SET_CONFIG = Action<'SET_CONFIG', Partial<Config>>
|
|
12
12
|
type UPDATE_CONFIG = Action<'UPDATE_CONFIG', [Config, Object?]>
|
|
13
|
-
type SET_DATA = Action<'SET_DATA',
|
|
13
|
+
type SET_DATA = Action<'SET_DATA', Record<string, any[]>>
|
|
14
14
|
type SET_LOADING = Action<'SET_LOADING', boolean>
|
|
15
15
|
type SET_PREVIEW = Action<'SET_PREVIEW', boolean>
|
|
16
16
|
type SET_FILTERED_DATA = Action<'SET_FILTERED_DATA', Object>
|
|
17
|
+
type SET_SHARED_FILTERS = Action<'SET_SHARED_FILTERS', SharedFilter[]>
|
|
17
18
|
type SET_TAB_SELECTED = Action<'SET_TAB_SELECTED', Tab>
|
|
18
19
|
type RENAME_DASHBOARD_TAB = Action<'RENAME_DASHBOARD_TAB', { current: string; new: string }>
|
|
19
20
|
type INITIALIZE_MULTIDASHBOARDS = Action<'INITIALIZE_MULTIDASHBOARDS', undefined>
|
|
@@ -23,14 +24,12 @@ type ADD_NEW_DASHBOARD = Action<'ADD_NEW_DASHBOARD', undefined>
|
|
|
23
24
|
type SAVE_CURRENT_CHANGES = Action<'SAVE_CURRENT_CHANGES', undefined>
|
|
24
25
|
type SWITCH_CONFIG = Action<'SWITCH_CONFIG', number>
|
|
25
26
|
type TOGGLE_ROW = Action<'TOGGLE_ROW', { rowIndex: number; colIndex: number }>
|
|
26
|
-
|
|
27
|
-
type UPDATE_VISUALIZATION = Action<'UPDATE_VISUALIZATION', { vizKey: string; configureData: Partial<ConfigureData> }>
|
|
27
|
+
type UPDATE_VISUALIZATION = Action<'UPDATE_VISUALIZATION', { vizKey: string; configureData: Partial<AnyVisualization> }>
|
|
28
28
|
type UPDATE_ROW = Action<'UPDATE_ROW', { rowIndex: number; rowData: Partial<ConfigRow> }>
|
|
29
|
-
=======
|
|
30
|
-
type SET_SHARED_FILTERS = Action<'SET_SHARED_FILTERS', SharedFilter[]>
|
|
31
|
-
>>>>>>> 35436844 (fixed api dropdowns)
|
|
32
29
|
|
|
33
30
|
type DashboardActions =
|
|
31
|
+
| ADD_FOOTNOTE
|
|
32
|
+
| APPLY_CONFIG
|
|
34
33
|
| ADD_NEW_DASHBOARD
|
|
35
34
|
| SET_CONFIG
|
|
36
35
|
| UPDATE_CONFIG
|
|
@@ -4,16 +4,25 @@ import { MultiDashboardConfig } from '../types/MultiDashboard'
|
|
|
4
4
|
import DashboardActions from './dashboard.actions'
|
|
5
5
|
import { devToolsWrapper } from '@cdc/core/helpers/withDevTools'
|
|
6
6
|
import { Tab } from '../types/Tab'
|
|
7
|
+
import { DashboardConfig } from '../types/DashboardConfig'
|
|
8
|
+
import { ConfigRow } from '../types/ConfigRow'
|
|
9
|
+
import { AnyVisualization } from '@cdc/core/types/Visualization'
|
|
10
|
+
import { initialState } from '../DashboardContext'
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
dashboard:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
type BlankMultiConfig = {
|
|
13
|
+
dashboard: Partial<DashboardConfig>
|
|
14
|
+
rows: Partial<ConfigRow>[]
|
|
15
|
+
visualizations: Record<string, Object>
|
|
16
|
+
table: Object
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const createBlankDashboard: () => BlankMultiConfig = () => ({
|
|
20
|
+
dashboard: {},
|
|
21
|
+
rows: [{ columns: [{ width: 12 }] }],
|
|
13
22
|
visualizations: {},
|
|
14
23
|
table: {
|
|
15
24
|
label: 'Data Table',
|
|
16
|
-
show:
|
|
25
|
+
show: false,
|
|
17
26
|
showDownloadUrl: false,
|
|
18
27
|
showVertical: true
|
|
19
28
|
}
|
|
@@ -21,7 +30,7 @@ const createBlankDashboard = () => ({
|
|
|
21
30
|
|
|
22
31
|
export type DashboardState = {
|
|
23
32
|
config: MultiDashboardConfig
|
|
24
|
-
data:
|
|
33
|
+
data: Record<string, any[]>
|
|
25
34
|
filteredData: Object
|
|
26
35
|
loading: boolean
|
|
27
36
|
preview: boolean
|
|
@@ -30,6 +39,11 @@ export type DashboardState = {
|
|
|
30
39
|
|
|
31
40
|
const reducer = (state: DashboardState, action: DashboardActions): DashboardState => {
|
|
32
41
|
switch (action.type) {
|
|
42
|
+
case 'ADD_FOOTNOTE': {
|
|
43
|
+
const { id, rowIndex, config } = action.payload
|
|
44
|
+
const newRows = state.config.rows.map((row, i) => (i === rowIndex ? { ...row, footnotesId: id } : row))
|
|
45
|
+
return { ...state, config: { ...state.config, rows: newRows, visualizations: { ...state.config.visualizations, [id]: config } } }
|
|
46
|
+
}
|
|
33
47
|
case 'ADD_NEW_DASHBOARD': {
|
|
34
48
|
const currentMultiDashboards = state.config.multiDashboards
|
|
35
49
|
const label = 'New Dashboard ' + (currentMultiDashboards.length + 1)
|
|
@@ -40,6 +54,19 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
40
54
|
const [config, filteredData] = getUpdateConfig(state)(...action.payload)
|
|
41
55
|
return { ...state, config, filteredData }
|
|
42
56
|
}
|
|
57
|
+
case 'APPLY_CONFIG': {
|
|
58
|
+
// using advanced editor. Wipe all existing data and apply new config
|
|
59
|
+
const [config, filteredData] = getUpdateConfig(state)(...action.payload)
|
|
60
|
+
// get the default data state
|
|
61
|
+
const data = [...Object.values(config.visualizations), ...config.rows]
|
|
62
|
+
.map(viz => viz.dataKey)
|
|
63
|
+
.reduce((acc, key) => {
|
|
64
|
+
const data = state.data[key] || state.config.datasets[key]?.data
|
|
65
|
+
if (data) acc[key] = data
|
|
66
|
+
return acc
|
|
67
|
+
}, {})
|
|
68
|
+
return { ...initialState, config, filteredData, data }
|
|
69
|
+
}
|
|
43
70
|
case 'SET_CONFIG': {
|
|
44
71
|
return { ...state, config: { ...state.config, ...action.payload } }
|
|
45
72
|
}
|
|
@@ -55,6 +82,11 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
55
82
|
case 'SET_PREVIEW': {
|
|
56
83
|
return { ...state, preview: action.payload }
|
|
57
84
|
}
|
|
85
|
+
case 'SET_SHARED_FILTERS': {
|
|
86
|
+
const newSharedFilters = action.payload
|
|
87
|
+
const newDashboardConfig = { ...state.config.dashboard, sharedFilters: newSharedFilters }
|
|
88
|
+
return { ...state, config: { ...state.config, dashboard: newDashboardConfig } }
|
|
89
|
+
}
|
|
58
90
|
case 'SET_TAB_SELECTED': {
|
|
59
91
|
return { ...state, tabSelected: action.payload }
|
|
60
92
|
}
|
|
@@ -92,11 +124,6 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
92
124
|
newMultiDashboards[saveSlot] = { ...toSave, label }
|
|
93
125
|
return applyMultiDashboards(state, newMultiDashboards)
|
|
94
126
|
}
|
|
95
|
-
case 'SET_SHARED_FILTERS': {
|
|
96
|
-
const newSharedFilters = action.payload
|
|
97
|
-
const newDashboardConfig = { ...state.config.dashboard, sharedFilters: newSharedFilters }
|
|
98
|
-
return { ...state, config: { ...state.config, dashboard: newDashboardConfig } }
|
|
99
|
-
}
|
|
100
127
|
case 'INITIALIZE_MULTIDASHBOARDS': {
|
|
101
128
|
const label = 'New Dashboard 1'
|
|
102
129
|
const toSave = _.pick(state.config, ['dashboard', 'visualizations', 'rows'])
|
|
@@ -122,7 +149,8 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
122
149
|
}
|
|
123
150
|
case 'UPDATE_VISUALIZATION': {
|
|
124
151
|
const { vizKey, configureData } = action.payload
|
|
125
|
-
|
|
152
|
+
const updatedViz = { ...state.config.visualizations[vizKey], ...configureData } as AnyVisualization
|
|
153
|
+
return { ...state, config: { ...state.config, visualizations: { ...state.config.visualizations, [vizKey]: updatedViz } } }
|
|
126
154
|
}
|
|
127
155
|
case 'UPDATE_ROW': {
|
|
128
156
|
const { rowIndex, rowData } = action.payload
|
package/src/types/APIFilter.ts
CHANGED
package/src/types/ConfigRow.ts
CHANGED
|
@@ -10,8 +10,10 @@ type Col = {
|
|
|
10
10
|
|
|
11
11
|
export type ConfigRow = {
|
|
12
12
|
columns: Col[]
|
|
13
|
+
expandCollapseAllButtons: boolean
|
|
13
14
|
uuid?: string | number
|
|
14
15
|
toggle?: boolean
|
|
15
16
|
equalHeight?: boolean
|
|
16
17
|
multiVizColumn?: string
|
|
18
|
+
footnotesId?: string // id for the footnotes in the vizConfig section
|
|
17
19
|
} & ConfigureData
|
package/src/types/Dashboard.ts
CHANGED
|
@@ -2,21 +2,19 @@ import { Series } from '@cdc/core/types/Series'
|
|
|
2
2
|
import { Runtime } from '@cdc/core/types/Runtime'
|
|
3
3
|
import { DataSet } from './DataSet'
|
|
4
4
|
import { ConfigRow } from './ConfigRow'
|
|
5
|
-
import {
|
|
5
|
+
import { AnyVisualization } from '@cdc/core/types/Visualization'
|
|
6
6
|
import { Table } from '@cdc/core/types/Table'
|
|
7
|
-
import { FilterBehavior } from '@cdc/core/types/FilterBehavior'
|
|
8
7
|
import { Dashboard } from './Dashboard'
|
|
9
8
|
|
|
10
9
|
export type DashboardConfig = DataSet & {
|
|
11
10
|
dashboard: Dashboard
|
|
12
11
|
confidenceKeys: Record<string, any>
|
|
13
|
-
visualizations: Record<string,
|
|
12
|
+
visualizations: Record<string, AnyVisualization>
|
|
14
13
|
series: Series
|
|
15
14
|
datasets: Record<string, DataSet>
|
|
16
15
|
dataFileName: string
|
|
17
16
|
table: Table
|
|
18
17
|
rows: ConfigRow[]
|
|
19
|
-
filterBehavior: FilterBehavior
|
|
20
18
|
runtime: Runtime
|
|
21
19
|
downloadImageButton: boolean
|
|
22
20
|
downloadPdfButton: boolean
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AnyVisualization } from '@cdc/core/types/Visualization'
|
|
2
2
|
import { Dashboard } from './Dashboard'
|
|
3
3
|
import { DashboardConfig } from './DashboardConfig'
|
|
4
4
|
import { ConfigRow } from './ConfigRow'
|
|
5
5
|
|
|
6
|
-
export type MultiDashboard = { dashboard: Dashboard; rows: ConfigRow[]; visualizations: Record<string,
|
|
6
|
+
export type MultiDashboard = { dashboard: Dashboard; rows: ConfigRow[]; visualizations: Record<string, AnyVisualization>; label: string }
|
|
7
7
|
|
|
8
8
|
export type MultiDashboardConfig = DashboardConfig & {
|
|
9
9
|
multiDashboards?: MultiDashboard[]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { FilterBase } from '@cdc/core/types/VizFilter'
|
|
1
2
|
import { APIFilter } from './APIFilter'
|
|
2
|
-
export type SharedFilter = {
|
|
3
|
+
export type SharedFilter = FilterBase & {
|
|
3
4
|
type?: 'urlfilter' | 'datafilter' | ''
|
|
4
5
|
fileName?: string
|
|
5
6
|
filterBy?: 'Query String' | 'File Name'
|
|
@@ -9,15 +10,11 @@ export type SharedFilter = {
|
|
|
9
10
|
queuedActive?: string
|
|
10
11
|
usedBy?: (string | number)[] // if number used by whole row, else used by specific viz
|
|
11
12
|
parents?: string[]
|
|
12
|
-
pivot?: string
|
|
13
13
|
setBy?: string
|
|
14
14
|
selectLimit?: number
|
|
15
|
-
columnName?: string
|
|
16
15
|
resetLabel?: string
|
|
17
|
-
showDropdown?: boolean
|
|
18
16
|
labels?: Record<string, any>
|
|
19
17
|
key: string
|
|
20
|
-
values?: string[]
|
|
21
18
|
apiFilter?: APIFilter
|
|
22
19
|
datasetKey?: string
|
|
23
20
|
tier?: number
|
package/src/types/Tab.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type Tab = 'Dashboard Description' | '
|
|
1
|
+
export type Tab = 'Dashboard Description' | 'Data Table Settings' | 'Dashboard Preview'
|