@cdc/dashboard 4.26.3 → 4.26.5

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 (151) hide show
  1. package/CONFIG.md +219 -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 +61559 -58048
  6. package/examples/__data__/data-2.json +6 -0
  7. package/examples/__data__/data.json +6 -0
  8. package/examples/dashboard-conditions-filters-incomplete.json +221 -0
  9. package/examples/dashboard-missing-datasets-multi.json +174 -0
  10. package/examples/dashboard-missing-datasets-single.json +121 -0
  11. package/examples/dashboard-multi-dashboard-version-regression.json +146 -0
  12. package/examples/dashboard-shared-filter-row-delete-cleanup.json +186 -0
  13. package/examples/dashboard-stale-dataset-keys.json +181 -0
  14. package/examples/dashboard-tiered-filter-regression.json +190 -0
  15. package/examples/legend-issue.json +1 -1
  16. package/examples/minimal-example.json +34 -0
  17. package/examples/private/cfa-dashboard.json +651 -0
  18. package/examples/private/data-bite-wrap.json +6936 -0
  19. package/examples/private/dengue.json +4640 -0
  20. package/examples/private/link_to_file.json +16662 -0
  21. package/examples/private/multi-dash-fix.json +16963 -0
  22. package/examples/private/versions.json +41612 -0
  23. package/examples/sankey.json +3 -3
  24. package/examples/test-api-filter-reset.json +4 -4
  25. package/examples/tp5-test.json +86 -4
  26. package/examples/us-map-filter-example.json +1074 -0
  27. package/package.json +9 -9
  28. package/src/CdcDashboard.tsx +6 -2
  29. package/src/CdcDashboardComponent.tsx +179 -88
  30. package/src/DashboardCopyPasteContext.test.tsx +33 -0
  31. package/src/DashboardCopyPasteContext.tsx +48 -0
  32. package/src/_stories/Dashboard.EditorRegression.stories.tsx +72 -0
  33. package/src/_stories/Dashboard.Regression.stories.tsx +196 -0
  34. package/src/_stories/Dashboard.Zoom.stories.tsx +88 -0
  35. package/src/_stories/Dashboard.smoke.stories.tsx +33 -0
  36. package/src/_stories/Dashboard.stories.tsx +337 -2
  37. package/src/_stories/FilteredTextMigrationComparison.stories.tsx +87 -0
  38. package/src/_stories/_mock/dashboard-data-driven-colors.json +171 -0
  39. package/src/_stories/_mock/tp5-test.json +86 -5
  40. package/src/components/Column.test.tsx +176 -0
  41. package/src/components/Column.tsx +214 -13
  42. package/src/components/DashboardConditionModal.test.tsx +420 -0
  43. package/src/components/DashboardConditionModal.tsx +367 -0
  44. package/src/components/DashboardConditionSummary.tsx +59 -0
  45. package/src/components/DashboardEditors.tsx +23 -0
  46. package/src/components/DashboardFilters/DashboardFilters.test.tsx +267 -0
  47. package/src/components/DashboardFilters/DashboardFilters.tsx +193 -172
  48. package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.test.tsx +164 -0
  49. package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +46 -6
  50. package/src/components/DashboardFilters/DashboardFiltersEditor/components/APIModal.tsx +5 -3
  51. package/src/components/DashboardFilters/DashboardFiltersEditor/components/DeleteFilterModal.tsx +59 -58
  52. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.test.tsx +304 -0
  53. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +43 -36
  54. package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +2 -2
  55. package/src/components/DashboardFilters/DashboardFiltersWrapper.test.tsx +142 -0
  56. package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +32 -27
  57. package/src/components/DashboardFilters/dashboardfilter.styles.css +42 -27
  58. package/src/components/DataDesignerModal.tsx +2 -1
  59. package/src/components/ExpandCollapseButtons.tsx +6 -4
  60. package/src/components/Grid.tsx +12 -7
  61. package/src/components/Header/Header.tsx +36 -17
  62. package/src/components/MultiConfigTabs/MultiConfigTabs.tsx +141 -140
  63. package/src/components/Row.test.tsx +228 -0
  64. package/src/components/Row.tsx +104 -28
  65. package/src/components/VisualizationRow.test.tsx +396 -0
  66. package/src/components/VisualizationRow.tsx +177 -51
  67. package/src/components/VisualizationsPanel/VisualizationsPanel.test.tsx +49 -0
  68. package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +14 -13
  69. package/src/components/Widget/Widget.test.tsx +218 -0
  70. package/src/components/Widget/Widget.tsx +123 -20
  71. package/src/components/Widget/widget.styles.css +58 -14
  72. package/src/components/dashboard-condition-modal.css +76 -0
  73. package/src/components/dashboard-condition-summary.css +87 -0
  74. package/src/data/initial-state.js +1 -0
  75. package/src/helpers/addValuesToDashboardFilters.ts +3 -5
  76. package/src/helpers/addVisualization.ts +17 -4
  77. package/src/helpers/cloneDashboardWidget.ts +127 -0
  78. package/src/helpers/dashboardColumnWidgets.ts +99 -0
  79. package/src/helpers/dashboardConditionUi.ts +47 -0
  80. package/src/helpers/dashboardConditions.ts +200 -0
  81. package/src/helpers/dashboardFilterTargets.ts +156 -0
  82. package/src/helpers/filterData.ts +4 -9
  83. package/src/helpers/filterVisibility.ts +20 -0
  84. package/src/helpers/formatConfigBeforeSave.ts +2 -2
  85. package/src/helpers/getFilteredData.ts +18 -5
  86. package/src/helpers/getUpdateConfig.ts +43 -12
  87. package/src/helpers/getVizRowColumnLocator.ts +11 -1
  88. package/src/helpers/iconHash.tsx +9 -3
  89. package/src/helpers/mapDataToConfig.ts +31 -29
  90. package/src/helpers/reloadURLHelpers.ts +25 -5
  91. package/src/helpers/removeDashboardFilter.ts +33 -33
  92. package/src/helpers/tests/addVisualization.test.ts +53 -9
  93. package/src/helpers/tests/cloneDashboardWidget.test.ts +136 -0
  94. package/src/helpers/tests/dashboardColumnWidgets.test.ts +99 -0
  95. package/src/helpers/tests/dashboardConditionUi.test.ts +41 -0
  96. package/src/helpers/tests/dashboardConditions.test.ts +428 -0
  97. package/src/helpers/tests/formatConfigBeforeSave.test.ts +51 -0
  98. package/src/helpers/tests/getFilteredData.test.ts +265 -86
  99. package/src/helpers/tests/getUpdateConfig.test.ts +338 -0
  100. package/src/helpers/tests/reloadURLHelpers.test.ts +394 -238
  101. package/src/index.tsx +6 -3
  102. package/src/scss/grid.scss +281 -22
  103. package/src/scss/main.scss +215 -64
  104. package/src/store/dashboard.actions.ts +17 -4
  105. package/src/store/dashboard.reducer.test.ts +538 -0
  106. package/src/store/dashboard.reducer.ts +136 -22
  107. package/src/test/CdcDashboard.test.jsx +24 -0
  108. package/src/test/CdcDashboard.test.tsx +148 -0
  109. package/src/test/CdcDashboardComponent.test.tsx +935 -2
  110. package/src/types/ConfigRow.ts +15 -0
  111. package/src/types/DashboardFilters.ts +4 -0
  112. package/src/types/SharedFilter.ts +2 -0
  113. package/tests/fixtures/dashboard-config-with-metadata.json +1 -1
  114. package/dist/cdcdashboard-vr9HZwRt.es.js +0 -6
  115. package/examples/DEV-6574.json +0 -2224
  116. package/examples/api-dashboard-data.json +0 -272
  117. package/examples/api-dashboard-years.json +0 -11
  118. package/examples/api-geographies-data.json +0 -11
  119. package/examples/chart-data.json +0 -5409
  120. package/examples/custom/css/respiratory.css +0 -236
  121. package/examples/custom/js/respiratory.js +0 -242
  122. package/examples/default-data.json +0 -368
  123. package/examples/default-filter-control.json +0 -209
  124. package/examples/default-multi-dataset-shared-filter.json +0 -1729
  125. package/examples/default-multi-dataset.json +0 -506
  126. package/examples/ed-visits-county-file.json +0 -402
  127. package/examples/filters/Alabama.json +0 -72
  128. package/examples/filters/Alaska.json +0 -1737
  129. package/examples/filters/Arkansas.json +0 -4713
  130. package/examples/filters/California.json +0 -212
  131. package/examples/filters/Colorado.json +0 -1500
  132. package/examples/filters/Connecticut.json +0 -559
  133. package/examples/filters/Delaware.json +0 -63
  134. package/examples/filters/DistrictofColumbia.json +0 -63
  135. package/examples/filters/Florida.json +0 -4217
  136. package/examples/filters/States.json +0 -146
  137. package/examples/state-level.json +0 -90136
  138. package/examples/state-points.json +0 -10474
  139. package/examples/temp-example-data.json +0 -130
  140. package/examples/test-dashboard-simple.json +0 -503
  141. package/examples/test-example.json +0 -752
  142. package/examples/test-file.json +0 -147
  143. package/examples/test.json +0 -752
  144. package/examples/testing.json +0 -94456
  145. /package/examples/{data → __data__}/data-with-metadata.json +0 -0
  146. /package/examples/{legend-issue-data.json → __data__/legend-issue-data.json} +0 -0
  147. /package/examples/api-test/{categories.json → __data__/categories.json} +0 -0
  148. /package/examples/api-test/{chart-data.json → __data__/chart-data.json} +0 -0
  149. /package/examples/api-test/{topics.json → __data__/topics.json} +0 -0
  150. /package/examples/api-test/{years.json → __data__/years.json} +0 -0
  151. /package/src/_stories/{Dashboard.Pages.stories.tsx → Dashboard.Pages.smoke.stories.tsx} +0 -0
