@cdc/dashboard 4.24.3 → 4.24.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 (37) hide show
  1. package/dist/cdcdashboard.js +148123 -105018
  2. package/examples/chart-data.json +5409 -0
  3. package/examples/full-dash-test.json +14643 -0
  4. package/examples/full-dashboard.json +10036 -0
  5. package/index.html +2 -2
  6. package/package.json +9 -9
  7. package/src/CdcDashboard.tsx +8 -3
  8. package/src/CdcDashboardComponent.tsx +141 -290
  9. package/src/_stories/Dashboard.stories.tsx +52 -7
  10. package/src/_stories/_mock/markup-include.json +78 -0
  11. package/src/_stories/_mock/multi-dashboards.json +914 -0
  12. package/src/_stories/_mock/multi-viz.json +378 -0
  13. package/src/_stories/_mock/pivot-filter.json +2 -2
  14. package/src/_stories/_mock/standalone-table.json +2 -0
  15. package/src/components/DataDesignerModal.tsx +145 -0
  16. package/src/components/Grid.tsx +3 -1
  17. package/src/components/Header/FilterModal.tsx +63 -33
  18. package/src/components/MultiConfigTabs/MultiTabs.tsx +3 -2
  19. package/src/components/Row.tsx +50 -25
  20. package/src/components/Toggle/Toggle.tsx +6 -7
  21. package/src/components/VisualizationRow.tsx +183 -0
  22. package/src/components/VisualizationsPanel.tsx +26 -3
  23. package/src/components/Widget.tsx +21 -103
  24. package/src/helpers/filterData.ts +1 -1
  25. package/src/helpers/getFilteredData.ts +39 -0
  26. package/src/helpers/getUpdateConfig.ts +15 -0
  27. package/src/helpers/getVizConfig.ts +31 -0
  28. package/src/helpers/getVizRowColumnLocator.ts +9 -0
  29. package/src/scss/grid.scss +9 -2
  30. package/src/scss/main.scss +5 -0
  31. package/src/store/dashboard.actions.ts +6 -0
  32. package/src/store/dashboard.reducer.ts +33 -8
  33. package/src/types/ConfigRow.ts +12 -3
  34. package/src/types/DataSet.ts +11 -8
  35. package/src/types/SharedFilter.ts +1 -1
  36. package/src/components/EditorWrapper/EditorWrapper.tsx +0 -52
  37. package/src/components/EditorWrapper/editor-wrapper.style.css +0 -13
@@ -1,17 +1,16 @@
1
- import React, { useContext, useRef, useEffect } from 'react'
1
+ import { useContext } from 'react'
2
2
  import { useDrag } from 'react-dnd'
3
3
 
4
4
  import { useGlobalContext } from '@cdc/core/components/GlobalContext'
5
5
  import { DashboardContext, DashboardDispatchContext } from '../DashboardContext'
6
6
 
7
7
  import { DataTransform } from '@cdc/core/helpers/DataTransform'
8
- import fetchRemoteData from '@cdc/core/helpers/fetchRemoteData'
9
-
10
- import DataDesigner from '@cdc/core/components/managers/DataDesigner'
11
8
  import Icon from '@cdc/core/components/ui/Icon'
12
9
  import Modal from '@cdc/core/components/ui/Modal'
13
10
  import { Visualization } from '@cdc/core/types/Visualization'
14
11
  import { iconHash } from '../helpers/iconHash'
12
+ import _ from 'lodash'
13
+ import { DataDesignerModal } from './DataDesignerModal'
15
14
 
