@cdc/dashboard 4.26.1 → 4.26.3
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/LICENSE +201 -0
- package/dist/cdcdashboard-8NmHlKRI.es.js +15 -0
- package/dist/cdcdashboard-BPoPzKPz.es.js +6 -0
- package/dist/{cdcdashboard-dgT_1dIT.es.js → cdcdashboard-DQ00cQCm.es.js} +1 -20
- package/dist/cdcdashboard-jiQQPkty.es.js +6 -0
- package/dist/cdcdashboard-vr9HZwRt.es.js +6 -0
- package/dist/cdcdashboard.js +80971 -83096
- package/examples/custom/css/respiratory.css +1 -1
- package/examples/data/data-with-metadata.json +18 -0
- package/examples/default.json +492 -132
- package/examples/nested-dropdown.json +6985 -0
- package/examples/private/abc.json +467 -0
- package/examples/private/dash.json +12696 -0
- package/examples/private/inline-markup.json +775 -0
- package/examples/private/npcr.json +1 -0
- package/examples/private/recent-update.json +1456 -0
- package/examples/private/test.json +125407 -0
- package/examples/private/timeline-data.json +4994 -0
- package/examples/private/timeline.json +1708 -0
- package/examples/private/toggle.json +10137 -0
- package/examples/test-api-filter-reset.json +8 -4
- package/examples/tp5-gauges.json +196 -0
- package/examples/tp5-test.json +266 -0
- package/index.html +1 -29
- package/package.json +38 -40
- package/src/CdcDashboard.tsx +2 -1
- package/src/CdcDashboardComponent.tsx +47 -30
- package/src/_stories/Dashboard.DataSetup.stories.tsx +8 -2
- package/src/_stories/Dashboard.Pages.stories.tsx +22 -0
- package/src/_stories/Dashboard.stories.tsx +4501 -80
- package/src/_stories/_mock/dashboard-line-chart-angles.json +1030 -0
- package/src/_stories/_mock/tab-simple-filter.json +153 -0
- package/src/_stories/_mock/tp5-test.json +267 -0
- package/src/components/DashboardFilters/DashboardFilters.tsx +19 -3
- package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +10 -4
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/APIModal.tsx +1 -1
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +6 -3
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +13 -8
- package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +8 -8
- package/src/components/DashboardFilters/_stories/DashboardFilters.stories.tsx +1 -1
- package/src/components/DashboardFilters/dashboardfilter.styles.css +3 -3
- package/src/components/DataDesignerModal.tsx +2 -2
- package/src/components/Header/Header.tsx +27 -5
- package/src/components/Header/index.scss +1 -1
- package/src/components/MultiConfigTabs/multiconfigtabs.styles.css +6 -6
- package/src/components/Row.tsx +21 -0
- package/src/components/Toggle/toggle-style.css +7 -7
- package/src/components/VisualizationRow.tsx +42 -29
- package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +1 -71
- package/src/components/VisualizationsPanel/visualizations-panel-styles.css +2 -2
- package/src/components/Widget/Widget.tsx +2 -2
- package/src/components/Widget/widget.styles.css +12 -12
- package/src/data/initial-state.js +1 -1
- package/src/helpers/addValuesToDashboardFilters.ts +17 -11
- package/src/helpers/addVisualization.ts +71 -0
- package/src/helpers/apiFilterHelpers.ts +28 -32
- package/src/helpers/formatConfigBeforeSave.ts +1 -1
- package/src/helpers/getVizConfig.ts +13 -3
- package/src/helpers/iconHash.tsx +45 -36
- package/src/helpers/processDataLegacy.ts +19 -14
- package/src/helpers/tests/addValuesToDashboardFilters.test.ts +141 -44
- package/src/helpers/tests/addVisualization.test.ts +52 -0
- package/src/helpers/tests/apiFilterHelpers.test.ts +523 -420
- package/src/helpers/tests/formatConfigBeforeSave.test.ts +81 -1
- package/src/scss/editor-panel.scss +1 -1
- package/src/scss/main.scss +169 -41
- package/src/store/dashboard.reducer.ts +1 -1
- package/src/test/CdcDashboard.test.jsx +2 -2
- package/src/test/CdcDashboardComponent.test.tsx +74 -0
- package/src/types/FilterStyles.ts +2 -1
- package/tests/fixtures/dashboard-config-with-metadata.json +89 -0
- package/vite.config.js +7 -1
- package/dist/cdcdashboard-BnB1QM5d.es.js +0 -361528
- package/dist/cdcdashboard-Ct2SB0vL.es.js +0 -231049
- package/dist/cdcdashboard-D6CG2-Hb.es.js +0 -39377
- package/dist/cdcdashboard-MXgURbdZ.es.js +0 -39194
|
@@ -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
|
+
})
|
package/src/scss/main.scss
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
@import '@cdc/core/styles/
|
|
1
|
+
@import '@cdc/core/styles/utils/breakpoints';
|
|
2
2
|
|
|
3
|
-
.
|
|
3
|
+
button.row-menu__btn[title*='Equal Height Rows'] {
|
|
4
|
+
margin-left: 15px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.cove-visualization.type-dashboard {
|
|
4
8
|
@import 'editor-panel';
|
|
5
9
|
@import 'grid';
|
|
6
|
-
|
|
10
|
+
|
|
11
|
+
.loading>div.la-ball-beat {
|
|
7
12
|
margin-top: 20%;
|
|
8
13
|
}
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
>.cove-editor__content {
|
|
11
16
|
width: 100% !important;
|
|
12
17
|
left: 0px;
|
|
13
18
|
}
|
|
@@ -19,22 +24,27 @@
|
|
|
19
24
|
display: flex;
|
|
20
25
|
width: 100vw;
|
|
21
26
|
z-index: 5;
|
|
27
|
+
|
|
22
28
|
&.sub-dashboard-viz {
|
|
23
29
|
height: 3em;
|
|
24
30
|
}
|
|
31
|
+
|
|
25
32
|
.heading-1 {
|
|
26
33
|
min-width: 335px;
|
|
27
34
|
font-size: 1.2em;
|
|
28
35
|
padding-right: 1em;
|
|
29
36
|
margin: 0.5em 1em 0.5em 0;
|
|
30
37
|
border-right: 1px solid black;
|
|
38
|
+
|
|
31
39
|
&.back-to {
|
|
32
40
|
display: flex;
|
|
41
|
+
|
|
33
42
|
span {
|
|
34
43
|
font-weight: bold;
|
|
35
44
|
padding-right: 0.3em;
|
|
36
45
|
}
|
|
37
46
|
}
|
|
47
|
+
|
|
38
48
|
input[type='text'] {
|
|
39
49
|
width: 100%;
|
|
40
50
|
margin-top: 10px;
|
|
@@ -43,6 +53,7 @@
|
|
|
43
53
|
|
|
44
54
|
.heading-body {
|
|
45
55
|
display: flex;
|
|
56
|
+
align-items: flex-start;
|
|
46
57
|
|
|
47
58
|
.wrap {
|
|
48
59
|
display: inline-flex;
|
|
@@ -83,6 +94,7 @@
|
|
|
83
94
|
position: relative;
|
|
84
95
|
bottom: -1px;
|
|
85
96
|
border-bottom: #c7c7c7 1px solid;
|
|
97
|
+
|
|
86
98
|
li {
|
|
87
99
|
padding: 0.3em 1.5em;
|
|
88
100
|
color: var(--mediumGray);
|
|
@@ -90,12 +102,14 @@
|
|
|
90
102
|
white-space: nowrap;
|
|
91
103
|
text-overflow: ellipsis;
|
|
92
104
|
overflow: hidden;
|
|
105
|
+
|
|
93
106
|
&.active {
|
|
94
107
|
border-bottom-color: var(--mediumGray);
|
|
95
108
|
border-bottom-style: inherit;
|
|
96
109
|
border-bottom-width: 5px;
|
|
97
110
|
color: var(--darkGray);
|
|
98
111
|
}
|
|
112
|
+
|
|
99
113
|
&:hover {
|
|
100
114
|
border-bottom-color: var(--darkGray);
|
|
101
115
|
color: var(--darkGray);
|
|
@@ -122,6 +136,7 @@
|
|
|
122
136
|
}
|
|
123
137
|
|
|
124
138
|
.btn {
|
|
139
|
+
|
|
125
140
|
// Expand and Collapse Buttons for Multiviz Dashboard
|
|
126
141
|
&.expand-collapse-buttons {
|
|
127
142
|
background-color: var(--lightestGray);
|
|
@@ -139,11 +154,13 @@
|
|
|
139
154
|
border: var(--lightGray) 1px solid;
|
|
140
155
|
clear: both;
|
|
141
156
|
margin-bottom: 20px;
|
|
157
|
+
|
|
142
158
|
.multi-visualiation-heading {
|
|
143
159
|
position: relative;
|
|
144
160
|
background: var(--lightestGray);
|
|
145
161
|
padding: 0.5em 0.7em;
|
|
146
162
|
cursor: pointer;
|
|
163
|
+
|
|
147
164
|
svg {
|
|
148
165
|
position: absolute;
|
|
149
166
|
height: 100%;
|
|
@@ -156,10 +173,12 @@
|
|
|
156
173
|
z-index: 2;
|
|
157
174
|
position: relative;
|
|
158
175
|
}
|
|
176
|
+
|
|
159
177
|
@include breakpoint(xs) {
|
|
160
178
|
font-size: 0.9em;
|
|
161
179
|
}
|
|
162
180
|
}
|
|
181
|
+
|
|
163
182
|
.data-table-heading {
|
|
164
183
|
display: none;
|
|
165
184
|
}
|
|
@@ -181,10 +200,11 @@
|
|
|
181
200
|
margin-bottom: 1.5rem;
|
|
182
201
|
|
|
183
202
|
// Remove padding from first and last columns to keep content flush to edges
|
|
184
|
-
>
|
|
203
|
+
>[class*='col-']:first-child {
|
|
185
204
|
padding-left: 0;
|
|
186
205
|
}
|
|
187
|
-
|
|
206
|
+
|
|
207
|
+
>[class*='col-']:last-child {
|
|
188
208
|
padding-right: 0;
|
|
189
209
|
}
|
|
190
210
|
|
|
@@ -199,7 +219,7 @@
|
|
|
199
219
|
.row {
|
|
200
220
|
margin-bottom: 1.5rem;
|
|
201
221
|
|
|
202
|
-
>
|
|
222
|
+
>[class*='col-'] {
|
|
203
223
|
// Remove side padding when columns stack to full width
|
|
204
224
|
padding-left: 0;
|
|
205
225
|
padding-right: 0;
|
|
@@ -207,7 +227,7 @@
|
|
|
207
227
|
}
|
|
208
228
|
|
|
209
229
|
// Last column doesn't need margin (row margin handles gap to next row)
|
|
210
|
-
>
|
|
230
|
+
>[class*='col-']:last-child {
|
|
211
231
|
margin-bottom: 0;
|
|
212
232
|
}
|
|
213
233
|
|
|
@@ -221,6 +241,7 @@
|
|
|
221
241
|
.dashboard-row {
|
|
222
242
|
display: flex;
|
|
223
243
|
flex-direction: column;
|
|
244
|
+
|
|
224
245
|
&.toggle {
|
|
225
246
|
display: block;
|
|
226
247
|
}
|
|
@@ -228,9 +249,10 @@
|
|
|
228
249
|
|
|
229
250
|
.dashboard-col {
|
|
230
251
|
margin: 0;
|
|
252
|
+
|
|
231
253
|
// Disable the module individual margin
|
|
232
254
|
.map-container,
|
|
233
|
-
.
|
|
255
|
+
.cove-visualization.type-chart .cove-visualization__body>* {
|
|
234
256
|
margin-left: 0;
|
|
235
257
|
margin-right: 0;
|
|
236
258
|
}
|
|
@@ -261,6 +283,7 @@
|
|
|
261
283
|
.dashboard-col-8 {
|
|
262
284
|
width: 66%;
|
|
263
285
|
}
|
|
286
|
+
|
|
264
287
|
.dashboard-col-6 {
|
|
265
288
|
width: 50%;
|
|
266
289
|
}
|
|
@@ -292,42 +315,148 @@
|
|
|
292
315
|
padding: 1rem;
|
|
293
316
|
}
|
|
294
317
|
|
|
295
|
-
//
|
|
296
|
-
.row
|
|
318
|
+
// User-configured equal height rows
|
|
319
|
+
.row.equal-height {
|
|
297
320
|
display: flex !important;
|
|
298
321
|
align-items: stretch !important;
|
|
299
322
|
|
|
300
|
-
// Ensure Bootstrap columns are flex containers
|
|
301
323
|
[class*='col-'] {
|
|
302
|
-
display: flex
|
|
324
|
+
display: flex;
|
|
303
325
|
flex-direction: column !important;
|
|
326
|
+
flex: 1 1 auto !important;
|
|
327
|
+
align-items: stretch !important;
|
|
328
|
+
min-height: 0 !important;
|
|
304
329
|
|
|
305
|
-
|
|
330
|
+
>* {
|
|
306
331
|
display: flex !important;
|
|
307
332
|
flex-direction: column !important;
|
|
308
|
-
flex: 1 !important;
|
|
309
|
-
|
|
310
|
-
|
|
333
|
+
flex: 1 1 auto !important;
|
|
334
|
+
align-items: stretch !important;
|
|
335
|
+
min-height: 0 !important;
|
|
336
|
+
width: 100% !important;
|
|
311
337
|
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
338
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
339
|
+
.collapsable-multiviz-container,
|
|
340
|
+
.cove-visualization {
|
|
341
|
+
display: flex !important;
|
|
342
|
+
flex-direction: column !important;
|
|
343
|
+
flex: 1 1 auto !important;
|
|
344
|
+
align-items: stretch !important;
|
|
345
|
+
min-height: 0 !important;
|
|
346
|
+
width: 100% !important;
|
|
347
|
+
|
|
348
|
+
>.cove-visualization__content,
|
|
349
|
+
>.cove-visualization__outer,
|
|
350
|
+
>.cove-visualization__inner,
|
|
351
|
+
>.cove-visualization__body {
|
|
352
|
+
display: flex !important;
|
|
353
|
+
flex-direction: column !important;
|
|
354
|
+
flex: 1 1 auto !important;
|
|
355
|
+
align-items: stretch !important;
|
|
356
|
+
min-height: 0 !important;
|
|
357
|
+
width: 100% !important;
|
|
358
|
+
|
|
359
|
+
>.cove-visualization__inner,
|
|
360
|
+
>.cove-visualization__body,
|
|
361
|
+
>.cove-visualization__body-wrap {
|
|
362
|
+
display: flex !important;
|
|
363
|
+
flex-direction: column !important;
|
|
364
|
+
flex: 1 1 auto !important;
|
|
365
|
+
align-items: stretch !important;
|
|
366
|
+
min-height: 0 !important;
|
|
367
|
+
width: 100% !important;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.cove-visualization__outer,
|
|
372
|
+
.cove-visualization__inner,
|
|
373
|
+
.cove-visualization__body,
|
|
374
|
+
.cove-visualization__body-wrap {
|
|
375
|
+
display: flex !important;
|
|
376
|
+
flex-direction: column !important;
|
|
377
|
+
flex: 1 1 auto !important;
|
|
378
|
+
align-items: stretch !important;
|
|
379
|
+
min-height: 0 !important;
|
|
380
|
+
width: 100% !important;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
319
383
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
384
|
+
.bite,
|
|
385
|
+
.bite-content-container,
|
|
386
|
+
.bite-content,
|
|
387
|
+
.bite-content__text-wrap,
|
|
388
|
+
.cdc-callout,
|
|
389
|
+
.cdc-callout__content {
|
|
390
|
+
display: flex !important;
|
|
391
|
+
flex-direction: column !important;
|
|
392
|
+
flex: 1 1 auto !important;
|
|
393
|
+
min-height: 0 !important;
|
|
394
|
+
}
|
|
324
395
|
|
|
325
|
-
|
|
396
|
+
.cdc-callout__body {
|
|
397
|
+
flex: 1 1 auto !important;
|
|
398
|
+
min-height: 0 !important;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.cove-visualization .cove-visualization__body.bite__style--tp5>.cove-visualization__body-wrap {
|
|
326
402
|
display: flex !important;
|
|
327
403
|
flex-direction: column !important;
|
|
328
|
-
flex: 1 !important;
|
|
329
|
-
min-height: 0;
|
|
330
|
-
|
|
404
|
+
flex: 1 1 auto !important;
|
|
405
|
+
min-height: 0 !important;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.cove-visualization .cove-visualization__body.bite__style--tp5>.cove-visualization__body-wrap>.cove-visualization__content-section {
|
|
409
|
+
display: flex !important;
|
|
410
|
+
flex-direction: column !important;
|
|
411
|
+
flex: 1 1 auto !important;
|
|
412
|
+
min-height: 0 !important;
|
|
413
|
+
width: 100% !important;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.cove-visualization .cove-visualization__body.bite__style--tp5>.cove-visualization__body-wrap>.cove-visualization__content-section>.cdc-callout {
|
|
417
|
+
display: flex !important;
|
|
418
|
+
flex-direction: column !important;
|
|
419
|
+
flex: 1 1 auto !important;
|
|
420
|
+
min-height: 100% !important;
|
|
421
|
+
width: 100% !important;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.cove-visualization.waffle__style--tp5 .cove-visualization__body>.cove-visualization__body-wrap,
|
|
425
|
+
.cove-visualization.gauge__style--tp5 .cove-visualization__body>.cove-visualization__body-wrap {
|
|
426
|
+
display: flex !important;
|
|
427
|
+
flex-direction: column !important;
|
|
428
|
+
flex: 1 1 auto !important;
|
|
429
|
+
min-height: 0 !important;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.cove-visualization.waffle__style--tp5 .cove-visualization__body>.cove-visualization__body-wrap>.cove-visualization__content-section,
|
|
433
|
+
.cove-visualization.gauge__style--tp5 .cove-visualization__body>.cove-visualization__body-wrap>.cove-visualization__content-section {
|
|
434
|
+
display: flex !important;
|
|
435
|
+
flex-direction: column !important;
|
|
436
|
+
flex: 1 1 auto !important;
|
|
437
|
+
min-height: 0 !important;
|
|
438
|
+
width: 100% !important;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.cove-visualization.waffle__style--tp5 .cove-visualization__body>.cove-visualization__body-wrap>.cove-visualization__content-section>.cdc-callout,
|
|
442
|
+
.cove-visualization.gauge__style--tp5 .cove-visualization__body>.cove-visualization__body-wrap>.cove-visualization__content-section>.cdc-callout {
|
|
443
|
+
display: flex !important;
|
|
444
|
+
flex-direction: column !important;
|
|
445
|
+
flex: 1 1 auto !important;
|
|
446
|
+
min-height: 100% !important;
|
|
447
|
+
width: 100% !important;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.cove-visualization .cove-visualization__body.bite__style--tp5 .cdc-callout__body {
|
|
451
|
+
display: flex !important;
|
|
452
|
+
flex: 1 1 auto !important;
|
|
453
|
+
align-items: stretch !important;
|
|
454
|
+
min-height: 0 !important;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
.cove-visualization .cove-visualization__body.bite__style--tp5 .cdc-callout__content {
|
|
458
|
+
flex: 1 1 auto !important;
|
|
459
|
+
min-height: 0 !important;
|
|
331
460
|
}
|
|
332
461
|
}
|
|
333
462
|
}
|
|
@@ -346,15 +475,12 @@
|
|
|
346
475
|
}
|
|
347
476
|
}
|
|
348
477
|
|
|
349
|
-
// TP5 Waffle
|
|
350
|
-
.row:has(.waffle__style--tp5):has([class*='col-'] ~ [class*='col-'])
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
display: flex;
|
|
356
|
-
flex-direction: column;
|
|
357
|
-
}
|
|
478
|
+
// TP5 Waffle/Gauge adjustments when there are 2+ in a row
|
|
479
|
+
.row:has(.waffle__style--tp5):has([class*='col-'] ~ [class*='col-']),
|
|
480
|
+
.row:has(.gauge__style--tp5):has([class*='col-'] ~ [class*='col-']) {
|
|
481
|
+
|
|
482
|
+
.waffle__style--tp5,
|
|
483
|
+
.gauge__style--tp5 {
|
|
358
484
|
|
|
359
485
|
.cdc-callout {
|
|
360
486
|
flex: 1;
|
|
@@ -390,6 +516,7 @@
|
|
|
390
516
|
|
|
391
517
|
.sub-editor {
|
|
392
518
|
margin-top: 40px;
|
|
519
|
+
|
|
393
520
|
.sub-editor-heading {
|
|
394
521
|
display: flex;
|
|
395
522
|
align-items: center;
|
|
@@ -401,6 +528,7 @@
|
|
|
401
528
|
background-color: red;
|
|
402
529
|
z-index: 101;
|
|
403
530
|
}
|
|
531
|
+
|
|
404
532
|
.editor-panel {
|
|
405
533
|
top: 40px;
|
|
406
534
|
}
|
|
@@ -414,4 +542,4 @@
|
|
|
414
542
|
display: block;
|
|
415
543
|
margin: 1em 0;
|
|
416
544
|
}
|
|
417
|
-
}
|
|
545
|
+
}
|
|
@@ -237,7 +237,7 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
237
237
|
|
|
238
238
|
const filteredRows = _.map(newRows, row => ({
|
|
239
239
|
...row,
|
|
240
|
-
columns:
|
|
240
|
+
columns: row.columns.map(column => (column.widget === uid ? _.omit(column, 'widget') : column))
|
|
241
241
|
}))
|
|
242
242
|
|
|
243
243
|
return {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import path from 'path'
|
|
1
|
+
import path from 'node:path'
|
|
2
2
|
import { testStandaloneBuild } from '@cdc/core/helpers/tests/testStandaloneBuild.ts'
|
|
3
3
|
import { describe, it, expect } from 'vitest'
|
|
4
4
|
|
|
5
5
|
describe('Dashboard', () => {
|
|
6
6
|
it('Can be built in isolation', async () => {
|
|
7
7
|
const pkgDir = path.join(__dirname, '..')
|
|
8
|
-
const result = testStandaloneBuild(pkgDir)
|
|
8
|
+
const result = await testStandaloneBuild(pkgDir)
|
|
9
9
|
expect(result).toBe(true)
|
|
10
10
|
}, 300000)
|
|
11
11
|
})
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import CdcDashboardComponent from '../CdcDashboardComponent'
|
|
5
|
+
import type { InitialState } from '../types/InitialState'
|
|
6
|
+
|
|
7
|
+
describe('CdcDashboardComponent', () => {
|
|
8
|
+
it('renders dashboard markup through the shared visualization shell', () => {
|
|
9
|
+
const initialState = {
|
|
10
|
+
config: {
|
|
11
|
+
type: 'dashboard',
|
|
12
|
+
dashboard: {
|
|
13
|
+
title: 'Dashboard Title',
|
|
14
|
+
titleStyle: 'small',
|
|
15
|
+
theme: 'theme-blue',
|
|
16
|
+
sharedFilters: []
|
|
17
|
+
},
|
|
18
|
+
visualizations: {},
|
|
19
|
+
rows: [],
|
|
20
|
+
datasets: {},
|
|
21
|
+
table: {}
|
|
22
|
+
},
|
|
23
|
+
data: {},
|
|
24
|
+
loading: false,
|
|
25
|
+
filteredData: {},
|
|
26
|
+
preview: false,
|
|
27
|
+
tabSelected: 'Dashboard Preview',
|
|
28
|
+
filtersApplied: true
|
|
29
|
+
} as InitialState
|
|
30
|
+
|
|
31
|
+
const { container } = render(
|
|
32
|
+
<CdcDashboardComponent initialState={initialState} interactionLabel='dashboard-test' isEditor={false} />
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
const shell = container.querySelector('.cove-visualization')
|
|
36
|
+
|
|
37
|
+
expect(shell).toHaveClass('type-dashboard')
|
|
38
|
+
expect(shell).toHaveAttribute('data-download-id')
|
|
39
|
+
expect(shell?.querySelector('.cove-visualization__outer')).toBeInTheDocument()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('keeps the dashboard root out of the shared editor grid layout', () => {
|
|
43
|
+
const initialState = {
|
|
44
|
+
config: {
|
|
45
|
+
type: 'dashboard',
|
|
46
|
+
dashboard: {
|
|
47
|
+
title: 'Dashboard Title',
|
|
48
|
+
titleStyle: 'small',
|
|
49
|
+
theme: 'theme-blue',
|
|
50
|
+
sharedFilters: []
|
|
51
|
+
},
|
|
52
|
+
visualizations: {},
|
|
53
|
+
rows: [],
|
|
54
|
+
datasets: {},
|
|
55
|
+
table: {}
|
|
56
|
+
},
|
|
57
|
+
data: {},
|
|
58
|
+
loading: false,
|
|
59
|
+
filteredData: {},
|
|
60
|
+
preview: false,
|
|
61
|
+
tabSelected: 'Dashboard Preview',
|
|
62
|
+
filtersApplied: true
|
|
63
|
+
} as InitialState
|
|
64
|
+
|
|
65
|
+
const { container } = render(
|
|
66
|
+
<CdcDashboardComponent initialState={initialState} interactionLabel='dashboard-test' isEditor={true} />
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
const shell = container.querySelector('.cove-visualization')
|
|
70
|
+
|
|
71
|
+
expect(shell).toHaveClass('type-dashboard', 'is-dashboard-editor')
|
|
72
|
+
expect(shell).not.toHaveClass('is-editor')
|
|
73
|
+
})
|
|
74
|
+
})
|
|
@@ -2,7 +2,8 @@ export const FILTER_STYLE = {
|
|
|
2
2
|
combobox: 'combobox',
|
|
3
3
|
dropdown: 'dropdown',
|
|
4
4
|
multiSelect: 'multi-select',
|
|
5
|
-
nestedDropdown: 'nested-dropdown'
|
|
5
|
+
nestedDropdown: 'nested-dropdown',
|
|
6
|
+
tabSimple: 'tab-simple'
|
|
6
7
|
} as const
|
|
7
8
|
|
|
8
9
|
export type FilterStyle = (typeof FILTER_STYLE)[keyof typeof FILTER_STYLE]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dashboard": {
|
|
3
|
+
"theme": "theme-blue",
|
|
4
|
+
"title": "Metadata Test Dashboard",
|
|
5
|
+
"sharedFilters": [
|
|
6
|
+
{
|
|
7
|
+
"values": ["Alabama", "Alaska"],
|
|
8
|
+
"columnName": "Location",
|
|
9
|
+
"showDropdown": true,
|
|
10
|
+
"usedBy": ["chart-metadata-test", "databite-metadata-test"],
|
|
11
|
+
"tier": 1,
|
|
12
|
+
"type": "datafilter"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"rows": [
|
|
17
|
+
{
|
|
18
|
+
"columns": [
|
|
19
|
+
{ "width": 12, "widget": "legacySharedFilters" }
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"columns": [
|
|
24
|
+
{ "width": 6, "widget": "chart-metadata-test" },
|
|
25
|
+
{ "width": 6, "widget": "databite-metadata-test" }
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"visualizations": {
|
|
30
|
+
"chart-metadata-test": {
|
|
31
|
+
"type": "chart",
|
|
32
|
+
"visualizationType": "Bar",
|
|
33
|
+
"uid": "chart-metadata-test",
|
|
34
|
+
"title": "Amount by Year",
|
|
35
|
+
"description": "Data last updated {{lastUpdated}}",
|
|
36
|
+
"enableMarkupVariables": true,
|
|
37
|
+
"markupVariables": [
|
|
38
|
+
{
|
|
39
|
+
"name": "Last Updated",
|
|
40
|
+
"tag": "{{lastUpdated}}",
|
|
41
|
+
"metadataKey": "lastUpdated",
|
|
42
|
+
"conditions": []
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"xAxis": { "dataKey": "Year" },
|
|
46
|
+
"series": [{ "dataKey": "Amount", "type": "Bar" }],
|
|
47
|
+
"dataKey": "metadata-test-data",
|
|
48
|
+
"theme": "theme-blue"
|
|
49
|
+
},
|
|
50
|
+
"databite-metadata-test": {
|
|
51
|
+
"type": "data-bite",
|
|
52
|
+
"visualizationType": "data-bite",
|
|
53
|
+
"uid": "databite-metadata-test",
|
|
54
|
+
"title": "",
|
|
55
|
+
"subtext": "Source: {{source}}",
|
|
56
|
+
"enableMarkupVariables": true,
|
|
57
|
+
"markupVariables": [
|
|
58
|
+
{
|
|
59
|
+
"name": "Source",
|
|
60
|
+
"tag": "{{source}}",
|
|
61
|
+
"metadataKey": "source",
|
|
62
|
+
"conditions": []
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"dataColumn": "Amount",
|
|
66
|
+
"dataFunction": "Sum",
|
|
67
|
+
"biteStyle": "title",
|
|
68
|
+
"bitePosition": "Left",
|
|
69
|
+
"biteFontSize": 24,
|
|
70
|
+
"fontSize": "medium",
|
|
71
|
+
"dataFormat": { "roundToPlace": 0, "commas": true },
|
|
72
|
+
"dataKey": "metadata-test-data",
|
|
73
|
+
"theme": "theme-orange"
|
|
74
|
+
},
|
|
75
|
+
"legacySharedFilters": {
|
|
76
|
+
"type": "dashboardFilters",
|
|
77
|
+
"visualizationType": "dashboardFilters",
|
|
78
|
+
"sharedFilterIndexes": [0],
|
|
79
|
+
"filterBehavior": "Filter Change",
|
|
80
|
+
"uid": "legacySharedFilters"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"table": { "label": "Data Table", "show": false },
|
|
84
|
+
"data": [],
|
|
85
|
+
"dataFileName": "metadata-test-data",
|
|
86
|
+
"dataFileSourceType": "",
|
|
87
|
+
"dataUrl": "/packages/dashboard/examples/data/data-with-metadata.json",
|
|
88
|
+
"type": "dashboard"
|
|
89
|
+
}
|
package/vite.config.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import GenerateViteConfig from '@cdc/core/generateViteConfig.js'
|
|
2
2
|
import { moduleName } from './package.json'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Dashboard uses is-dashboard-editor instead of is-editor for the padding selector
|
|
5
|
+
const dashboardCss = `
|
|
6
|
+
.cove-visualization.type-dashboard:not(.is-dashboard-editor) {
|
|
7
|
+
padding: 1rem;
|
|
8
|
+
}`
|
|
9
|
+
|
|
10
|
+
export default GenerateViteConfig(moduleName, {}, {}, { css: dashboardCss })
|