@@ -2,6 +2,8 @@
2
2
 
3
3
  $blue-light: #8bc6f7;
4
4
  $red: #f74242;
5
+ $copy-paste-orange: #b86f33;
6
+ $copy-paste-orange-bg: #fff7ef;
5
7
 
6
8
  .layout-container {
7
9
  display: flex;
@@ -102,17 +104,29 @@ $red: #f74242;
102
104
  }
103
105
 
104
106
  .row-menu__btn {
107
+ align-items: center;
105
108
  background-color: #c2c2c2;
106
109
  border-radius: 0.2em 0.2em 0 0;
110
+ justify-content: center;
111
+ min-height: 0;
107
112
  outline: none;
108
113
  transition: background-color 300ms cubic-bezier(0.16, 1, 0.3, 1);
109
114
  padding: 0.2em 0.3em;
110
115
  display: flex;
111
116
  fill: #fff;
117
+ box-shadow: none;
118
+ transform: none;
119
+ line-height: 1;
112
120
 
113
121
  + .row-menu__btn {
114
122
  margin-left: 0.2em;
115
123
  }
124
+
125
+ &:hover:not(:disabled),
126
+ &:active:not(:disabled) {
127
+ box-shadow: none;
128
+ transform: none;
129
+ }
116
130
  }
