@cdc/core 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/.claude/agents/qa-test-developer.md +126 -0
- package/CLAUDE.local.md +67 -0
- package/LICENSE +201 -0
- package/_stories/Gallery.Charts.stories.tsx +35 -42
- package/_stories/Gallery.DataBite.stories.tsx +15 -8
- package/_stories/Gallery.Maps.stories.tsx +37 -28
- package/_stories/Gallery.WaffleChart.stories.tsx +1 -1
- package/_stories/PageART.stories.tsx +5 -4
- package/_stories/PageBRFSS.stories.tsx +21 -16
- package/_stories/PageCancerRegistries.stories.tsx +15 -15
- package/_stories/PageEasternEquineEncephalitis.stories.tsx +33 -19
- package/_stories/PageExcessiveAlcoholUse.stories.tsx +148 -143
- package/_stories/PageMaternalMortality.stories.tsx +5 -4
- package/_stories/PageOralHealth.stories.tsx +15 -10
- package/_stories/PageRespiratory.stories.tsx +4 -4
- package/_stories/PageSmokingTobacco.stories.tsx +15 -10
- package/_stories/PageStateDiabetesProfiles.stories.tsx +15 -10
- package/_stories/PageWastewater.stories.tsx +44 -30
- package/_stories/VegaImport.stories.tsx +401 -0
- package/_stories/vega-fixtures/bars-with-line.json +444 -0
- package/_stories/vega-fixtures/bars.json +58 -0
- package/_stories/vega-fixtures/combo-bar-rolling-mean.json +88 -0
- package/_stories/vega-fixtures/combo.json +68 -0
- package/_stories/vega-fixtures/grouped-horizontal-bars.json +83 -0
- package/_stories/vega-fixtures/grouped-horizontal-bars2.json +231 -0
- package/_stories/vega-fixtures/horizontal-bar.json +427 -0
- package/_stories/vega-fixtures/horizontal-bars-with-bad-colors.json +197 -0
- package/_stories/vega-fixtures/horizontal-bars2.json +58 -0
- package/_stories/vega-fixtures/lines.json +227 -0
- package/_stories/vega-fixtures/measles-bars.json +348 -0
- package/_stories/vega-fixtures/measles-map.json +11101 -0
- package/_stories/vega-fixtures/measles-stacked-bars.json +2147 -0
- package/_stories/vega-fixtures/multi-dataset.json +255 -0
- package/_stories/vega-fixtures/no-data.json +14 -0
- package/_stories/vega-fixtures/pie-chart.json +94 -0
- package/_stories/vega-fixtures/repeat-spec.json +47 -0
- package/_stories/vega-fixtures/stacked-area.json +222 -0
- package/_stories/vega-fixtures/stacked-bar-with-rect.json +3412 -0
- package/_stories/vega-fixtures/stacked-bars-with-line.json +364 -0
- package/_stories/vega-fixtures/stacked-bars.json +212 -0
- package/_stories/vega-fixtures/stacked-horizontal-bars.json +140 -0
- package/_stories/vega-fixtures/warning-combo.json +59 -0
- package/_stories/vega-fixtures/warning-scatter-and-line.json +1182 -0
- package/assets/callout-flag.svg +7 -0
- package/assets/icon-chart-area.svg +1 -0
- package/assets/icon-chart-radar.svg +23 -0
- package/assets/logo2.svg +31 -0
- package/components/AdvancedEditor/EmbedEditor.tsx +270 -38
- package/components/Alert/components/Alert.styles.css +2 -2
- package/components/ComboBox/combobox.styles.css +48 -48
- package/components/CustomColorsEditor/CustomColorsEditor.css +53 -53
- package/components/CustomColorsEditor/CustomColorsEditor.tsx +3 -10
- package/components/DataTable/DataTable.tsx +46 -18
- package/components/DataTable/DataTableStandAlone.tsx +1 -0
- package/components/DataTable/components/ChartHeader.tsx +21 -12
- package/components/DataTable/components/MapHeader.tsx +34 -28
- package/components/DataTable/components/SortIcon/sort-icon.css +5 -5
- package/components/DataTable/data-table.css +50 -52
- package/components/DataTable/helpers/applyCustomOrder.ts +17 -0
- package/components/DataTable/helpers/getChartCellValue.ts +10 -7
- package/components/DataTable/helpers/getMapDataTableColumnKeys.ts +22 -0
- package/components/DataTable/helpers/getSeriesName.ts +6 -0
- package/components/DataTable/helpers/mapCellMatrix.tsx +33 -23
- package/components/DataTable/helpers/tests/mapCellMatrix.test.ts +33 -0
- package/components/DownloadButton.tsx +14 -6
- package/components/EditorPanel/ColumnsEditor.tsx +38 -31
- package/components/EditorPanel/CustomSortOrder.tsx +94 -0
- package/components/EditorPanel/DataTableEditor.tsx +139 -23
- package/components/EditorPanel/EditorPanel.styles.css +71 -71
- package/components/EditorPanel/EditorPanel.tsx +3 -8
- package/components/EditorPanel/EditorPanelDispatch.tsx +4 -4
- package/components/EditorPanel/FootnotesEditor.tsx +2 -2
- package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +21 -12
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +16 -10
- package/components/EditorPanel/VizFilterEditor/components/FilterOrder.tsx +33 -29
- package/components/EditorPanel/components/MarkupVariablesEditor.tsx +160 -106
- package/components/EditorPanel/components/PanelMarkup.tsx +5 -1
- package/{styles/v2/components → components/EditorPanel}/editor.scss +76 -22
- package/components/EditorPanel/sections/StyleTreatmentSection.tsx +99 -0
- package/components/EditorPanel/sections/VisualSection.tsx +11 -0
- package/components/EditorWrapper/editor-wrapper.style.css +1 -1
- package/components/Filters/Filters.tsx +3 -5
- package/components/Filters/components/Tabs.tsx +19 -7
- package/{styles → components/Filters}/filters.scss +3 -3
- package/components/Footnotes/FootnotesStandAlone.tsx +4 -2
- package/components/HeaderThemeSelector/HeaderThemeSelector.css +61 -5
- package/components/Layout/components/Responsive.tsx +14 -6
- package/components/Layout/components/Sidebar/components/Sidebar.tsx +1 -1
- package/components/Layout/components/Sidebar/components/sidebar.styles.scss +14 -20
- package/components/Layout/components/Visualization/index.tsx +50 -38
- package/components/Layout/components/Visualization/visualizations.scss +232 -15
- package/components/Layout/components/VisualizationContainer.test.tsx +67 -0
- package/components/Layout/components/VisualizationContainer.tsx +37 -0
- package/components/Layout/components/VisualizationContent.test.tsx +182 -0
- package/components/Layout/components/VisualizationContent.tsx +75 -0
- package/components/Layout/index.tsx +5 -5
- package/components/Layout/styles/editor-utils.scss +3 -3
- package/components/Layout/styles/editor.scss +4 -4
- package/components/Legend/Legend.Gradient.tsx +7 -1
- package/components/Loader/loader.styles.css +2 -2
- package/components/Loading.jsx +1 -1
- package/components/MediaControls.tsx +10 -3
- package/components/MultiSelect/multiselect.styles.css +19 -19
- package/components/NestedDropdown/nesteddropdown.styles.css +15 -15
- package/components/PaletteSelector/PaletteSelector.css +15 -15
- package/components/RichTooltip/richTooltip.css +6 -6
- package/components/Table/table.styles.css +2 -2
- package/components/Waiting.tsx +1 -1
- package/components/_stories/CustomColorsEditor.stories.tsx +37 -0
- package/components/_stories/DataTable.stories.tsx +1 -0
- package/components/_stories/Filters.stories.tsx +1 -1
- package/components/_stories/styles.scss +0 -1
- package/components/elements/Button.jsx +1 -1
- package/components/elements/Card.jsx +1 -1
- package/{styles/v2/components → components/elements}/button.scss +9 -8
- package/components/inputs/InputCheckbox.jsx +1 -1
- package/components/inputs/InputSelect.tsx +1 -1
- package/components/inputs/InputText.jsx +1 -1
- package/components/inputs/InputToggle.tsx +1 -1
- package/{styles/v2/components/input → components/inputs}/_input-check-radio.scss +2 -2
- package/{styles/v2/components/input → components/inputs}/_input-group.scss +3 -3
- package/{styles/v2/components/input → components/inputs}/_input-slider.scss +2 -2
- package/{styles/v2/components/input → components/inputs}/_input.scss +5 -5
- package/{styles/v2/components/input → components/inputs}/index.scss +2 -2
- package/{styles → components}/loading.scss +1 -1
- package/components/managers/DataDesigner.tsx +1 -1
- package/{styles/v2/components → components/managers}/data-designer.scss +6 -7
- package/components/ui/Accordion.jsx +1 -1
- package/components/ui/Icon.tsx +1 -1
- package/components/ui/LoadSpin.jsx +1 -1
- package/components/ui/Modal.jsx +1 -1
- package/components/ui/Overlay.jsx +1 -1
- package/components/ui/Title/index.test.tsx +34 -0
- package/components/ui/Title/index.tsx +24 -7
- package/components/ui/Title/title.styles.css +119 -25
- package/components/ui/Tooltip.tsx +1 -1
- package/components/ui/_stories/Title.stories.tsx +1 -1
- package/{styles/v2/components → components/ui}/accordion.scss +3 -3
- package/components/ui/accordion.styles.css +11 -11
- package/{styles/v2/components → components/ui}/modal.scss +2 -2
- package/{styles/v2/components → components/ui}/overlay.scss +6 -6
- package/{styles/v2/components → components}/ui/tooltip.scss +1 -1
- package/{styles → components}/waiting.scss +9 -3
- package/data/colorPalettes.ts +18 -5
- package/data/mapColorPalettes.ts +10 -0
- package/devTemplate/dev.js +285 -0
- package/devTemplate/index.html +30 -0
- package/devTemplate/preview.html +1503 -0
- package/devTemplate/sidebar.css +151 -0
- package/dist/cove-main.css +2530 -3901
- package/dist/cove-main.css.map +1 -1
- package/generateViteConfig.js +111 -2
- package/helpers/DataTransform.ts +1 -5
- package/helpers/backfillDefaults.ts +35 -0
- package/helpers/constants.ts +12 -0
- package/helpers/cove/date.ts +64 -3
- package/helpers/cove/number.ts +29 -15
- package/helpers/cove/string.ts +29 -0
- package/helpers/coveUpdateWorker.ts +14 -8
- package/helpers/displayDataAsText.ts +1 -1
- package/helpers/embed/embedCodeGenerator.ts +80 -0
- package/helpers/embed/embedHelper.js +169 -0
- package/helpers/embed/filterUtils.ts +121 -0
- package/helpers/embed/index.ts +17 -0
- package/helpers/embed/urlValidation.ts +119 -0
- package/helpers/extractDataAndMetadata.ts +20 -0
- package/helpers/fetchRemoteData.ts +14 -8
- package/helpers/filterVizData.ts +6 -1
- package/helpers/getFileExtension.ts +0 -6
- package/helpers/labelHash.ts +9 -0
- package/helpers/markupProcessor.ts +56 -38
- package/helpers/metrics/types.ts +3 -0
- package/helpers/palettes/colorDistributions.ts +1 -1
- package/helpers/palettes/utils.ts +12 -12
- package/helpers/parseCsvWithQuotes.ts +15 -14
- package/helpers/prepareScreenshot.ts +33 -10
- package/helpers/testing.ts +44 -0
- package/helpers/tests/DataTransform.test.ts +125 -0
- package/helpers/tests/abbreviateNumber.test.ts +59 -0
- package/helpers/tests/backfillDefaults.test.ts +253 -0
- package/helpers/tests/date.test.ts +110 -0
- package/helpers/tests/extractDataAndMetadata.test.ts +93 -0
- package/helpers/tests/markupProcessor.test.ts +315 -124
- package/helpers/tests/number.test.ts +42 -0
- package/helpers/tests/prepareScreenshot.test.ts +28 -28
- package/helpers/tests/testStandaloneBuild.ts +36 -26
- package/helpers/tests/useDataVizClasses.test.ts +66 -0
- package/helpers/tests/visualizationWrapperUsage.test.ts +57 -0
- package/helpers/useDataVizClasses.ts +13 -7
- package/helpers/vegaConfig.ts +1 -1
- package/helpers/vegaConfigImport.ts +160 -0
- package/helpers/ver/4.24.4.ts +24 -0
- package/helpers/ver/4.26.1.ts +1 -1
- package/helpers/ver/4.26.2.ts +84 -0
- package/helpers/ver/4.26.3.ts +44 -0
- package/helpers/ver/4.26.4.ts +31 -0
- package/helpers/ver/tests/4.26.1.test.ts +105 -0
- package/helpers/ver/tests/4.26.2.test.ts +298 -0
- package/helpers/ver/tests/4.26.3.test.ts +168 -0
- package/helpers/ver/tests/4.26.4.test.ts +88 -0
- package/helpers/ver/tests/coveUpdateWorker.test.ts +57 -0
- package/helpers/viewports.ts +2 -0
- package/package.json +27 -32
- package/styles/_global.scss +7 -7
- package/styles/_reset.scss +2 -2
- package/styles/{v2/base → base}/_file-selector.scss +4 -4
- package/styles/{v2/base → base}/_general.scss +2 -4
- package/styles/{v2/base → base}/index.scss +1 -1
- package/styles/base.scss +107 -165
- package/styles/cove-main.scss +3 -6
- package/styles/layout/_component.scss +110 -0
- package/styles/{v2/layout → layout}/_data-table.scss +7 -7
- package/styles/layout/_wrapper-padding.scss +27 -0
- package/styles/{v2/main.scss → main.scss} +3 -1
- package/styles/{v2/themes → themes}/_color-definitions.scss +46 -41
- package/styles/{_accessibility.scss → utils/_accessibility.scss} +1 -1
- package/styles/{v2/utils → utils}/_grid.scss +8 -3
- package/styles/{_global-variables.scss → utils/_properties.scss} +133 -112
- package/styles/{v2/utils → utils}/index.scss +2 -1
- package/types/Annotation.ts +10 -11
- package/types/Axis.ts +2 -0
- package/types/ComponentStyles.ts +1 -0
- package/types/ConfigureData.ts +1 -0
- package/types/General.ts +2 -0
- package/types/MarkupInclude.ts +1 -0
- package/types/MarkupVariable.ts +2 -1
- package/types/Palette.ts +22 -0
- package/types/Table.ts +9 -0
- package/types/Visualization.ts +7 -0
- package/_stories/StoryRenderingTests.stories.tsx +0 -164
- package/helpers/embedCodeGenerator.ts +0 -109
- package/styles/_common-components.css +0 -73
- package/styles/_variables.scss +0 -63
- package/styles/v2/layout/_component.scss +0 -21
- package/styles/v2/utils/_variables.scss +0 -9
- package/{styles/v2/components/card.scss → components/elements/card.css} +2 -2
- /package/{styles/v2/components → components/ui}/icon.scss +0 -0
- /package/{styles/v2/components → components/ui}/loadspin.scss +0 -0
- /package/styles/{v2/base → base}/_heading.scss +0 -0
- /package/styles/{v2/base → base}/_reset.scss +0 -0
- /package/styles/{v2/layout → layout}/_alert.scss +0 -0
- /package/styles/{v2/layout → layout}/_progression.scss +0 -0
- /package/styles/{v2/layout → layout}/_tooltip.scss +0 -0
- /package/styles/{v2/layout → layout}/index.scss +0 -0
- /package/styles/{v2/themes → themes}/index.scss +0 -0
- /package/styles/{v2/utils → utils}/_align.scss +0 -0
- /package/styles/{v2/utils → utils}/_animations.scss +0 -0
- /package/styles/{v2/utils → utils}/_breakpoints.scss +0 -0
- /package/styles/{v2/utils → utils}/_mixins.scss +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Vega-to-COVE conversion helper for stories.
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
convertVegaConfig,
|
|
6
|
+
getVegaConfigType,
|
|
7
|
+
getVegaErrors,
|
|
8
|
+
getVegaWarnings,
|
|
9
|
+
isVegaConfig,
|
|
10
|
+
parseVegaConfig
|
|
11
|
+
} from './vegaConfig'
|
|
12
|
+
|
|
13
|
+
/** Chart-type "button" definitions used to seed new COVE configs. */
|
|
14
|
+
const buttons = [
|
|
15
|
+
{
|
|
16
|
+
id: 1,
|
|
17
|
+
category: 'Charts',
|
|
18
|
+
label: 'Bar',
|
|
19
|
+
type: 'chart',
|
|
20
|
+
subType: 'Bar',
|
|
21
|
+
orientation: 'vertical',
|
|
22
|
+
barThickness: '0.37',
|
|
23
|
+
visualizationSubType: 'regular',
|
|
24
|
+
xAxis: { type: 'categorical', size: 75, maxTickRotation: 45, labelOffset: 0 },
|
|
25
|
+
content: 'Use bars to show comparisons between data categories.'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: 3,
|
|
29
|
+
category: 'Charts',
|
|
30
|
+
label: 'Combo Chart',
|
|
31
|
+
type: 'chart',
|
|
32
|
+
subType: 'Combo',
|
|
33
|
+
orientation: 'vertical',
|
|
34
|
+
content: 'Use bars to show comparisons between data categories.'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 4,
|
|
38
|
+
category: 'Charts',
|
|
39
|
+
label: 'Line',
|
|
40
|
+
type: 'chart',
|
|
41
|
+
subType: 'Line',
|
|
42
|
+
orientation: 'vertical',
|
|
43
|
+
content: 'Present one or more data trends over time.'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 6,
|
|
47
|
+
category: 'Charts',
|
|
48
|
+
label: 'Area Chart',
|
|
49
|
+
type: 'chart',
|
|
50
|
+
subType: 'Area Chart',
|
|
51
|
+
orientation: 'vertical',
|
|
52
|
+
content: 'Display an area chart to visualize quantities over time.'
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 8,
|
|
56
|
+
category: 'Charts',
|
|
57
|
+
label: 'Scatter Plot',
|
|
58
|
+
type: 'chart',
|
|
59
|
+
subType: 'Scatter Plot',
|
|
60
|
+
orientation: 'vertical',
|
|
61
|
+
content: 'Display a scatter plot to explore relationships between numeric variables.'
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 12,
|
|
65
|
+
category: 'Charts',
|
|
66
|
+
label: 'Horizontal Bar (Stacked)',
|
|
67
|
+
type: 'chart',
|
|
68
|
+
subType: 'Bar',
|
|
69
|
+
visualizationSubType: 'stacked',
|
|
70
|
+
orientation: 'horizontal',
|
|
71
|
+
content: 'Use bars to show comparisons between data categories.'
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 19,
|
|
75
|
+
category: 'Maps',
|
|
76
|
+
label: 'United States (State- or County-Level)',
|
|
77
|
+
type: 'map',
|
|
78
|
+
subType: 'us',
|
|
79
|
+
content: 'Present a U.S. choropleth map at state or county level.',
|
|
80
|
+
position: 'right'
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
/** Build a seed COVE config from a button definition. */
|
|
85
|
+
const generateNewConfig = (props: any) => {
|
|
86
|
+
let newConfig: any = {}
|
|
87
|
+
switch (props.category) {
|
|
88
|
+
case 'Charts': {
|
|
89
|
+
const visualizationType = props.subType
|
|
90
|
+
const visualizationSubType = !props.visualizationSubType ? 'regular' : props.visualizationSubType
|
|
91
|
+
newConfig = {
|
|
92
|
+
...props,
|
|
93
|
+
visualizationType,
|
|
94
|
+
visualizationSubType,
|
|
95
|
+
newViz: true,
|
|
96
|
+
datasets: {}
|
|
97
|
+
}
|
|
98
|
+
break
|
|
99
|
+
}
|
|
100
|
+
case 'Maps': {
|
|
101
|
+
newConfig = { ...props, newViz: true, datasets: {}, type: 'map' }
|
|
102
|
+
newConfig['general'] = { geoType: props.subType, type: props?.generalType }
|
|
103
|
+
break
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return newConfig
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Convert a raw Vega/Vega-Lite config into a COVE config.
|
|
111
|
+
* Returns `null` if the config has errors.
|
|
112
|
+
*/
|
|
113
|
+
export const importVegaConfig = async (rawConfig: any): Promise<any | null> => {
|
|
114
|
+
const vegaConfig = await parseVegaConfig(rawConfig)
|
|
115
|
+
const vegaErrors = getVegaErrors(rawConfig, vegaConfig)
|
|
116
|
+
if (vegaErrors.length > 0) {
|
|
117
|
+
console.warn('Vega import errors:', vegaErrors)
|
|
118
|
+
return null
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const configType = getVegaConfigType(vegaConfig)
|
|
122
|
+
const configSubType = configType === 'Map' ? 'United States (State- or County-Level)' : configType
|
|
123
|
+
const button = buttons.find(b => b.label === configSubType)
|
|
124
|
+
if (!button) {
|
|
125
|
+
console.warn(`No button found for config type "${configSubType}"`)
|
|
126
|
+
return null
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const coveConfig = generateNewConfig(JSON.parse(JSON.stringify(button)))
|
|
130
|
+
try {
|
|
131
|
+
const warnings = getVegaWarnings(rawConfig, vegaConfig)
|
|
132
|
+
if (warnings.length) {
|
|
133
|
+
console.warn('Vega import warnings:', warnings)
|
|
134
|
+
}
|
|
135
|
+
const result = convertVegaConfig(configType, vegaConfig, coveConfig)
|
|
136
|
+
|
|
137
|
+
// Ensure imported Vega configs use the v1 qualitative palette so CdcChart
|
|
138
|
+
// doesn't apply v2 sequential-blue defaults (which would change the colors).
|
|
139
|
+
if (result && result.type !== 'map') {
|
|
140
|
+
result.general = result.general || {}
|
|
141
|
+
result.general.palette = {
|
|
142
|
+
name: 'qualitative-bold',
|
|
143
|
+
version: '1.0'
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return result
|
|
148
|
+
} catch (err) {
|
|
149
|
+
console.error('Vega conversion error:', err)
|
|
150
|
+
return null
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Check if a config is a Vega config and convert it; otherwise pass through. */
|
|
155
|
+
export const maybeConvertVega = async (config: any): Promise<any | null> => {
|
|
156
|
+
if (isVegaConfig(config)) {
|
|
157
|
+
return importVegaConfig(config)
|
|
158
|
+
}
|
|
159
|
+
return config
|
|
160
|
+
}
|
package/helpers/ver/4.24.4.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import cloneConfig from '../cloneConfig'
|
|
3
|
+
import { ConfigRow } from '@cdc/dashboard/src/types/ConfigRow'
|
|
4
|
+
|
|
5
|
+
// Migrates rows from old array-of-arrays format to new { columns: [] } format.
|
|
6
|
+
// Configs saved at exactly 4.24.3 have this format but the 4.24.3 migration
|
|
7
|
+
// never runs for them (versionNeedsUpdate returns false when versions are equal).
|
|
8
|
+
const remapDashboardRows = config => {
|
|
9
|
+
if (config.type === 'dashboard' && config.rows) {
|
|
10
|
+
config.rows = config.rows.map(row => {
|
|
11
|
+
if (row.columns === undefined) {
|
|
12
|
+
const newRow = {} as ConfigRow
|
|
13
|
+
const newColumns = row.map(column => {
|
|
14
|
+
newRow.uuid = column.uuid
|
|
15
|
+
newRow.toggle = column.toggle
|
|
16
|
+
newRow.equalHeight = column.equalHeight
|
|
17
|
+
return _.pick(column, 'equalHeight', 'width', 'hide', 'widget', 'uuid')
|
|
18
|
+
})
|
|
19
|
+
newRow.columns = newColumns
|
|
20
|
+
return newRow
|
|
21
|
+
}
|
|
22
|
+
return row
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
3
26
|
|
|
4
27
|
const addFiltersToTables = config => {
|
|
5
28
|
if (config.type === 'dashboard') {
|
|
@@ -19,6 +42,7 @@ const update_4_24_4 = config => {
|
|
|
19
42
|
const ver = '4.24.4'
|
|
20
43
|
|
|
21
44
|
const newConfig = cloneConfig(config)
|
|
45
|
+
remapDashboardRows(newConfig)
|
|
22
46
|
addFiltersToTables(newConfig)
|
|
23
47
|
|
|
24
48
|
newConfig.version = ver
|
package/helpers/ver/4.26.1.ts
CHANGED
|
@@ -20,7 +20,7 @@ const removeOldBrushKeys = config => {
|
|
|
20
20
|
delete config.brush
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
if (config.type === 'dashboard') {
|
|
23
|
+
if (config.type === 'dashboard' && config.visualizations) {
|
|
24
24
|
Object.values((config as DashboardConfig).visualizations).forEach(visualization => {
|
|
25
25
|
removeOldBrushKeys(visualization)
|
|
26
26
|
})
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import cloneConfig from '../cloneConfig'
|
|
2
|
+
import { DashboardConfig } from '@cdc/dashboard/src/types/DashboardConfig'
|
|
3
|
+
|
|
4
|
+
const migrateAnnotationDimensions = config => {
|
|
5
|
+
if (config.annotations && Array.isArray(config.annotations)) {
|
|
6
|
+
// Calculate chart area height for Y conversion (matches calcInitialHeight)
|
|
7
|
+
const isHorizontal = config.orientation === 'horizontal'
|
|
8
|
+
const chartAreaHeight = isHorizontal
|
|
9
|
+
? Number(config.heights?.horizontal) || 750 // default horizontal height
|
|
10
|
+
: Number(config.heights?.vertical) || 300 // default vertical height
|
|
11
|
+
|
|
12
|
+
config.annotations = config.annotations.map(annotation => {
|
|
13
|
+
if (!annotation) return annotation
|
|
14
|
+
if (annotation.y !== undefined && chartAreaHeight > 0) {
|
|
15
|
+
// Convert Y from pixels to percentage using the chart area height
|
|
16
|
+
annotation.y = (annotation.y / chartAreaHeight) * 100
|
|
17
|
+
} else {
|
|
18
|
+
annotation.y = 50
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Delete savedDimensions to preserve old dx/dy behavior (fixed pixel offsets).
|
|
22
|
+
// The scaling function falls back to raw dx/dy when savedDimensions is missing.
|
|
23
|
+
// Once user drags the annotation, savedDimensions will be set with current chart
|
|
24
|
+
// dimensions, enabling responsive scaling from that point forward.
|
|
25
|
+
delete annotation.savedDimensions
|
|
26
|
+
|
|
27
|
+
return annotation
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (config.type === 'dashboard' && config.visualizations) {
|
|
32
|
+
Object.values((config as DashboardConfig).visualizations).forEach(visualization => {
|
|
33
|
+
migrateAnnotationDimensions(visualization)
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const migrateAnnotationDataModel = config => {
|
|
39
|
+
if (config.annotations && Array.isArray(config.annotations)) {
|
|
40
|
+
config.annotations = config.annotations.map(annotation => {
|
|
41
|
+
if (!annotation) return annotation
|
|
42
|
+
// Set all existing annotations to fixed mode
|
|
43
|
+
annotation.anchorMode = 'fixed'
|
|
44
|
+
|
|
45
|
+
// Delete xKey entirely - old format stored timestamps for dates,
|
|
46
|
+
// but new dataX expects raw data values. Format is incompatible.
|
|
47
|
+
// User can re-enable data mode which will set fresh dataX value.
|
|
48
|
+
delete annotation.xKey
|
|
49
|
+
|
|
50
|
+
// Delete yKey entirely (Y will be calculated dynamically in data mode)
|
|
51
|
+
delete annotation.yKey
|
|
52
|
+
|
|
53
|
+
// Delete empty seriesKey - it would cause yScale(undefined) errors in data mode
|
|
54
|
+
if (!annotation.seriesKey) {
|
|
55
|
+
delete annotation.seriesKey
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Delete deprecated properties
|
|
59
|
+
delete annotation.snapToNearestPoint
|
|
60
|
+
delete annotation.originalX
|
|
61
|
+
delete annotation.originalDX
|
|
62
|
+
delete annotation.originalY
|
|
63
|
+
|
|
64
|
+
return annotation
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (config.type === 'dashboard' && config.visualizations) {
|
|
69
|
+
Object.values((config as DashboardConfig).visualizations).forEach(visualization => {
|
|
70
|
+
migrateAnnotationDataModel(visualization)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const update_4_26_2 = config => {
|
|
76
|
+
const ver = '4.26.2'
|
|
77
|
+
const newConfig = cloneConfig(config)
|
|
78
|
+
migrateAnnotationDimensions(newConfig)
|
|
79
|
+
migrateAnnotationDataModel(newConfig)
|
|
80
|
+
newConfig.version = ver
|
|
81
|
+
return newConfig
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default update_4_26_2
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import cloneConfig from '../cloneConfig'
|
|
2
|
+
import { DashboardConfig } from '@cdc/dashboard/src/types/DashboardConfig'
|
|
3
|
+
|
|
4
|
+
const addLocale = config => {
|
|
5
|
+
if (!config.locale) {
|
|
6
|
+
config.locale = 'en-US'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (config.type === 'dashboard' && config.visualizations) {
|
|
10
|
+
Object.values((config as DashboardConfig).visualizations).forEach(visualization => {
|
|
11
|
+
addLocale(visualization)
|
|
12
|
+
})
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const disableExtraChartVisualSettings = config => {
|
|
17
|
+
if (config.type === 'chart') {
|
|
18
|
+
config.visual = {
|
|
19
|
+
...config.visual,
|
|
20
|
+
border: false,
|
|
21
|
+
borderColorTheme: false,
|
|
22
|
+
accent: false,
|
|
23
|
+
background: false,
|
|
24
|
+
hideBackgroundColor: false
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (config.type === 'dashboard' && config.visualizations) {
|
|
29
|
+
Object.values((config as DashboardConfig).visualizations).forEach(visualization => {
|
|
30
|
+
disableExtraChartVisualSettings(visualization)
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const update_4_26_3 = config => {
|
|
36
|
+
const ver = '4.26.3'
|
|
37
|
+
const newConfig = cloneConfig(config)
|
|
38
|
+
addLocale(newConfig)
|
|
39
|
+
disableExtraChartVisualSettings(newConfig)
|
|
40
|
+
newConfig.version = ver
|
|
41
|
+
return newConfig
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default update_4_26_3
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import cloneConfig from '../cloneConfig'
|
|
2
|
+
import { DashboardConfig } from '@cdc/dashboard/src/types/DashboardConfig'
|
|
3
|
+
|
|
4
|
+
const disableExtraChartVisualSettings = config => {
|
|
5
|
+
if (config.type === 'chart') {
|
|
6
|
+
config.visual = {
|
|
7
|
+
...config.visual,
|
|
8
|
+
border: false,
|
|
9
|
+
borderColorTheme: false,
|
|
10
|
+
accent: false,
|
|
11
|
+
background: false,
|
|
12
|
+
hideBackgroundColor: false
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (config.type === 'dashboard' && config.visualizations) {
|
|
17
|
+
Object.values((config as DashboardConfig).visualizations).forEach(visualization => {
|
|
18
|
+
disableExtraChartVisualSettings(visualization)
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const update_4_26_4 = config => {
|
|
24
|
+
const ver = '4.26.4'
|
|
25
|
+
const newConfig = cloneConfig(config)
|
|
26
|
+
disableExtraChartVisualSettings(newConfig)
|
|
27
|
+
newConfig.version = ver
|
|
28
|
+
return newConfig
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default update_4_26_4
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import update_4_26_1 from '../4.26.1'
|
|
2
|
+
import { expect, describe, it } from 'vitest'
|
|
3
|
+
|
|
4
|
+
describe('update_4_26_1', () => {
|
|
5
|
+
describe('normalizeFilterParents', () => {
|
|
6
|
+
it('should convert string parents to array in shared filters', () => {
|
|
7
|
+
const config: any = {
|
|
8
|
+
type: 'dashboard',
|
|
9
|
+
version: '4.26.0',
|
|
10
|
+
dashboard: {
|
|
11
|
+
sharedFilters: [
|
|
12
|
+
{
|
|
13
|
+
type: 'datafilter',
|
|
14
|
+
parents: 'parent-filter-id'
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const result = update_4_26_1(config)
|
|
21
|
+
|
|
22
|
+
expect(result.dashboard.sharedFilters[0].parents).toEqual(['parent-filter-id'])
|
|
23
|
+
expect(result.version).toBe('4.26.1')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('should leave array parents unchanged', () => {
|
|
27
|
+
const config: any = {
|
|
28
|
+
type: 'dashboard',
|
|
29
|
+
version: '4.26.0',
|
|
30
|
+
dashboard: {
|
|
31
|
+
sharedFilters: [
|
|
32
|
+
{
|
|
33
|
+
type: 'datafilter',
|
|
34
|
+
parents: ['parent1', 'parent2']
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const result = update_4_26_1(config)
|
|
41
|
+
|
|
42
|
+
expect(result.dashboard.sharedFilters[0].parents).toEqual(['parent1', 'parent2'])
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
describe('removeOldBrushKeys', () => {
|
|
47
|
+
it('should remove brush config from chart', () => {
|
|
48
|
+
const config: any = {
|
|
49
|
+
type: 'chart',
|
|
50
|
+
version: '4.26.0',
|
|
51
|
+
brush: { enabled: true }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const result = update_4_26_1(config)
|
|
55
|
+
|
|
56
|
+
expect(result.brush).toBeUndefined()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should remove brush config from dashboard visualizations', () => {
|
|
60
|
+
const config: any = {
|
|
61
|
+
type: 'dashboard',
|
|
62
|
+
version: '4.26.0',
|
|
63
|
+
visualizations: {
|
|
64
|
+
chart1: {
|
|
65
|
+
type: 'chart',
|
|
66
|
+
brush: { enabled: true }
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const result = update_4_26_1(config)
|
|
72
|
+
|
|
73
|
+
expect(result.visualizations.chart1.brush).toBeUndefined()
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('combined migrations', () => {
|
|
78
|
+
it('should run all migrations together', () => {
|
|
79
|
+
const config: any = {
|
|
80
|
+
type: 'dashboard',
|
|
81
|
+
version: '4.26.0',
|
|
82
|
+
dashboard: {
|
|
83
|
+
sharedFilters: [
|
|
84
|
+
{
|
|
85
|
+
type: 'datafilter',
|
|
86
|
+
parents: 'parent-id'
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
visualizations: {
|
|
91
|
+
chart1: {
|
|
92
|
+
type: 'chart',
|
|
93
|
+
brush: { enabled: true }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const result = update_4_26_1(config)
|
|
99
|
+
|
|
100
|
+
expect(result.dashboard.sharedFilters[0].parents).toEqual(['parent-id'])
|
|
101
|
+
expect(result.visualizations.chart1.brush).toBeUndefined()
|
|
102
|
+
expect(result.version).toBe('4.26.1')
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
})
|