@cdc/core 4.25.5-1 → 4.25.6-1
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/components/Alert/components/Alert.tsx +1 -1
- package/components/DataTable/DataTable.tsx +0 -3
- package/components/DataTable/DataTableStandAlone.tsx +15 -9
- package/components/DataTable/components/ChartHeader.tsx +6 -4
- package/components/DataTable/components/DataTableEditorPanel.tsx +25 -3
- package/components/DataTable/helpers/chartCellMatrix.tsx +13 -10
- package/components/DataTable/helpers/getChartCellValue.ts +42 -26
- package/components/DataTable/helpers/mapCellMatrix.tsx +9 -1
- package/components/EditorPanel/FootnotesEditor.tsx +76 -22
- package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +1 -1
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +48 -34
- package/components/Filters/Filters.tsx +27 -69
- package/components/Filters/components/Dropdown.tsx +1 -1
- package/components/Footnotes/Footnotes.tsx +1 -1
- package/components/Footnotes/FootnotesStandAlone.tsx +8 -33
- package/components/Layout/components/Visualization/index.tsx +2 -1
- package/components/Legend/Legend.Gradient.tsx +3 -2
- package/components/MultiSelect/MultiSelect.tsx +3 -6
- package/components/NestedDropdown/NestedDropdown.tsx +19 -19
- package/helpers/cove/number.ts +5 -3
- package/helpers/coveUpdateWorker.ts +4 -0
- package/helpers/formatConfigBeforeSave.ts +19 -32
- package/helpers/updateFieldFactory.ts +1 -0
- package/helpers/ver/4.25.4.ts +77 -0
- package/helpers/ver/4.25.6.ts +36 -0
- package/helpers/ver/4.25.7.ts +26 -0
- package/helpers/ver/tests/4.25.4.test.ts +66 -1
- package/helpers/ver/tests/4.25.6.test.ts +84 -0
- package/package.json +7 -5
- package/styles/_global.scss +0 -4
- package/styles/filters.scss +0 -4
- package/types/Axis.ts +2 -0
- package/types/DataSet.ts +14 -0
- package/types/Footnotes.ts +5 -2
- package/types/Table.ts +1 -0
- package/types/Visualization.ts +3 -12
- package/types/VizFilter.ts +3 -0
- package/components/Filters/helpers/getNewRuntime.ts +0 -35
- package/components/Filters/helpers/tests/getNewRuntime.test.ts +0 -82
- /package/helpers/{fetchRemoteData.js → fetchRemoteData.ts} +0 -0
|
@@ -50,7 +50,7 @@ const Options: React.FC<{
|
|
|
50
50
|
onKeyUp={handleKeyUp}
|
|
51
51
|
className={`nested-dropdown-group-${filterIndex}`}
|
|
52
52
|
>
|
|
53
|
-
<span className={'font-weight-bold'}>{label} </span>
|
|
53
|
+
<span className={'font-weight-bold fw-bold'}>{label} </span>
|
|
54
54
|
{
|
|
55
55
|
<span className='list-arrow' aria-hidden='true'>
|
|
56
56
|
{isTierOneExpanded ? (
|
|
@@ -241,7 +241,7 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
|
|
|
241
241
|
setInputHasFocus(false)
|
|
242
242
|
setIsListOpened(false)
|
|
243
243
|
} else {
|
|
244
|
-
;(e.relatedTarget as HTMLElement).focus()
|
|
244
|
+
; (e.relatedTarget as HTMLElement).focus()
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
|
|
@@ -302,23 +302,23 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
|
|
|
302
302
|
>
|
|
303
303
|
{filterOptions.length
|
|
304
304
|
? filterOptions.map(([group, subgroup], index) => {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
305
|
+
const [groupValue, groupText] = group
|
|
306
|
+
const groupTextValue = String(groupText || groupValue)
|
|
307
|
+
return (
|
|
308
|
+
<Options
|
|
309
|
+
key={groupTextValue + '_' + index}
|
|
310
|
+
handleBlur={handleOnBlur}
|
|
311
|
+
subOptions={subgroup}
|
|
312
|
+
filterIndex={filterIndex}
|
|
313
|
+
label={groupTextValue}
|
|
314
|
+
handleSubGroupSelect={subGroupValue => {
|
|
315
|
+
chooseSelectedSubGroup(groupValue, subGroupValue)
|
|
316
|
+
}}
|
|
317
|
+
userSelectedLabel={activeGroup + activeSubGroup}
|
|
318
|
+
userSearchTerm={userSearchTerm || ''}
|
|
319
|
+
/>
|
|
320
|
+
)
|
|
321
|
+
})
|
|
322
322
|
: 'There are no matching items'}
|
|
323
323
|
</ul>
|
|
324
324
|
</div>
|
package/helpers/cove/number.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { VisualizationType } from './../../../../node_modules/@cdc/chart/src/types/ChartConfig'
|
|
2
|
+
import { Visualization } from '@cdc/core/types/Visualization'
|
|
1
3
|
import numberFromString from '@cdc/core/helpers/numberFromString'
|
|
2
4
|
|
|
3
5
|
const abbreviateNumber = num => {
|
|
@@ -54,7 +56,6 @@ const formatNumber = (num, axis, shouldAbbreviate = false, config = null, addCol
|
|
|
54
56
|
bottomSuffix,
|
|
55
57
|
bottomComas,
|
|
56
58
|
commas,
|
|
57
|
-
onlyShowTopPrefixSuffix,
|
|
58
59
|
prefix,
|
|
59
60
|
rightPrefix,
|
|
60
61
|
rightRoundTo,
|
|
@@ -63,6 +64,7 @@ const formatNumber = (num, axis, shouldAbbreviate = false, config = null, addCol
|
|
|
63
64
|
suffix
|
|
64
65
|
}
|
|
65
66
|
} = config
|
|
67
|
+
const { inlineLabel } = config.yAxis || {}
|
|
66
68
|
|
|
67
69
|
// destructure Additional Col dataformat values
|
|
68
70
|
const { addColCommas, addColRoundTo, addColPrefix, addColSuffix } = addColParams || {}
|
|
@@ -154,7 +156,7 @@ const formatNumber = (num, axis, shouldAbbreviate = false, config = null, addCol
|
|
|
154
156
|
num = abbreviateNumber(parseFloat(num))
|
|
155
157
|
}
|
|
156
158
|
|
|
157
|
-
if (!
|
|
159
|
+
if (!inlineLabel || addColPrefix) {
|
|
158
160
|
if (addColPrefix !== undefined && axis === 'left') {
|
|
159
161
|
result = addColPrefix + result
|
|
160
162
|
} else {
|
|
@@ -174,7 +176,7 @@ const formatNumber = (num, axis, shouldAbbreviate = false, config = null, addCol
|
|
|
174
176
|
|
|
175
177
|
result += num
|
|
176
178
|
|
|
177
|
-
if (!
|
|
179
|
+
if (!inlineLabel || addColSuffix) {
|
|
178
180
|
if (addColSuffix !== undefined && axis === 'left') {
|
|
179
181
|
result += addColSuffix
|
|
180
182
|
} else {
|
|
@@ -14,6 +14,8 @@ import update_4_24_11 from './ver/4.24.11'
|
|
|
14
14
|
import update_4_25_1 from './ver/4.25.1'
|
|
15
15
|
import update_4_25_3 from './ver/4.25.3'
|
|
16
16
|
import update_4_25_4 from './ver/4.25.4'
|
|
17
|
+
import update_4_25_6 from './ver/4.25.6'
|
|
18
|
+
import update_4_25_7 from './ver/4.25.7'
|
|
17
19
|
|
|
18
20
|
export const coveUpdateWorker = (config, multiDashboardVersion?) => {
|
|
19
21
|
let genConfig = config
|
|
@@ -31,6 +33,8 @@ export const coveUpdateWorker = (config, multiDashboardVersion?) => {
|
|
|
31
33
|
['4.25.1', update_4_25_1],
|
|
32
34
|
['4.25.3', update_4_25_3],
|
|
33
35
|
['4.25.4', update_4_25_4],
|
|
36
|
+
['4.25.6', update_4_25_6],
|
|
37
|
+
['4.25.7', update_4_25_7]
|
|
34
38
|
]
|
|
35
39
|
|
|
36
40
|
versions.forEach(([version, updateFunction, alwaysRun]: [string, UpdateFunction, boolean?]) => {
|
|
@@ -5,29 +5,12 @@ import { removeDashboardFilter } from '@cdc/dashboard/src/helpers/removeDashboar
|
|
|
5
5
|
import _ from 'lodash'
|
|
6
6
|
|
|
7
7
|
const cleanDashboardFootnotes = (config: DashboardConfig) => {
|
|
8
|
-
// strip any blank footnote visualizations
|
|
9
|
-
const footnoteIds: string[] = []
|
|
10
|
-
|
|
11
|
-
if (config.rows) {
|
|
12
|
-
config.rows.forEach(row => {
|
|
13
|
-
if (row.footnotesId) {
|
|
14
|
-
const { dataKey, staticFootnotes } = (config.visualizations[row.footnotesId] || {}) as Footnotes
|
|
15
|
-
if (!dataKey && !staticFootnotes?.length) {
|
|
16
|
-
delete config.visualizations[row.footnotesId]
|
|
17
|
-
delete row.footnotesId
|
|
18
|
-
} else {
|
|
19
|
-
footnoteIds.push(row.footnotesId)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
|
|
25
8
|
if (config.visualizations) {
|
|
26
9
|
Object.keys(config.visualizations).forEach(vizKey => {
|
|
27
10
|
const viz: Visualization = config.visualizations[vizKey]
|
|
28
|
-
if (viz.
|
|
29
|
-
|
|
30
|
-
delete config.visualizations[vizKey]
|
|
11
|
+
if (viz.footnotes) {
|
|
12
|
+
delete config.visualizations[vizKey].footnotes.data
|
|
13
|
+
delete config.visualizations[vizKey].footnotes.formattedData
|
|
31
14
|
}
|
|
32
15
|
})
|
|
33
16
|
}
|
|
@@ -64,23 +47,27 @@ const cleanDashboardData = (config: DashboardConfig) => {
|
|
|
64
47
|
|
|
65
48
|
export const cleanSharedFilters = (config: DashboardConfig) => {
|
|
66
49
|
if (config.dashboard?.sharedFilters) {
|
|
67
|
-
|
|
68
50
|
const recursiveRemoveFilters = (sharedFilters, visualizations: Record<string, AnyVisualization>) => {
|
|
69
|
-
const usedFilters = _.uniq(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
51
|
+
const usedFilters = _.uniq(
|
|
52
|
+
Object.values(visualizations).reduce((acc, viz) => {
|
|
53
|
+
if (viz.type === 'dashboardFilters') {
|
|
54
|
+
acc = acc.concat(viz.sharedFilterIndexes)
|
|
55
|
+
}
|
|
56
|
+
return acc
|
|
57
|
+
}, [])
|
|
58
|
+
)
|
|
59
|
+
for (let index = 0; index < sharedFilters.length; index++) {
|
|
76
60
|
const filter = sharedFilters[index]
|
|
77
|
-
if(!usedFilters.includes(index)) {
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
if (!usedFilters.includes(index)) {
|
|
62
|
+
const [newSharedFilters, newVisualizations] = removeDashboardFilter(
|
|
63
|
+
index,
|
|
64
|
+
config.dashboard.sharedFilters,
|
|
65
|
+
config.visualizations
|
|
66
|
+
)
|
|
80
67
|
config.dashboard.sharedFilters = newSharedFilters
|
|
81
68
|
config.visualizations = newVisualizations
|
|
82
69
|
recursiveRemoveFilters(newSharedFilters, newVisualizations)
|
|
83
|
-
break
|
|
70
|
+
break
|
|
84
71
|
} else {
|
|
85
72
|
delete config.dashboard.sharedFilters[index].active
|
|
86
73
|
if (filter.subGrouping) delete config.dashboard.sharedFilters[index].subGrouping.active
|
|
@@ -18,6 +18,7 @@ export const updateFieldFactory =
|
|
|
18
18
|
const isArray = Array.isArray(config[section])
|
|
19
19
|
|
|
20
20
|
let sectionValue = isArray ? [...config[section], newValue] : { ...config[section], [fieldName]: newValue }
|
|
21
|
+
if (!fieldName && !legacy) sectionValue = newValue
|
|
21
22
|
|
|
22
23
|
if (null !== subsection) {
|
|
23
24
|
if (isArray) {
|
package/helpers/ver/4.25.4.ts
CHANGED
|
@@ -21,11 +21,88 @@ const migrateTableGeneralSettings = config => {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
const hasMultipleWidgetColumns = row => {
|
|
25
|
+
const multipleColumns = row.columns.filter(column => column.widget).length > 1
|
|
26
|
+
return multipleColumns && !row.toggle
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const newMarkupIncludeVisualization = (uid, footnotes) => {
|
|
30
|
+
return {
|
|
31
|
+
filters: [],
|
|
32
|
+
filterBehavior: 'Filter Change',
|
|
33
|
+
footnotes,
|
|
34
|
+
uid,
|
|
35
|
+
type: 'markup-include',
|
|
36
|
+
visualizationType: 'markup-include',
|
|
37
|
+
contentEditor: {
|
|
38
|
+
inlineHTML: '',
|
|
39
|
+
markupVariables: [],
|
|
40
|
+
showHeader: false,
|
|
41
|
+
srcUrl: '',
|
|
42
|
+
title: '',
|
|
43
|
+
useInlineHTML: false
|
|
44
|
+
},
|
|
45
|
+
theme: 'theme-blue',
|
|
46
|
+
visual: {
|
|
47
|
+
border: false,
|
|
48
|
+
accent: false,
|
|
49
|
+
background: false,
|
|
50
|
+
hideBackgroundColor: false,
|
|
51
|
+
borderColorTheme: false
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const makeNewRow = uuid => {
|
|
57
|
+
return { columns: [{ width: 12, widget: uuid }] }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const moveFootnotesToVizLevel = config => {
|
|
61
|
+
if (config.type === 'dashboard') {
|
|
62
|
+
const newRowsToAdd = [
|
|
63
|
+
/*old row index*/
|
|
64
|
+
/*new row object*/
|
|
65
|
+
]
|
|
66
|
+
config.rows.forEach((row, index) => {
|
|
67
|
+
if (!row.footnotesId) return
|
|
68
|
+
const makeNewFootnotesRow = hasMultipleWidgetColumns(row)
|
|
69
|
+
const footnotesId = row.footnotesId
|
|
70
|
+
const footnote = _.pick(config.visualizations[footnotesId], ['dataKey', 'dynamicFootnotes', 'staticFootnotes'])
|
|
71
|
+
if (makeNewFootnotesRow) {
|
|
72
|
+
const uuid = `markup-include-${Date.now()}${index}`
|
|
73
|
+
const newRow = makeNewRow(uuid)
|
|
74
|
+
const newFootnotesViz = newMarkupIncludeVisualization(uuid, footnote)
|
|
75
|
+
config.visualizations[uuid] = newFootnotesViz
|
|
76
|
+
newRowsToAdd.push([index, newRow])
|
|
77
|
+
} else {
|
|
78
|
+
row.columns.forEach(column => {
|
|
79
|
+
if (!column.widget) return
|
|
80
|
+
const footnotes = config.visualizations[column.widget].footnotes
|
|
81
|
+
if (typeof footnotes === 'string') {
|
|
82
|
+
// move legacy footnotes
|
|
83
|
+
config.visualizations[column.widget].legacyFootnotes = footnotes
|
|
84
|
+
}
|
|
85
|
+
config.visualizations[column.widget].footnotes = footnote
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
delete config.visualizations[footnotesId]
|
|
90
|
+
delete row.footnotesId
|
|
91
|
+
})
|
|
92
|
+
if (newRowsToAdd.length) {
|
|
93
|
+
newRowsToAdd.forEach(([oldRowIndex, newRow]) => {
|
|
94
|
+
config.rows.splice(oldRowIndex + 1, 0, newRow)
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
24
100
|
const update_4_25_4 = config => {
|
|
25
101
|
const ver = '4.25.4'
|
|
26
102
|
const newConfig = _.cloneDeep(config)
|
|
27
103
|
makeChartLegendsUnified(newConfig)
|
|
28
104
|
migrateTableGeneralSettings(newConfig)
|
|
105
|
+
moveFootnotesToVizLevel(newConfig)
|
|
29
106
|
newConfig.version = ver
|
|
30
107
|
return newConfig
|
|
31
108
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
|
|
3
|
+
// *NOTE: This ends support for only showing the top prefix
|
|
4
|
+
export const changeOnlyShowTopSuffixToInlineLabel = config => {
|
|
5
|
+
if (config.type === 'chart') {
|
|
6
|
+
if (!config.dataFormat?.suffix) return config
|
|
7
|
+
if (!config.dataFormat.onlyShowTopPrefixSuffix) return config
|
|
8
|
+
|
|
9
|
+
delete config.dataFormat.onlyShowTopPrefixSuffix
|
|
10
|
+
|
|
11
|
+
if (!config.yAxis) config.yAxis = {}
|
|
12
|
+
|
|
13
|
+
if (!config.yAxis?.inlineLabel) {
|
|
14
|
+
config.yAxis.inlineLabel = config.dataFormat.suffix
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
config.dataFormat.suffix = ''
|
|
18
|
+
|
|
19
|
+
return config
|
|
20
|
+
} else if (config.type === 'dashboard') {
|
|
21
|
+
Object.values(config.visualizations).forEach(visualization => {
|
|
22
|
+
changeOnlyShowTopSuffixToInlineLabel(visualization)
|
|
23
|
+
})
|
|
24
|
+
return config
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const update_4_25_6 = config => {
|
|
29
|
+
const ver = '4.25.6'
|
|
30
|
+
const newConfig = _.cloneDeep(config)
|
|
31
|
+
changeOnlyShowTopSuffixToInlineLabel(newConfig)
|
|
32
|
+
newConfig.version = ver
|
|
33
|
+
return newConfig
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default update_4_25_6
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
|
|
3
|
+
export const updatePreliminaryDataSeriesKeys = config => {
|
|
4
|
+
if (config.type === 'chart') {
|
|
5
|
+
;(config.preliminaryData || []).forEach(pd => {
|
|
6
|
+
if (!pd.seriesKeys) {
|
|
7
|
+
pd.seriesKeys = pd.seriesKey ? [pd.seriesKey] : []
|
|
8
|
+
delete pd.seriesKey
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
} else if (config.type === 'dashboard') {
|
|
12
|
+
Object.values(config.visualizations).forEach(visualization => {
|
|
13
|
+
updatePreliminaryDataSeriesKeys(visualization)
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const update_4_25_7 = config => {
|
|
19
|
+
const ver = '4.25.7'
|
|
20
|
+
const newConfig = _.cloneDeep(config)
|
|
21
|
+
updatePreliminaryDataSeriesKeys(newConfig)
|
|
22
|
+
newConfig.version = ver
|
|
23
|
+
return newConfig
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default update_4_25_7
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { expect, describe, it } from 'vitest'
|
|
2
|
-
import { makeChartLegendsUnified } from '../4.25.4'
|
|
2
|
+
import { makeChartLegendsUnified, moveFootnotesToVizLevel } from '../4.25.4'
|
|
3
3
|
import { ChartConfig } from '@cdc/chart/src/types/ChartConfig'
|
|
4
4
|
import { DashboardConfig } from '@cdc/dashboard/src/types/DashboardConfig'
|
|
5
5
|
|
|
@@ -22,3 +22,68 @@ describe('makeChartLegendsUnified(config) ', () => {
|
|
|
22
22
|
expect(mockConfig.visualizations['2'].legend?.unified).toBe(true)
|
|
23
23
|
})
|
|
24
24
|
})
|
|
25
|
+
|
|
26
|
+
describe('moveFootnotesToVizLevel', () => {
|
|
27
|
+
it('moves footnotes to visualization level', () => {
|
|
28
|
+
const toMigrate = {
|
|
29
|
+
rows: [
|
|
30
|
+
{
|
|
31
|
+
columns: [
|
|
32
|
+
{
|
|
33
|
+
width: 12,
|
|
34
|
+
widget: 'table123'
|
|
35
|
+
},
|
|
36
|
+
{},
|
|
37
|
+
{}
|
|
38
|
+
],
|
|
39
|
+
footnotesId: 'footnotes123'
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
visualizations: {
|
|
43
|
+
table123: {},
|
|
44
|
+
footnotes123: {
|
|
45
|
+
uid: 'footnotes123',
|
|
46
|
+
type: 'footnotes',
|
|
47
|
+
visualizationType: 'footnotes',
|
|
48
|
+
dataKey: 'valid-data-chart.csv',
|
|
49
|
+
dynamicFootnotes: {
|
|
50
|
+
symbolColumn: 'Race',
|
|
51
|
+
textColumn: 'Age-adjusted rate'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
type: 'dashboard',
|
|
56
|
+
version: '4.25.4'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const expectedMigration = {
|
|
60
|
+
rows: [
|
|
61
|
+
{
|
|
62
|
+
columns: [
|
|
63
|
+
{
|
|
64
|
+
width: 12,
|
|
65
|
+
widget: 'table123'
|
|
66
|
+
},
|
|
67
|
+
{},
|
|
68
|
+
{}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
visualizations: {
|
|
73
|
+
table123: {
|
|
74
|
+
footnotes: {
|
|
75
|
+
dataKey: 'valid-data-chart.csv',
|
|
76
|
+
dynamicFootnotes: {
|
|
77
|
+
symbolColumn: 'Race',
|
|
78
|
+
textColumn: 'Age-adjusted rate'
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
type: 'dashboard',
|
|
84
|
+
version: '4.25.4'
|
|
85
|
+
}
|
|
86
|
+
moveFootnotesToVizLevel(toMigrate)
|
|
87
|
+
expect(toMigrate).toEqual(expectedMigration)
|
|
88
|
+
})
|
|
89
|
+
})
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { expect, describe, it } from 'vitest'
|
|
2
|
+
import { changeOnlyShowTopSuffixToInlineLabel } from '../4.25.6'
|
|
3
|
+
|
|
4
|
+
describe('changeOnlyShowTopSuffixToInlineLabel(config) ', () => {
|
|
5
|
+
it("should'nt change config if no suffix", () => {
|
|
6
|
+
const config = {
|
|
7
|
+
type: 'chart',
|
|
8
|
+
dataFormat: {
|
|
9
|
+
onlyShowTopPrefixSuffix: true,
|
|
10
|
+
suffix: ''
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const newConfig = changeOnlyShowTopSuffixToInlineLabel(config)
|
|
14
|
+
expect(newConfig).toEqual(config)
|
|
15
|
+
})
|
|
16
|
+
it("should't change suffix if onlyShowTopPrefixSuffix is false", () => {
|
|
17
|
+
const config = {
|
|
18
|
+
type: 'chart',
|
|
19
|
+
dataFormat: {
|
|
20
|
+
onlyShowTopPrefixSuffix: false,
|
|
21
|
+
suffix: 'test'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const newConfig = changeOnlyShowTopSuffixToInlineLabel(config)
|
|
25
|
+
expect(newConfig).toEqual(config)
|
|
26
|
+
})
|
|
27
|
+
it('should change suffix to inlineLabel if onlyShowTopPrefixSuffix is true', () => {
|
|
28
|
+
const config = {
|
|
29
|
+
type: 'chart',
|
|
30
|
+
dataFormat: {
|
|
31
|
+
onlyShowTopPrefixSuffix: true,
|
|
32
|
+
suffix: 'test'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const newConfig = changeOnlyShowTopSuffixToInlineLabel(config)
|
|
36
|
+
expect(newConfig.yAxis.inlineLabel).toBe('test')
|
|
37
|
+
expect(newConfig.dataFormat.onlyShowTopPrefixSuffix).toBe(undefined)
|
|
38
|
+
expect(newConfig.dataFormat.suffix).toBe('')
|
|
39
|
+
})
|
|
40
|
+
it("should't overwrite existing yAxis inlineLabel", () => {
|
|
41
|
+
const config = {
|
|
42
|
+
type: 'chart',
|
|
43
|
+
dataFormat: {
|
|
44
|
+
onlyShowTopPrefixSuffix: true,
|
|
45
|
+
suffix: 'test'
|
|
46
|
+
},
|
|
47
|
+
yAxis: {
|
|
48
|
+
inlineLabel: 'test2'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const newConfig = changeOnlyShowTopSuffixToInlineLabel(config)
|
|
52
|
+
expect(newConfig.yAxis.inlineLabel).toBe('test2')
|
|
53
|
+
expect(newConfig.dataFormat.onlyShowTopPrefixSuffix).toBe(undefined)
|
|
54
|
+
expect(newConfig.dataFormat.suffix).toBe('')
|
|
55
|
+
})
|
|
56
|
+
it('should change suffix to inlineLabel for dashboard visualizations', () => {
|
|
57
|
+
const config = {
|
|
58
|
+
type: 'dashboard',
|
|
59
|
+
visualizations: [
|
|
60
|
+
{
|
|
61
|
+
type: 'chart',
|
|
62
|
+
dataFormat: {
|
|
63
|
+
onlyShowTopPrefixSuffix: true,
|
|
64
|
+
suffix: 'test'
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'chart',
|
|
69
|
+
dataFormat: {
|
|
70
|
+
onlyShowTopPrefixSuffix: true,
|
|
71
|
+
suffix: 'test2'
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
const newConfig = changeOnlyShowTopSuffixToInlineLabel(config)
|
|
77
|
+
expect(newConfig.visualizations[0].yAxis.inlineLabel).toBe('test')
|
|
78
|
+
expect(newConfig.visualizations[0].dataFormat.onlyShowTopPrefixSuffix).toBe(undefined)
|
|
79
|
+
expect(newConfig.visualizations[0].dataFormat.suffix).toBe('')
|
|
80
|
+
expect(newConfig.visualizations[1].yAxis.inlineLabel).toBe('test2')
|
|
81
|
+
expect(newConfig.visualizations[1].dataFormat.onlyShowTopPrefixSuffix).toBe(undefined)
|
|
82
|
+
expect(newConfig.visualizations[1].dataFormat.suffix).toBe('')
|
|
83
|
+
})
|
|
84
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/core",
|
|
3
|
-
"version": "4.25.
|
|
3
|
+
"version": "4.25.6-1",
|
|
4
4
|
"description": "Core components, styles, hooks, and helpers, for the CDC Open Visualization project",
|
|
5
5
|
"moduleName": "CdcCore",
|
|
6
6
|
"main": "dist/cdccore",
|
|
@@ -21,19 +21,21 @@
|
|
|
21
21
|
},
|
|
22
22
|
"license": "Apache-2.0",
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"dompurify": "^3.2.6",
|
|
24
25
|
"html2canvas": "^1.4.1",
|
|
25
|
-
"json-edit-react": "^1.
|
|
26
|
+
"json-edit-react": "^1.27.0",
|
|
26
27
|
"prop-types": "^15.8.1",
|
|
27
|
-
"react-accessible-accordion": "^5.0.
|
|
28
|
+
"react-accessible-accordion": "^5.0.1",
|
|
28
29
|
"react-select": "^5.3.1",
|
|
29
30
|
"react-tooltip": "5.8.2-beta.3",
|
|
30
|
-
"
|
|
31
|
+
"sass": "^1.89.2",
|
|
32
|
+
"use-debounce": "^10.0.5"
|
|
31
33
|
},
|
|
32
34
|
"peerDependencies": {
|
|
33
35
|
"react": "^18.2.0",
|
|
34
36
|
"react-dom": "^18.2.0"
|
|
35
37
|
},
|
|
36
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "ac45ee0f1d6a4045648c4e083992fc091795e084",
|
|
37
39
|
"devDependencies": {
|
|
38
40
|
"sass": "^1.79.4"
|
|
39
41
|
}
|
package/styles/_global.scss
CHANGED
package/styles/filters.scss
CHANGED
|
@@ -93,10 +93,6 @@ div.single-filters {
|
|
|
93
93
|
&:focus:not(:focus-visible) {
|
|
94
94
|
outline: none !important;
|
|
95
95
|
}
|
|
96
|
-
&:focus-visible {
|
|
97
|
-
outline: 2px dashed var(--colors-blue-vivid-60, #005ea2) !important;
|
|
98
|
-
outline-offset: 3px;
|
|
99
|
-
}
|
|
100
96
|
|
|
101
97
|
&.tab--active {
|
|
102
98
|
font-weight: 500;
|
package/types/Axis.ts
CHANGED
|
@@ -17,6 +17,7 @@ export type Axis = {
|
|
|
17
17
|
hideAxis?: boolean
|
|
18
18
|
hideLabel?: boolean
|
|
19
19
|
hideTicks?: boolean
|
|
20
|
+
inlineLabel?: string
|
|
20
21
|
label?: string
|
|
21
22
|
labelOffset?: number
|
|
22
23
|
labelPlacement?: string
|
|
@@ -50,4 +51,5 @@ export type Axis = {
|
|
|
50
51
|
axisBBox: number
|
|
51
52
|
maxValue: string
|
|
52
53
|
sortByRecentDate: boolean
|
|
54
|
+
brushActive: boolean
|
|
53
55
|
}
|
package/types/DataSet.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ConfigureData } from '@cdc/core/types/ConfigureData'
|
|
2
|
+
|
|
3
|
+
export type DataSet = ConfigureData & {
|
|
4
|
+
dataFileFormat?: string
|
|
5
|
+
dataFileName?: string
|
|
6
|
+
dataFileSize?: number
|
|
7
|
+
preview?: boolean
|
|
8
|
+
dataUrl: string
|
|
9
|
+
runtimeDataUrl: string
|
|
10
|
+
dataFileSourceType: string
|
|
11
|
+
loadQueryParam?: string // fetched from the browser's query string and appended to the dataUrl on load.
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type Datasets = Record<string, DataSet>
|
package/types/Footnotes.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VizFilter } from './VizFilter'
|
|
2
2
|
|
|
3
3
|
export type Footnote = {
|
|
4
4
|
symbol?: string
|
|
5
5
|
text: string
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
type Footnotes =
|
|
8
|
+
type Footnotes = {
|
|
9
|
+
filters?: VizFilter[]
|
|
10
|
+
dataKey?: string
|
|
11
|
+
data?: Object[]
|
|
9
12
|
dynamicFootnotes?: {
|
|
10
13
|
symbolColumn?: string
|
|
11
14
|
textColumn: string
|
package/types/Table.ts
CHANGED
package/types/Visualization.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { FilterBehavior } from './FilterBehavior'
|
|
|
10
10
|
import { General } from './General'
|
|
11
11
|
import { Runtime } from './Runtime'
|
|
12
12
|
import { DashboardFilters } from '@cdc/dashboard/src/types/DashboardFilters'
|
|
13
|
+
import Footnotes from './Footnotes'
|
|
13
14
|
|
|
14
15
|
// This was originally created as a catchall for the different types of visualizations.
|
|
15
16
|
// Currently it includes properties that ares specific to one Visualization type.
|
|
@@ -26,7 +27,6 @@ type DeprecatedVisualizationType = {
|
|
|
26
27
|
filters: VizFilter[]
|
|
27
28
|
general: General
|
|
28
29
|
legend: Legend
|
|
29
|
-
multiDashboards?: any[]
|
|
30
30
|
newViz: boolean
|
|
31
31
|
isResponsiveTicks: boolean
|
|
32
32
|
openModal?: boolean
|
|
@@ -37,17 +37,7 @@ type DeprecatedVisualizationType = {
|
|
|
37
37
|
table: Table
|
|
38
38
|
theme: string
|
|
39
39
|
title: string
|
|
40
|
-
type:
|
|
41
|
-
| 'dashboard'
|
|
42
|
-
| 'chart'
|
|
43
|
-
| 'footnotes'
|
|
44
|
-
| 'map'
|
|
45
|
-
| 'data-bite'
|
|
46
|
-
| 'waffle-chart'
|
|
47
|
-
| 'markup-include'
|
|
48
|
-
| 'filtered-text'
|
|
49
|
-
| 'table'
|
|
50
|
-
| 'navigation'
|
|
40
|
+
type: 'chart' | 'map' | 'data-bite' | 'waffle-chart' | 'markup-include' | 'filtered-text' | 'table' | 'navigation'
|
|
51
41
|
usesSharedFilter?: any
|
|
52
42
|
visualizationSubType: string
|
|
53
43
|
visualizationType: string
|
|
@@ -65,6 +55,7 @@ export type CommonVisualizationProperties = Partial<StatefulProperties> & {
|
|
|
65
55
|
uid?: string | number // this is the actual key of the visualization object
|
|
66
56
|
visualizationType?: string
|
|
67
57
|
filterBehavior: FilterBehavior
|
|
58
|
+
footnotes?: Footnotes
|
|
68
59
|
} & Partial<ConfigureData>
|
|
69
60
|
|
|
70
61
|
export type Visualization = DeprecatedVisualizationType & CommonVisualizationProperties
|
package/types/VizFilter.ts
CHANGED