117
131
 
118
132
  .row-menu__btn-disabled {
@@ -131,11 +145,47 @@ $red: #f74242;
131
145
  align-items: center;
132
146
  position: relative;
133
147
  height: 180px;
134
- margin-left: 0.5rem;
135
- margin-right: 0.5rem;
136
148
  background-color: transparent;
137
149
  border: 2px dashed #c2c2c2;
138
150
  flex: 1 1 auto;
151
+ min-width: 0;
152
+
153
+ &:hover {
154
+ border-color: color.adjust(#c2c2c2, $lightness: -20%);
155
+ }
156
+
157
+ &.column--populated {
158
+ background: none;
159
+ border: none;
160
+ }
161
+
162
+ &.column--paste-ready {
163
+ background-color: $copy-paste-orange-bg;
164
+ border-color: $copy-paste-orange;
165
+ cursor: copy;
166
+ }
167
+ }
168
+
169
+ .builder-column--conditional {
170
+ align-items: stretch;
171
+ background: none;
172
+ border: none;
173
+ flex-direction: column;
174
+ gap: 0.75rem;
175
+ height: auto;
176
+ justify-content: flex-start;
177
+ }
178
+
179
+ .builder-column--conditional__slot {
180
+ align-items: center;
181
+ background-color: transparent;
182
+ border: 2px dashed #c2c2c2;
183
+ display: flex;
184
+ flex: 0 0 180px;
185
+ justify-content: center;
186
+ min-height: 180px;
187
+ position: relative;
188
+ width: 100%;
139
189
 
140
190
  &:hover {
141
191
  border-color: color.adjust(#c2c2c2, $lightness: -20%);
@@ -145,6 +195,12 @@ $red: #f74242;
145
195
  background: none;
146
196
  border: none;
147
197
  }
198
+
199
+ &.column--paste-ready {
200
+ background-color: $copy-paste-orange-bg;
201
+ border-color: $copy-paste-orange;
202
+ cursor: copy;
203
+ }
148
204
  }
149
205
 
150
206
  .column--drop {
@@ -179,6 +235,20 @@ $red: #f74242;
179
235
  color: var(--mediumGray);
180
236
  }
181
237
 
238
+ .builder-column__hint {
239
+ display: block;
240
+ margin-top: 0.25rem;
241
+ font-size: 13px;
242
+ line-height: 15px;
243
+ }
244
+
245
+ .column--paste-ready .builder-column__text {
246
+ max-width: 16rem;
247
+ overflow-wrap: normal;
248
+ white-space: normal;
249
+ width: calc(100% - 2rem);
250
+ }
251
+
182
252
  .widget {
183
253
  display: flex;
184
254
  height: 100%;
@@ -192,6 +262,7 @@ $red: #f74242;
192
262
  padding: 0;
193
263
  position: relative;
194
264
  cursor: move;
265
+ overflow: hidden;
195
266
 
196
267
  &:hover {
197
268
  $lightGray: #c7c7c7;
@@ -208,6 +279,15 @@ $red: #f74242;
208
279
  }
209
280
  }
210
281
 
282
+ &.widget--copied-source {
283
+ border-color: $copy-paste-orange;
284
+ box-shadow: 0 0 0 2px $copy-paste-orange, 0 0 0 5px rgba(184, 111, 51, 0.18);
285
+ }
286
+
287
+ &.widget--copied-source:hover {
288
+ border-color: $copy-paste-orange;
289
+ }
290
+
211
291
  .drag-icon,
212
292
  .drag-icon svg {
213
293
  fill: var(--lightGray);
@@ -221,6 +301,42 @@ $red: #f74242;
221
301
  }
222
302
  }
223
303
 
304
+ .widget__copied-badge {
305
+ align-items: center;
306
+ background: $copy-paste-orange-bg;
307
+ border: 1px solid $copy-paste-orange;
308
+ border-radius: 999px;
309
+ color: $copy-paste-orange;
310
+ cursor: pointer;
311
+ display: inline-flex;
312
+ font-size: 0.75rem;
313
+ font-weight: 600;
314
+ gap: 0.35rem;
315
+ left: 0.5rem;
316
+ line-height: 1;
317
+ padding: 0.25rem 0.45rem 0.25rem 0.55rem;
318
+ position: absolute;
319
+ top: 0.5rem;
320
+ z-index: 2;
321
+
322
+ svg {
323
+ display: block;
324
+ height: 0.65rem;
325
+ margin: 0;
326
+ width: 0.65rem;
327
+ }
328
+
329
+ &:hover,
330
+ &:focus {
331
+ background: color.adjust($copy-paste-orange-bg, $lightness: -3%);
332
+ outline: none;
333
+ }
334
+
335
+ &:focus-visible {
336
+ box-shadow: 0 0 0 2px #fff, 0 0 0 4px $copy-paste-orange;
337
+ }
338
+ }
339
+
224
340
  .widget__media {
225
341
  display: flex;
226
342
  justify-content: center;
@@ -251,12 +367,97 @@ $red: #f74242;
251
367
  flex-direction: column;
252
368
  align-items: center;
253
369
  justify-content: center;
370
+ min-height: 0;
371
+ overflow: hidden;
254
372
 
255
373
  svg {
256
374
  margin-bottom: 0.5em;
257
375
  }
258
376
  }
259
377
 
378
+ .widget--in-row .widget__content--with-menu:not(.widget__content--has-condition) {
379
+ justify-content: flex-start;
380
+ padding-top: 2.75rem;
381
+ }
382
+
383
+ .widget--in-row .widget__content--with-menu.widget__content--has-condition {
384
+ justify-content: flex-start;
385
+ padding-top: 2rem;
386
+ }
387
+
388
+ .widget--in-row .widget__summary {
389
+ align-items: center;
390
+ display: inline-flex;
391
+ gap: 0.75rem;
392
+ justify-content: center;
393
+ margin-bottom: 0.75rem;
394
+ max-width: 100%;
395
+ min-width: 0;
396
+ }
397
+
398
+ .widget--in-row .widget__type-icon {
399
+ align-items: center;
400
+ display: inline-flex;
401
+ flex: 0 0 auto;
402
+ height: 42px;
403
+ justify-content: center;
404
+ width: 42px;
405
+
406
+ svg {
407
+ display: block;
408
+ flex: 0 0 auto;
409
+ height: 42px;
410
+ margin: 0;
411
+ max-height: 42px;
412
+ max-width: 42px;
413
+ width: 42px;
414
+ }
415
+ }
416
+
417
+ .widget--in-row .widget__summary-text {
418
+ display: flex;
419
+ flex: 1 1 auto;
420
+ flex-direction: column;
421
+ font-size: 16px;
422
+ justify-content: center;
423
+ line-height: 1.2;
424
+ min-height: 42px;
425
+ min-width: 0;
426
+ text-align: left;
427
+ }
428
+
429
+ .widget--in-row .widget__type-label,
430
+ .widget--in-row .widget__title {
431
+ font-size: 16px;
432
+ line-height: 1.2;
433
+ overflow-wrap: break-word;
434
+ }
435
+
436
+ .widget--in-row .widget__title {
437
+ display: block;
438
+ flex: 0 1 auto;
439
+ max-width: 100%;
440
+ min-height: 0;
441
+ overflow: hidden;
442
+ text-align: center;
443
+ }
444
+
445
+ .widget--in-row .widget__type-label {
446
+ font-weight: 600;
447
+ }
448
+
449
+ .widget-menu .cove-button.btn-configure.btn-configure--copy.is-active {
450
+ background: $copy-paste-orange-bg !important;
451
+ box-shadow: inset 0 0 0 1px $copy-paste-orange;
452
+ color: $copy-paste-orange;
453
+ }
454
+
455
+ .widget-menu .cove-button.btn-configure.btn-configure--copy.is-active:hover:not(:disabled),
456
+ .widget-menu .cove-button.btn-configure.btn-configure--copy.is-active:active:not(:disabled) {
457
+ background: color.adjust($copy-paste-orange-bg, $lightness: -3%) !important;
458
+ box-shadow: inset 0 0 0 1px $copy-paste-orange;
459
+ }
460
+
260
461
  .widget-card {
261
462
  position: relative;
262
463
  display: flex;
@@ -276,21 +477,67 @@ $red: #f74242;
276
477
  }
277
478
  }
