-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathCdcDashboard.tsx
144 lines (124 loc) · 5.29 KB
/
CdcDashboard.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import { useContext, useEffect, useState } from 'react'
import CdcDashboard from './CdcDashboardComponent'
import { MultiDashboardConfig } from './types/MultiDashboard'
import Loading from '@cdc/core/components/Loading'
import defaults from './data/initial-state'
import { getVizKeys } from './helpers/getVizKeys'
import { processDataLegacy } from './helpers/processDataLegacy'
import { WCMSProps } from '@cdc/core/types/WCMSProps'
import { initialState } from './DashboardContext'
import { getUpdateConfig } from './helpers/getUpdateConfig'
import { InitialState } from './types/InitialState'
import { DashboardConfig } from './types/DashboardConfig'
import { coveUpdateWorker } from '@cdc/core/helpers/coveUpdateWorker'
import _ from 'lodash'
import { getQueryParams } from '@cdc/core/helpers/queryStringUtils'
import EditorContext from '../../editor/src/ConfigContext'
type MultiDashboardProps = Omit<WCMSProps, 'configUrl'> & {
configUrl?: string
config?: MultiDashboardConfig
}
const MultiDashboardWrapper: React.FC<MultiDashboardProps> = ({ configUrl, isEditor, isDebug }) => {
const [initial, setInitial] = useState<InitialState>(undefined)
const editorContext = useContext(EditorContext)
const getSelectedConfig = (config: MultiDashboardConfig): number | null => {
if (!config.multiDashboards) return null
// if query parameter, select based on query parameter
const selectedConfig = getQueryParams()['cove-tab']
if (selectedConfig !== undefined && Number(selectedConfig) < config.multiDashboards.length) {
return Number(selectedConfig)
}
// else select the first available
return 0
}
const formatInitialState = (
newConfig: MultiDashboardConfig | DashboardConfig,
datasets: Record<string, Object[]>
) => {
const [config, filteredData] = getUpdateConfig(initialState)(newConfig, datasets)
const versionedConfig = coveUpdateWorker(config)
return { ...initialState, config: versionedConfig, filteredData, data: datasets }
}
const loadConfig = async () => {
const _config: MultiDashboardConfig = editorContext.config || (await (await fetch(configUrl)).json())
const selected = getSelectedConfig(_config)
const { newConfig, datasets } =
selected !== null ? await loadMultiDashboard(_config, selected) : await loadSingleDashboard(_config)
setInitial(formatInitialState(newConfig, datasets))
}
useEffect(() => {
loadConfig()
}, [])
const prepareDatasets = (initialConfig: DashboardConfig | MultiDashboardConfig) => {
let newConfig = { ...initialConfig }
const datasets: Record<string, Object[]> = Object.keys(initialConfig.datasets).reduce((acc, key) => {
const dataset = initialConfig.datasets[key]
acc[key] = dataset.formattedData || dataset.data
return acc
}, {})
getVizKeys(newConfig).forEach(vizKey => {
const formattedData = datasets[newConfig.visualizations[vizKey].dataKey]
if (formattedData) {
newConfig.visualizations[vizKey].formattedData = formattedData
}
})
Object.keys(datasets).forEach(key => {
newConfig.datasets[key].data = datasets[key]
})
return { newConfig, datasets }
}
const loadSingleDashboard = async config => {
let newConfig = { ...defaults, ...config } as DashboardConfig
if (config.datasets) {
return prepareDatasets(newConfig)
} else {
const dataKey = newConfig.dataFileName || 'backwards-compatibility'
const data = await processDataLegacy(config)
const datasetsFull = {}
datasetsFull[dataKey] = {
data,
dataDescription: newConfig.dataDescription
}
newConfig.datasets = datasetsFull
getVizKeys(newConfig).forEach(vizKey => {
const newData = { dataKey, ..._.pick(newConfig, 'dataDescription', 'formattedData') }
newConfig.visualizations[vizKey] = { ...newConfig.visualizations[vizKey], ...newData }
})
const blankFields = {
data: [],
dataUrl: '',
dataFileName: '',
dataFileSourceType: '',
dataDescription: {},
formattedData: []
}
newConfig = { ...newConfig, ...blankFields }
if (newConfig.dashboard.filters) {
const dashboard = { ...newConfig.dashboard }
// replace filters with sharedFilters
if (!dashboard.sharedFilters) dashboard.sharedFilters = []
const filters = dashboard.filters.map(filter => {
return { ...filter, key: filter.label, showDropdown: true, usedBy: getVizKeys(newConfig) }
})
dashboard.sharedFilters = [...dashboard.sharedFilters, ...filters]
newConfig.dashboard = { ...dashboard, filters: undefined }
}
const datasets: Record<string, Object[]> = { [dataKey]: data }
return { newConfig, datasets }
}
}
const loadMultiDashboard = async (multiConfig: MultiDashboardConfig, selectedConfig: number) => {
const selectedDashboard = multiConfig.multiDashboards[selectedConfig]
const newConfig = {
...defaults,
...multiConfig,
...selectedDashboard,
multiDashboards: multiConfig.multiDashboards,
activeDashboard: selectedConfig
} as MultiDashboardConfig
return prepareDatasets(newConfig)
}
if (!initial) return <Loading />
return <CdcDashboard isEditor={isEditor} isDebug={isDebug} initialState={initial} />
}
export default MultiDashboardWrapper