16
15
  const labelHash = {
17
16
  'data-bite': 'Data Bite',
@@ -45,8 +44,6 @@ const Widget = ({ data, addVisualization, type }: WidgetProps) => {
45
44
  const visualizations = config.visualizations
46
45
  const dispatch = useContext(DashboardDispatchContext)
47
46
  const updateConfig = config => dispatch({ type: 'UPDATE_CONFIG', payload: [config] })
48
- const dataRef = useRef<WidgetData>()
49
- dataRef.current = data
50
47
 
51
48
  const transform = new DataTransform()
52
49
 
@@ -58,14 +55,14 @@ const Widget = ({ data, addVisualization, type }: WidgetProps) => {
58
55
  const { rowIdx, colIdx } = result
59
56
 
60
57
  if (undefined !== data?.rowIdx) {
61
- rows[data.rowIdx][data.colIdx].widget = null // Wipe from old position
58
+ rows[data.rowIdx].columns[data.colIdx].widget = null // Wipe from old position
62
59
 
63
- rows[rowIdx][colIdx].widget = data.uid // Add to new row and col
60
+ rows[rowIdx].columns[colIdx].widget = data.uid // Add to new row and col
64
61
  } else if (!!addVisualization) {
65
62
  // Item does not exist, instantiate a new one
66
63
  const newViz = addVisualization()
67
64
  visualizations[newViz.uid] = newViz // Add to widgets collection
68
- rows[rowIdx][colIdx].widget = newViz.uid // Store reference in rows collection under the specific column
65
+ rows[rowIdx].columns[colIdx].widget = newViz.uid // Store reference in rows collection under the specific column
69
66
  }
70
67
 
71
68
  updateConfig({ ...config, rows, visualizations })
@@ -84,7 +81,7 @@ const Widget = ({ data, addVisualization, type }: WidgetProps) => {
84
81
 
85
82
  const deleteWidget = () => {
86
83
  if (!data) return
87
- rows[data.rowIdx][data.colIdx].widget = null
84
+ rows[data.rowIdx].columns[data.colIdx].widget = null
88
85
 
89
86
  delete visualizations[data.uid]
90
87
 
@@ -106,78 +103,6 @@ const Widget = ({ data, addVisualization, type }: WidgetProps) => {
106
103
  updateConfig({ ...config, visualizations })
107
104
  }
108
105
 
109
- const changeDataset = (uid, value) => {
110
- visualizations[uid].dataDescription = {}
111
- visualizations[uid].formattedData = undefined
112
-
113
- visualizations[uid].dataKey = value
114
-
115
- updateConfig({ ...config, visualizations })
116
- }
117
-
118
- const updateDescriptionProp = async (visualizationKey, datasetKey, key, value) => {
119
- let dataDescription = { ...(dataRef.current?.dataDescription as Object), [key]: value }
120
-
121
- let newData
122
- if (!config.datasets[datasetKey].data && config.datasets[datasetKey].dataUrl) {
123
- newData = await fetchRemoteData(config.datasets[datasetKey].dataUrl)
124
- newData = transform.autoStandardize(newData)
125
- } else {
126
- newData = config.datasets[datasetKey].data
127
- }
128
-
129
- let formattedData = transform.developerStandardize(newData, dataDescription)
130
-
131
- let newVisualizations = { ...config.visualizations }
132
- newVisualizations[visualizationKey] = { ...newVisualizations[visualizationKey], data: newData, dataDescription, formattedData }
133
-
134
- updateConfig({ ...config, visualizations: newVisualizations })
135
-
136
- overlay?.actions.openOverlay(dataDesignerModal(newVisualizations[visualizationKey]))
137
- }
138
-
139
- const dataDesignerModal = (configureData, dataKeyOverride?) => {
140
- const dataKey = !dataKeyOverride && dataKeyOverride !== '' ? data?.dataKey || dataRef.current?.dataKey : dataKeyOverride
141
-
142
- overlay?.actions.toggleOverlay()
143
-
144
- return (
145
- <Modal>
146
- <Modal.Content>
147
- <div className='dataset-selector-container'>
148
- Select a dataset:&nbsp;
149
- <select
150
- className='dataset-selector'
151
- defaultValue={dataKey}
152
- onChange={e => {
153
- changeDataset(data?.uid, e.target.value)
154
- overlay?.actions.openOverlay(dataDesignerModal(data, e.target.value || ''))
155
- }}
156
- >
157
- <option value=''>Select a dataset</option>
158
- {config.datasets && Object.keys(config.datasets).map(datasetKey => <option key={datasetKey}>{datasetKey}</option>)}
159
- </select>
160
- </div>
161
- {dataKey && (
162
- <DataDesigner
163
- {...{
164
- configureData,
165
- visualizationKey: data?.uid,
166
- dataKey: dataKey,
167
- updateDescriptionProp
168
- }}
169
- />
170
- )}
171
- {configureData.formattedData && (
172
- <button style={{ margin: '1em' }} className='cove-button' onClick={() => overlay?.actions.toggleOverlay()}>
173
- Continue
174
- </button>
175
- )}
176
- </Modal.Content>
177
- </Modal>
178
- )
179
- }
180
-
181
106
  const FilterHideModal = configureData => {
182
107
  const currentVizKey = Object.keys(visualizations).find(vizKey => vizKey === configureData.uid) || ''
183
108
  const currentViz = config.visualizations && config.visualizations[currentVizKey]
@@ -208,8 +133,6 @@ const Widget = ({ data, addVisualization, type }: WidgetProps) => {
208
133
  }
209
134
  }
210
135
 
211
- overlay?.actions.toggleOverlay()
212
-
213
136
  const showAutoLoadCheckbox = !vizWithAutoLoad || vizWithAutoLoad === currentVizKey
214
137
  return (
215
138
  <Modal>
@@ -243,29 +166,24 @@ const Widget = ({ data, addVisualization, type }: WidgetProps) => {
243
166
  )
244
167
  }
245
168
 
246
- useEffect(() => {
247
- if (data?.openModal) {
248
- overlay?.actions.openOverlay(type === 'filter-dropdowns' ? FilterHideModal(dataRef.current) : dataDesignerModal(dataRef.current))
249
-
250
- visualizations[data.uid].openModal = false
251
-
252
- updateConfig({ ...config, visualizations })
253
- }
254
- }, [data?.openModal])
255
-
256
169
  let isConfigurationReady = false
257
- if (type === 'markup-include' || type === 'filter-dropdowns') {
258
- isConfigurationReady = true
259
- } else if (data && data.formattedData) {
170
+ const dataConfiguredForRow = !!rows[data?.rowIdx]?.dataKey
171
+ if (dataConfiguredForRow || ['filter-dropdowns', 'markup-include'].includes(type)) {
260
172
  isConfigurationReady = true
261
- } else if (data && data.dataKey && data.dataDescription && config.datasets[data.dataKey]) {
262
- let formattedDataAttempt = transform.autoStandardize(config.datasets[data.dataKey].data)
263
- formattedDataAttempt = transform.developerStandardize(formattedDataAttempt, data.dataDescription)
264
- if (formattedDataAttempt) {
173
+ } else {
174
+ if (data?.formattedData) {
265
175
  isConfigurationReady = true
176
+ } else if (data?.dataKey && data?.dataDescription && config.datasets[data.dataKey]) {
177
+ const formattedDataAttempt = transform.autoStandardize(config.datasets[data.dataKey].data)
178
+ const canFormatData = !!transform.developerStandardize(formattedDataAttempt, data.dataDescription)
179
+ if (canFormatData) {
180
+ isConfigurationReady = true
181
+ }
266
182
  }
267
183
  }
268
184
 
185
+ const needsDataConfiguration = !dataConfiguredForRow
186
+
269
187
  return (
270
188
  <>
271
189
  <div className='widget' ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }} {...collected}>
@@ -278,12 +196,12 @@ const Widget = ({ data, addVisualization, type }: WidgetProps) => {
278
196
  {iconHash['tools']}
279
197
  </button>
280
198
  )}
281
- {type !== 'markup-include' && (
199
+ {needsDataConfiguration && (
282
200
  <button
283
201
  title='Configure Data'
284
202
  className='btn btn-configure'
285
203
  onClick={() => {
286
- overlay?.actions.openOverlay(type === 'filter-dropdowns' ? FilterHideModal(data) : dataDesignerModal(data))
204
+ overlay?.actions.openOverlay(type === 'filter-dropdowns' ? FilterHideModal(data) : <DataDesignerModal rowIndex={data.rowIdx} vizKey={data.uid} />)
287
205
  }}
288
206
  >
289
207
  {iconHash['gear']}
@@ -66,7 +66,7 @@ const pivotData = (data, pivotFilter: SharedFilter) => {
66
66
  const row = newData[index] || {}
67
67
  if (!inactive.includes(key)) row[key] = val[valueColumn]
68
68
  const toAdd = _.omit(val, [pivotColumn, valueColumn, ...inactive])
69
- newData[index] = { ...row, ...toAdd }
69
+ newData[index] = { ...toAdd, ...row }
70
70
  })
71
71
  }
72
72
  return newData
@@ -0,0 +1,39 @@
1
+ import { DashboardState } from '../store/dashboard.reducer'
2
+ import { Dashboard } from '../types/Dashboard'
3
+ import { SharedFilter } from '../types/SharedFilter'
4
+ import { filterData } from './filterData'
5
+ import { getFormattedData } from './getFormattedData'
6
+ import { getVizKeys } from './getVizKeys'
7
+
8
+ export const getApplicableFilters = (dashboard: Dashboard, key: string | number): false | SharedFilter[] => {
9
+ const c = dashboard.sharedFilters?.filter(sharedFilter => sharedFilter.usedBy && sharedFilter.usedBy.indexOf(`${key}`) !== -1)
10
+ return c?.length > 0 ? c : false
11
+ }
12
+
13
+ export const getFilteredData = (state: DashboardState, initialFilteredData = {}, dataOverride?: Object) => {
14
+ const newFilteredData = initialFilteredData
15
+ const { config } = state
16
+ getVizKeys(config).forEach(key => {
17
+ const applicableFilters = getApplicableFilters(config.dashboard, key)
18
+ if (applicableFilters) {
19
+ const { dataKey, data, dataDescription } = config.visualizations[key]
20
+ const _data = state.data[dataKey] || data
21
+ const formattedData = dataOverride?.[dataKey] || (dataDescription ? getFormattedData(_data, dataDescription) : _data)
22
+
23
+ newFilteredData[key] = filterData(applicableFilters, formattedData)
24
+ }
25
+ })
26
+ config.rows.forEach((row, index) => {
27
+ if (row.dataKey) {
28
+ const applicableFilters = getApplicableFilters(config.dashboard, index)
29
+ if (applicableFilters) {
30
+ const { dataKey, data, dataDescription } = row
31
+ const _data = state.data[dataKey] || data
32
+ const formattedData = dataOverride?.[dataKey] ?? dataDescription ? getFormattedData(_data, dataDescription) : _data
33
+
34
+ newFilteredData[index] = filterData(applicableFilters, formattedData)
35
+ }
36
+ }
37
+ })
38
+ return newFilteredData
39
+ }
@@ -4,6 +4,7 @@ import { filterData } from './filterData'
4
4
  import { generateValuesForFilter } from './generateValuesForFilter'
5
5
  import { getFormattedData } from './getFormattedData'
6
6
  import { getVizKeys } from './getVizKeys'
7
+ import { getVizRowColumnLocator } from './getVizRowColumnLocator'
7
8
 
8
9
  import { getQueryStringFilterValue } from '@cdc/core/helpers/queryStringUtils'
9
10
 
@@ -17,6 +18,8 @@ export const getUpdateConfig =
17
18
  let newFilteredData = {}
18
19
  let visualizationKeys = getVizKeys(newConfig)
19
20
 
21
+ const vizRowColumnLocator = getVizRowColumnLocator(newConfig.rows)
22
+
20
23
  if (newConfig.dashboard.sharedFilters) {
21
24
  newConfig.dashboard.sharedFilters.forEach((filter, i) => {
22
25
  const filterIsSetByVizData = !!visualizationKeys.find(key => key === filter.setBy)
@@ -52,6 +55,8 @@ export const getUpdateConfig =
52
55
  })
53
56
 
54
57
  visualizationKeys.forEach(visualizationKey => {
58
+ const row = vizRowColumnLocator[visualizationKey]
59
+ if (newConfig.rows[row]?.datakey) return // data configured on the row level
55
60
  const applicableFilters = newConfig.dashboard.sharedFilters.filter(sharedFilter => sharedFilter.usedBy && sharedFilter.usedBy.indexOf(visualizationKey) !== -1)
56
61
 
57
62
  if (applicableFilters.length > 0) {
@@ -62,6 +67,16 @@ export const getUpdateConfig =
62
67
  newFilteredData[visualizationKey] = filterData(applicableFilters, _data)
63
68
  }
64
69
  })
70
+
71
+ newConfig.rows.forEach((row, rowIndex) => {
72
+ const applicableFilters = newConfig.dashboard.sharedFilters.filter(sharedFilter => sharedFilter.usedBy && sharedFilter.usedBy.indexOf(rowIndex) !== -1)
73
+
74
+ if (applicableFilters.length > 0) {
75
+ const formattedData = getFormattedData(row.data, row.dataDescription)
76
+ const _data = formattedData || (dataOverride || state.data)[rowIndex]
77
+ newFilteredData[rowIndex] = filterData(applicableFilters, _data)
78
+ }
79
+ })
65
80
  }
66
81
  //Enforce default values that need to be calculated at runtime
67
82
  newConfig.runtime = {}
@@ -0,0 +1,31 @@
1
+ import _ from 'lodash'
2
+ import { MultiDashboardConfig } from '../types/MultiDashboard'
3
+ import DataTransform from '@cdc/core/helpers/DataTransform'
4
+
5
+ const transform = new DataTransform()
6
+
7
+ export const getVizConfig = (visualizationKey: string, rowNumber: number, config: MultiDashboardConfig, data: Object, filteredData?: Object) => {
8
+ const visualizationConfig = _.cloneDeep(config.visualizations[visualizationKey])
9
+ const rowData = config.rows[rowNumber]
10
+ if (rowData?.dataKey) {
11
+ // data configured on the row
12
+ Object.assign(visualizationConfig, _.pick(rowData, ['dataKey', 'dataDescription', 'formattedData', 'data']))
13
+ }
14
+
15
+ if (visualizationConfig.formattedData) visualizationConfig.originalFormattedData = visualizationConfig.formattedData
16
+ const filteredVizData = filteredData?.[rowNumber] ?? filteredData?.[visualizationKey]
17
+
18
+ if (filteredVizData) {
19
+ visualizationConfig.data = filteredVizData
20
+ if (visualizationConfig.formattedData) {
21
+ visualizationConfig.formattedData = visualizationConfig.data
22
+ }
23
+ } else {
24
+ const dataKey = visualizationConfig.dataKey || 'backwards-compatibility'
25
+ visualizationConfig.data = data[dataKey]
26
+ if (visualizationConfig.formattedData) {
27
+ visualizationConfig.formattedData = transform.developerStandardize(visualizationConfig.data, visualizationConfig.dataDescription) || visualizationConfig.data
28
+ }
29
+ }
30
+ return visualizationConfig
31
+ }
@@ -0,0 +1,9 @@
1
+ import { ConfigRow } from '../types/ConfigRow'
2
+
3
+ export const getVizRowColumnLocator = (rows: ConfigRow[]) =>
4
+ rows.reduce((acc, curr, index) => {
5
+ curr.columns?.forEach((column, columnIndex) => {
6
+ if (column.widget !== undefined) acc[column.widget] = { row: index, column: columnIndex }
7
+ })
8
+ return acc
9
+ }, {})
@@ -35,8 +35,7 @@ $red: #f74242;
35
35
  flex-flow: row;
36
36
  width: 100%;
37
37
  position: relative;
38
- top: 0;
39
- padding: 1em;
38
+ padding: 2em 1em 1em;
40
39
  border: 1px solid #c2c2c2;
41
40
  transition: border 300ms cubic-bezier(0.16, 1, 0.3, 1);
42
41
  background-color: #f2f2f2;
@@ -330,6 +329,14 @@ $red: #f74242;
330
329
  .builder-row {
331
330
  position: relative;
332
331
 
332
+ .btn-configure-row {
333
+ background: none;
334
+ display: block;
335
+ position: absolute;
336
+ right: 1em;
337
+ top: 0;
338
+ }
339
+
333
340
  .widget__content {
334
341
  padding: 0 2em;
335
342
 
@@ -10,6 +10,11 @@
10
10
  margin-top: 20%;
11
11
  }
12
12
 
13
+ > .cove-editor__content {
14
+ width: 100% !important;
15
+ left: 0px;
16
+ }
17
+
13
18
  .editor-heading {
14
19
  background-color: #ddd;
15
20
  border-bottom: #c7c7c7 1px solid;
@@ -1,6 +1,8 @@
1
1
  import type { DashboardConfig as Config } from '../types/DashboardConfig'
2
2
  import { type Action } from '@cdc/core/types/Action'
3
3
  import { Tab } from '../types/Tab'
4
+ import { ConfigureData } from '@cdc/core/types/ConfigureData'
5
+ import { ConfigRow } from '../types/ConfigRow'
4
6
 
5
7
  type SET_CONFIG = Action<'SET_CONFIG', Config>
6
8
  type UPDATE_CONFIG = Action<'UPDATE_CONFIG', [Config, Object?]>
@@ -17,6 +19,8 @@ type ADD_NEW_DASHBOARD = Action<'ADD_NEW_DASHBOARD', undefined>
17
19
  type SAVE_CURRENT_CHANGES = Action<'SAVE_CURRENT_CHANGES', undefined>
18
20
  type SWITCH_CONFIG = Action<'SWITCH_CONFIG', number>
19
21
  type TOGGLE_ROW = Action<'TOGGLE_ROW', { rowIndex: number; colIndex: number }>
22
+ type UPDATE_VISUALIZATION = Action<'UPDATE_VISUALIZATION', { vizKey: string; configureData: Partial<ConfigureData> }>
23
+ type UPDATE_ROW = Action<'UPDATE_ROW', { rowIndex: number; rowData: Partial<ConfigRow> }>
20
24
 
21
25
  type DashboardActions =
22
26
  | ADD_NEW_DASHBOARD
@@ -34,4 +38,6 @@ type DashboardActions =
34
38
  | SWITCH_CONFIG
35
39
  | INITIALIZE_MULTIDASHBOARDS
36
40
  | TOGGLE_ROW
41
+ | UPDATE_VISUALIZATION
42
+ | UPDATE_ROW
37
43
  export default DashboardActions
@@ -1,19 +1,26 @@
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'
7
+ import { DashboardConfig } from '../types/DashboardConfig'
8
+ import { ConfigRow } from '../types/ConfigRow'
7
9
 
8
- const createBlankDashboard = () => ({
9
- dashboard: {
10
- theme: 'theme-blue'
11
- },
12
- rows: [[{ width: 12 }, {}, {}]],
10
+ type BlankMultiConfig = {
11
+ dashboard: Partial<DashboardConfig>
12
+ rows: Partial<ConfigRow>[]
13
+ visualizations: Record<string, Object>
14
+ table: Object
15
+ }
16
+
17
+ const createBlankDashboard: () => BlankMultiConfig = () => ({
18
+ dashboard: {},
19
+ rows: [{ columns: [{ width: 12 }] }],
13
20
  visualizations: {},
14
21
  table: {
15
22
  label: 'Data Table',
16
- show: true,
23
+ show: false,
17
24
  showDownloadUrl: false,
18
25
  showVertical: true
19
26
  }
@@ -107,7 +114,25 @@ const reducer = (state: DashboardState, action: DashboardActions): DashboardStat
107
114
  case 'TOGGLE_ROW': {
108
115
  const { rowIndex, colIndex } = action.payload
109
116
  const newRows = state.config.rows.map((row, index) => {
110
- return index === rowIndex ? row.map((col, i) => ({ ...col, hide: i !== colIndex })) : row
117
+ if (index === rowIndex) {
118
+ const newColumns = row.columns.map((col, i) => ({ ...col, hide: i === colIndex }))
119
+ return { ...row, columns: newColumns }
120
+ }
121
+ return row
122
+ })
123
+ return { ...state, config: { ...state.config, rows: newRows } }
124
+ }
125
+ case 'UPDATE_VISUALIZATION': {
126
+ const { vizKey, configureData } = action.payload
127
+ return { ...state, config: { ...state.config, visualizations: { ...state.config.visualizations, [vizKey]: { ...state.config.visualizations[vizKey], ...configureData } } } }
128
+ }
129
+ case 'UPDATE_ROW': {
130
+ const { rowIndex, rowData } = action.payload
131
+ const newRows = state.config.rows.map((row, index) => {
132
+ if (index === rowIndex) {
133
+ return { ...row, ...rowData }
134
+ }
135
+ return row
111
136
  })
112
137
  return { ...state, config: { ...state.config, rows: newRows } }
113
138
  }
@@ -1,8 +1,17 @@
1
- export type ConfigRow = {
1
+ import { ConfigureData } from '@cdc/core/types/ConfigureData'
2
+
3
+ type Col = {
2
4
  equalHeight?: boolean
3
5
  width: number | null
4
- toggle?: boolean
5
6
  hide?: boolean
6
7
  widget?: string
7
8
  uuid?: string | number
8
- }[] & { uuid?: string | number }
9
+ }
10
+
11
+ export type ConfigRow = {
12
+ columns: Col[]
13
+ uuid?: string | number
14
+ toggle?: boolean
15
+ equalHeight?: boolean
16
+ multiVizColumn?: string
17
+ } & ConfigureData
@@ -1,8 +1,11 @@
1
- export type DataSet = {
2
- data: Object[]
3
- dataDescription: {}
4
- dataUrl: string
5
- runtimeDataUrl: string
6
- dataFileSourceType: string
7
- formattedData: Object[]
8
- }
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
+ }
@@ -7,7 +7,7 @@ export type SharedFilter = {
7
7
  setByQueryParameter?: string
8
8
  active?: string | string[]
9
9
  queuedActive?: string
10
- usedBy?: string[]
10
+ usedBy?: (string | number)[] // if number used by whole row, else used by specific viz
11
11
  parents?: string[]
12
12
  pivot?: string
13
13
  setBy?: string
@@ -1,52 +0,0 @@
1
- import React from 'react'
2
- import { Accordion } from 'react-accessible-accordion'
3
- import Header from '../Header'
4
- import { Visualization } from '@cdc/core/types/Visualization'
5
- import { ViewPort } from '@cdc/core/types/ViewPort'
6
- import './editor-wrapper.style.css'
7
-
8
- type StandAloneComponentProps = {
9
- visualizationKey: string
10
- config: Visualization
11
- isEditor: boolean
12
- setConfig: Function
13
- isDashboard: boolean
14
- configUrl: string
15
- setEditing: Function
16
- hostname: string
17
- viewport?: ViewPort
18
- }
19
-
20
- type EditorProps = {
21
- component: React.JSXElementConstructor<StandAloneComponentProps>
22
- type: string
23
- visualizationKey: string
24
- visualizationConfig: Visualization
25
- updateConfig: Function
26
- viewport?: ViewPort
27
- }
28
-
29
- const EditorWrapper: React.FC<React.PropsWithChildren<EditorProps>> = ({ children, visualizationKey, visualizationConfig, type, component: Component, updateConfig, viewport }) => {
30
- const [displayPanel, setDisplayPanel] = React.useState(true)
31
- return (
32
- <>
33
- <Header visualizationKey={visualizationKey} subEditor={type} />
34
- <div className='editor-wrapper'>
35
- <button className={`editor-toggle ${displayPanel ? '' : 'collapsed'}`} title={displayPanel ? `Collapse Editor` : `Expand Editor`} onClick={() => setDisplayPanel(!displayPanel)} />
36
- <section className={`${displayPanel ? '' : 'hidden'} editor-panel cove`}>
37
- <div aria-level={2} role='heading' className='heading-2'>
38
- Configure {type}
39
- </div>
40
- <form>
41
- <Accordion allowZeroExpanded={true}>{children}</Accordion>
42
- </form>
43
- </section>
44
- <div className='preview-wrapper'>
45
- <Component visualizationKey={visualizationKey} config={visualizationConfig} isEditor={true} setConfig={updateConfig} isDashboard={true} configUrl={undefined} setEditing={undefined} hostname={undefined} viewport={viewport} />
46
- </div>
47
- </div>
48
- </>
49
- )
50
- }
51
-
52
- export default EditorWrapper
@@ -1,13 +0,0 @@
1
- .editor-wrapper {
2
- --editorPanelWidth: 350px;
3
- position: relative;
4
- .editor-panel {
5
- :is(form) {
6
- border-right: var(--lightGray) 1px solid;
7
- flex-grow: 1;
8
- }
9
- }
10
- .preview-wrapper {
11
- padding-left: var(--editorPanelWidth);
12
- }
13
- }