278
479
 
279
- .btn--fluid {
280
- @extend .btn;
281
- width: 100%;
282
- text-align: center;
283
- }
284
-
285
480
  .builder-row {
286
481
  position: relative;
287
482
 
483
+ .builder-row__label {
484
+ align-items: center;
485
+ color: var(--darkGray);
486
+ display: inline-flex;
487
+ font-size: 16px;
488
+ left: 1rem;
489
+ line-height: 1;
490
+ min-height: 28px;
491
+ position: absolute;
492
+ top: 0.375rem;
493
+ }
494
+
288
495
  .btn-configure-row {
289
- background: none;
290
- display: block;
496
+ align-items: center;
497
+ background: transparent !important;
498
+ border: 0;
499
+ border-radius: 999px;
500
+ box-shadow: none;
501
+ color: var(--mediumGray);
502
+ display: inline-flex;
503
+ height: 28px;
504
+ justify-content: center;
505
+ line-height: 1;
506
+ min-height: 28px;
507
+ min-width: 28px;
508
+ padding: 4px;
291
509
  position: absolute;
292
- right: 1em;
293
- top: 0;
510
+ right: 1rem;
511
+ top: 0.375rem;
512
+ transform: none;
513
+ width: 28px;
514
+
515
+ &:hover:not(:disabled),
516
+ &:active:not(:disabled) {
517
+ background: rgba(0, 94, 170, 0.08) !important;
518
+ box-shadow: none;
519
+ transform: none;
520
+ }
521
+
522
+ &.btn-configure-row--data {
523
+ right: calc(1rem + 28px + 6px);
524
+ }
525
+
526
+ &.btn-configure-row--condition {
527
+ right: 1rem;
528
+ }
529
+
530
+ &.is-active {
531
+ background: var(--dashboard-condition-active-blue-bg, #f2f7fb) !important;
532
+ box-shadow: inset 0 0 0 1px var(--dashboard-condition-active-blue, var(--blue));
533
+ color: var(--dashboard-condition-active-blue, var(--blue));
534
+ }
535
+
536
+ &.is-active:hover:not(:disabled),
537
+ &.is-active:active:not(:disabled) {
538
+ background: var(--dashboard-condition-active-blue-bg-hover, #e6eff7) !important;
539
+ box-shadow: inset 0 0 0 1px var(--dashboard-condition-active-blue, var(--blue));
540
+ }
294
541
  }
295
542
 
296
543
  .footnotes {
@@ -306,7 +553,7 @@ $red: #f74242;
306
553
  }
307
554
  }
308
555
 
309
- padding: 2em 1em 1em;
556
+ padding: 2.125rem 1em 1em;
310
557
  border: 1px solid #c2c2c2;
311
558
  transition: border 300ms cubic-bezier(0.16, 1, 0.3, 1);
312
559
  background-color: #f2f2f2;
@@ -319,19 +566,16 @@ $red: #f74242;
319
566
  .column-container {
320
567
  display: flex;
321
568
  flex-flow: row;
569
+ gap: 1rem;
322
570
  width: 100%;
323
571
  }
324
572
 
325
573
  .widget__content {
326
- padding: 0 2em;
327
-
328
- > svg {
329
- width: 100%;
330
- height: auto;
331
- max-width: 100px;
332
- max-height: 80px;
333
- flex-grow: 1;
334
- }
574
+ padding: 0 1em;
575
+ }
576
+
577
+ .widget--in-row .widget__content--with-menu:not(.widget__content--has-condition) {
578
+ padding-top: 2rem;
335
579
  }
336
580
 
337
581
  &:hover {
@@ -351,3 +595,18 @@ $red: #f74242;
351
595
  border-color: var(--blue);
352
596
  }
353
597
  }
598
+
599
+ .row-menu__btn svg,
600
+ .builder-row .btn-configure-row svg {
601
+ display: block;
602
+ height: 1.1em;
603
+ margin-bottom: 0;
604
+ top: 0;
605
+ vertical-align: middle;
606
+ width: 1.1em;
607
+ }
608
+
609
+ .builder-row .btn-configure-row--condition svg {
610
+ transform: scale(1.15);
611
+ transform-origin: center;
612
+ }