@cdc/dashboard 4.25.1 → 4.25.2-25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdcdashboard.js +52965 -52581
- package/examples/all-components.json +529 -4607
- package/examples/dashboard-gallery.json +397 -397
- package/examples/private/DEV-10527.json +564 -0
- package/examples/private/DEV-10586.json +54319 -0
- package/examples/private/DEV-10856.json +54319 -0
- package/examples/private/dashboard-map-filter.json +815 -0
- package/examples/private/dev-10856-2.json +1348 -0
- package/examples/private/feelings.json +1 -0
- package/examples/private/nhis.json +1792 -0
- package/index.html +4 -3
- package/package.json +9 -9
- package/src/CdcDashboard.tsx +5 -8
- package/src/CdcDashboardComponent.tsx +58 -56
- package/src/_stories/Dashboard.stories.tsx +31 -0
- package/src/_stories/_mock/dashboard-filter-asc.json +551 -0
- package/src/components/CollapsibleVisualizationRow.tsx +1 -1
- package/src/components/DashboardFilters/DashboardFilters.tsx +10 -5
- package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +22 -5
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/DeleteFilterModal.tsx +13 -3
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +129 -40
- package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +10 -7
- package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +11 -12
- package/src/components/DashboardFilters/dashboardfilter.styles.css +0 -2
- package/src/components/VisualizationRow.tsx +12 -2
- package/src/helpers/addValuesToDashboardFilters.ts +6 -5
- package/src/helpers/apiFilterHelpers.ts +10 -5
- package/src/helpers/changeFilterActive.ts +17 -4
- package/src/helpers/getFilteredData.ts +13 -4
- package/src/helpers/getUpdateConfig.ts +11 -4
- package/src/helpers/loadAPIFilters.ts +6 -4
- package/src/helpers/tests/updatesChildFilters.test.ts +56 -0
- package/src/helpers/updateChildFilters.ts +50 -0
- package/src/scss/main.scss +0 -3
- package/src/store/dashboard.reducer.ts +46 -24
- package/src/types/SharedFilter.ts +1 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { SharedFilter } from '../types/SharedFilter'
|
|
2
|
+
import _ from 'lodash'
|
|
3
|
+
|
|
4
|
+
export const updateChildFilters = (newSharedFilters: SharedFilter[], data: Record<string, any>): SharedFilter[] => {
|
|
5
|
+
const dataSet = Object.values(data).flat()
|
|
6
|
+
|
|
7
|
+
// Find indexes of all child filters
|
|
8
|
+
const childFilterIndexes: number[] = newSharedFilters
|
|
9
|
+
.map((filter, index) => (filter.type === 'datafilter' && filter.parents ? index : -1))
|
|
10
|
+
.filter(index => index !== -1)
|
|
11
|
+
if (childFilterIndexes.length === 0) return newSharedFilters
|
|
12
|
+
|
|
13
|
+
// deep copy of the shared filters
|
|
14
|
+
const updatedFilters = _.cloneDeep(newSharedFilters)
|
|
15
|
+
|
|
16
|
+
// Update each child filter
|
|
17
|
+
childFilterIndexes.forEach(childIndex => {
|
|
18
|
+
const childFilter: SharedFilter = newSharedFilters[childIndex]
|
|
19
|
+
const parentFilter: SharedFilter = newSharedFilters.find(
|
|
20
|
+
filter => String(childFilter.parents) === String(filter.key)
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if (parentFilter) {
|
|
24
|
+
// Filter dataset based on parent's active value
|
|
25
|
+
const parentsActiveValues: string[] = dataSet.filter((d: Record<string, any>) => {
|
|
26
|
+
return parentFilter.active?.includes(d[parentFilter.columnName])
|
|
27
|
+
})
|
|
28
|
+
// Get unique active values for the child filter
|
|
29
|
+
const childFilterValues = _.uniq(parentsActiveValues.map(d => d[childFilter.columnName]).filter(Boolean))
|
|
30
|
+
|
|
31
|
+
// Update the child filter if unique values exist
|
|
32
|
+
if (childFilterValues.length > 0) {
|
|
33
|
+
const isChildMultiSelect = childFilter.filterStyle === 'multi-select'
|
|
34
|
+
const activeValue = isChildMultiSelect
|
|
35
|
+
? childFilterValues
|
|
36
|
+
: childFilter.active
|
|
37
|
+
? childFilter.active
|
|
38
|
+
: childFilter.defaultValue
|
|
39
|
+
? childFilter.defaultValue
|
|
40
|
+
: childFilterValues[0]
|
|
41
|
+
updatedFilters[childIndex] = {
|
|
42
|
+
...childFilter,
|
|
43
|
+
values: childFilterValues,
|
|
44
|
+
active: activeValue
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
return updatedFilters
|
|
50
|
+
}
|
package/src/scss/main.scss
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import { getUpdateConfig } from '../helpers/getUpdateConfig'
|
|
3
|
-
import { MultiDashboardConfig } from '../types/MultiDashboard'
|
|
3
|
+
import { MultiDashboard, MultiDashboardConfig } from '../types/MultiDashboard'
|
|
4
4
|
import DashboardActions from './dashboard.actions'
|
|
5
5
|
import { devToolsWrapper } from '@cdc/core/helpers/withDevTools'
|
|
6
6
|
import { Tab } from '../types/Tab'
|
|
@@ -44,7 +44,10 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
44
44
|
const newRows = state.config.rows.map((row, i) => (i === rowIndex ? { ...row, footnotesId: id } : row))
|
|
45
45
|
return {
|
|
46
46
|
...state,
|
|
47
|
-
config:
|
|
47
|
+
config: saveMultiChanges(
|
|
48
|
+
{ ...state.config, rows: newRows, visualizations: { ...state.config.visualizations, [id]: config } },
|
|
49
|
+
state.config.activeDashboard
|
|
50
|
+
)
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
case 'ADD_NEW_DASHBOARD': {
|
|
@@ -55,7 +58,7 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
55
58
|
}
|
|
56
59
|
case 'UPDATE_CONFIG': {
|
|
57
60
|
const [config, filteredData] = getUpdateConfig(state)(...action.payload)
|
|
58
|
-
return { ...state, config, filteredData }
|
|
61
|
+
return { ...state, config: saveMultiChanges(config, state.config.activeDashboard), filteredData }
|
|
59
62
|
}
|
|
60
63
|
case 'APPLY_CONFIG': {
|
|
61
64
|
// using advanced editor. Wipe all existing data and apply new config
|
|
@@ -68,14 +71,17 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
68
71
|
if (data) acc[key] = data
|
|
69
72
|
return acc
|
|
70
73
|
}, {})
|
|
71
|
-
return { ...initialState, config, filteredData, data }
|
|
74
|
+
return { ...initialState, config: saveMultiChanges(config, state.config.activeDashboard), filteredData, data }
|
|
72
75
|
}
|
|
73
76
|
case 'SET_CONFIG': {
|
|
74
77
|
if (
|
|
75
78
|
action.payload.activeDashboard === undefined ||
|
|
76
79
|
state.config.activeDashboard === action.payload.activeDashboard
|
|
77
80
|
) {
|
|
78
|
-
return {
|
|
81
|
+
return {
|
|
82
|
+
...state,
|
|
83
|
+
config: saveMultiChanges({ ...state.config, ...action.payload }, action.payload.activeDashboard)
|
|
84
|
+
}
|
|
79
85
|
} else return state // ignore SET_CONFIG calls that have the wrong activeDashboard due to async api fetching
|
|
80
86
|
}
|
|
81
87
|
case 'SET_DATA': {
|
|
@@ -93,14 +99,10 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
93
99
|
case 'SET_SHARED_FILTERS': {
|
|
94
100
|
const newSharedFilters = action.payload
|
|
95
101
|
const newDashboardConfig = { ...state.config.dashboard, sharedFilters: newSharedFilters }
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
newMultiDashboards[saveSlot].dashboard = newDashboardConfig
|
|
100
|
-
const newState = applyMultiDashboards(state, newMultiDashboards)
|
|
101
|
-
return { ...newState, config: { ...newState.config, dashboard: newDashboardConfig } }
|
|
102
|
+
return {
|
|
103
|
+
...state,
|
|
104
|
+
config: saveMultiChanges({ ...state.config, dashboard: newDashboardConfig }, state.config.activeDashboard)
|
|
102
105
|
}
|
|
103
|
-
return { ...state, config: { ...state.config, dashboard: newDashboardConfig } }
|
|
104
106
|
}
|
|
105
107
|
case 'SET_TAB_SELECTED': {
|
|
106
108
|
return { ...state, tabSelected: action.payload }
|
|
@@ -143,7 +145,8 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
143
145
|
const label = newMultiDashboards[saveSlot].label
|
|
144
146
|
const toSave = _.pick(state.config, ['dashboard', 'visualizations', 'rows'])
|
|
145
147
|
newMultiDashboards[saveSlot] = { ...toSave, label }
|
|
146
|
-
|
|
148
|
+
const newConfig = saveMultiChanges(state.config, saveSlot)
|
|
149
|
+
return { ...state, config: newConfig }
|
|
147
150
|
}
|
|
148
151
|
case 'INITIALIZE_MULTIDASHBOARDS': {
|
|
149
152
|
const label = 'New Dashboard 1'
|
|
@@ -176,7 +179,10 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
176
179
|
newRows[rowIdx].columns[colIdx].widget = vizKey
|
|
177
180
|
return {
|
|
178
181
|
...state,
|
|
179
|
-
config:
|
|
182
|
+
config: saveMultiChanges(
|
|
183
|
+
{ ...state.config, visualizations: { ...state.config.visualizations, [vizKey]: newViz }, rows: newRows },
|
|
184
|
+
state.config.activeDashboard
|
|
185
|
+
)
|
|
180
186
|
}
|
|
181
187
|
}
|
|
182
188
|
case 'MOVE_VISUALIZATION': {
|
|
@@ -186,7 +192,7 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
186
192
|
newRows[rowIdx].columns[colIdx].widget = widget.uid
|
|
187
193
|
return {
|
|
188
194
|
...state,
|
|
189
|
-
config: { ...state.config, rows: newRows }
|
|
195
|
+
config: saveMultiChanges({ ...state.config, rows: newRows }, state.config.activeDashboard)
|
|
190
196
|
}
|
|
191
197
|
}
|
|
192
198
|
case 'UPDATE_VISUALIZATION': {
|
|
@@ -194,7 +200,10 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
194
200
|
const updatedViz = { ...state.config.visualizations[vizKey], ...configureData } as AnyVisualization
|
|
195
201
|
return {
|
|
196
202
|
...state,
|
|
197
|
-
config:
|
|
203
|
+
config: saveMultiChanges(
|
|
204
|
+
{ ...state.config, visualizations: { ...state.config.visualizations, [vizKey]: updatedViz } },
|
|
205
|
+
state.config.activeDashboard
|
|
206
|
+
)
|
|
198
207
|
}
|
|
199
208
|
}
|
|
200
209
|
case 'UPDATE_ROW': {
|
|
@@ -205,12 +214,13 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
205
214
|
}
|
|
206
215
|
return row
|
|
207
216
|
})
|
|
208
|
-
return { ...state, config: { ...state.config, rows: newRows } }
|
|
217
|
+
return { ...state, config: saveMultiChanges({ ...state.config, rows: newRows }, state.config.activeDashboard) }
|
|
209
218
|
}
|
|
210
219
|
case 'DELETE_WIDGET': {
|
|
211
220
|
const { uid } = action.payload
|
|
212
221
|
const newRows = _.cloneDeep(state.config.rows)
|
|
213
222
|
const newVisualizations = _.cloneDeep(state.config.visualizations)
|
|
223
|
+
delete newVisualizations[uid]
|
|
214
224
|
const newSharedFilters = _.cloneDeep(state.config.dashboard.sharedFilters)
|
|
215
225
|
if (newSharedFilters && newSharedFilters.length > 0) {
|
|
216
226
|
newSharedFilters.forEach(sharedFilter => {
|
|
@@ -227,12 +237,15 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
227
237
|
|
|
228
238
|
return {
|
|
229
239
|
...state,
|
|
230
|
-
config:
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
config: saveMultiChanges(
|
|
241
|
+
{
|
|
242
|
+
...state.config,
|
|
243
|
+
dashboard: { ...state.config.dashboard, sharedFilters: newSharedFilters },
|
|
244
|
+
visualizations: newVisualizations,
|
|
245
|
+
rows: filteredRows
|
|
246
|
+
},
|
|
247
|
+
state.config.activeDashboard
|
|
248
|
+
)
|
|
236
249
|
}
|
|
237
250
|
}
|
|
238
251
|
default:
|
|
@@ -240,7 +253,16 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
|
|
|
240
253
|
}
|
|
241
254
|
}
|
|
242
255
|
|
|
243
|
-
const
|
|
256
|
+
const saveMultiChanges = (config: MultiDashboardConfig, saveSlot?: number): MultiDashboardConfig => {
|
|
257
|
+
if (saveSlot === undefined || !config.multiDashboards) return config
|
|
258
|
+
const newMultiDashboards = [...config.multiDashboards]
|
|
259
|
+
const label = newMultiDashboards[saveSlot].label
|
|
260
|
+
const toSave = _.pick(config, ['dashboard', 'visualizations', 'rows'])
|
|
261
|
+
newMultiDashboards[saveSlot] = { ...toSave, label }
|
|
262
|
+
return { ...config, multiDashboards: newMultiDashboards }
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const applyMultiDashboards = (state: DashboardState, newMultiDashboards: MultiDashboard[]): DashboardState => ({
|
|
244
266
|
...state,
|
|
245
267
|
config: { ...state.config, multiDashboards: newMultiDashboards }
|
|
246
268
|
})
|
|
@@ -11,7 +11,7 @@ export type SharedFilter = FilterBase & {
|
|
|
11
11
|
active?: string | string[]
|
|
12
12
|
queuedActive?: string | string[]
|
|
13
13
|
usedBy?: (string | number)[] // if number used by whole row, else used by specific viz
|
|
14
|
-
order: 'cust' | 'desc' | 'asc'
|
|
14
|
+
order: 'cust' | 'desc' | 'asc' | 'column'
|
|
15
15
|
parents?: string[]
|
|
16
16
|
setBy?: string
|
|
17
17
|
selectLimit?: number
|