@cdc/dashboard 4.22.10 → 4.23.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/README.md +36 -36
- package/dist/495.js +3 -0
- package/dist/703.js +1 -0
- package/dist/cdcdashboard.js +2405 -134
- package/examples/default-data.json +367 -367
- package/examples/default-filter-control.json +205 -174
- package/examples/default-multi-dataset.json +505 -497
- package/examples/default.json +161 -155
- package/examples/private/chart-issue.json +3462 -3466
- package/examples/private/no-issue.json +3462 -3466
- package/examples/private/totals-two.json +103 -103
- package/examples/private/totals.json +102 -102
- package/examples/temp-example-data.json +1 -1
- package/examples/test-example.json +163 -1
- package/package.json +7 -7
- package/src/CdcDashboard.js +200 -124
- package/src/CdcDashboard.jsx +292 -279
- package/src/ConfigContext.js +3 -3
- package/src/components/Column.jsx +10 -9
- package/src/components/DataTable.tsx +97 -108
- package/src/components/EditorPanel.js +184 -246
- package/src/components/Grid.jsx +8 -4
- package/src/components/Header.jsx +244 -119
- package/src/components/Row.js +30 -29
- package/src/components/Row.jsx +36 -52
- package/src/components/Widget.js +68 -61
- package/src/components/Widget.jsx +85 -62
- package/src/data/initial-state.js +5 -10
- package/src/index.html +3 -3
- package/src/index.js +12 -12
- package/src/scss/editor-panel.scss +494 -489
- package/src/scss/grid.scss +20 -19
- package/src/scss/main.scss +66 -17
- package/src/scss/variables.scss +1 -1
package/src/components/Row.jsx
CHANGED
|
@@ -29,11 +29,11 @@ const RowMenu = ({ rowIdx, row }) => {
|
|
|
29
29
|
return res.join('')
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const [
|
|
33
|
-
const [
|
|
32
|
+
const [curr, setCurr] = useState(getCurr())
|
|
33
|
+
const [equalHeight, setEqualHeight] = useState(false)
|
|
34
34
|
|
|
35
|
-
const setRowLayout =
|
|
36
|
-
const newRows = [
|
|
35
|
+
const setRowLayout = layout => {
|
|
36
|
+
const newRows = [...rows]
|
|
37
37
|
const r = newRows[rowIdx]
|
|
38
38
|
|
|
39
39
|
for (let i = 0; i < r.length; i++) {
|
|
@@ -64,8 +64,8 @@ const RowMenu = ({ rowIdx, row }) => {
|
|
|
64
64
|
let calcRowMove = dir === 'down' ? 202 : -202
|
|
65
65
|
let calcRowMove2 = dir === 'down' ? -202 : 202
|
|
66
66
|
|
|
67
|
-
let rowEle = document.querySelector(
|
|
68
|
-
let rowNewEle = document.querySelector(
|
|
67
|
+
let rowEle = document.querySelector("[data-row-id='" + rowIdx + "']")
|
|
68
|
+
let rowNewEle = document.querySelector("[data-row-id='" + newIdx + "']")
|
|
69
69
|
|
|
70
70
|
rowEle.style.pointerEvents = 'none'
|
|
71
71
|
rowNewEle.style.pointerEvents = 'none'
|
|
@@ -98,68 +98,50 @@ const RowMenu = ({ rowIdx, row }) => {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
const layoutList = [
|
|
101
|
-
<li className={curr === '12' ? `current row-menu__list--item` : `row-menu__list--item`}
|
|
102
|
-
|
|
103
|
-
<OneColIcon/>
|
|
101
|
+
<li className={curr === '12' ? `current row-menu__list--item` : `row-menu__list--item`} onClick={() => setRowLayout([12])} key='12' title='1 Column'>
|
|
102
|
+
<OneColIcon />
|
|
104
103
|
</li>,
|
|
105
|
-
<li className={curr === '66' ? `current row-menu__list--item` : `row-menu__list--item`}
|
|
106
|
-
|
|
107
|
-
<TwoColIcon/>
|
|
104
|
+
<li className={curr === '66' ? `current row-menu__list--item` : `row-menu__list--item`} onClick={() => setRowLayout([6, 6])} key='66' title='2 Columns'>
|
|
105
|
+
<TwoColIcon />
|
|
108
106
|
</li>,
|
|
109
|
-
<li className={curr === '444' ? `current row-menu__list--item` : `row-menu__list--item`}
|
|
110
|
-
|
|
111
|
-
<ThreeColIcon/>
|
|
107
|
+
<li className={curr === '444' ? `current row-menu__list--item` : `row-menu__list--item`} onClick={() => setRowLayout([4, 4, 4])} key='444' title='3 Columns'>
|
|
108
|
+
<ThreeColIcon />
|
|
112
109
|
</li>,
|
|
113
|
-
<li className={curr === '48' ? `current row-menu__list--item` : `row-menu__list--item`}
|
|
114
|
-
|
|
115
|
-
<FourEightColIcon/>
|
|
110
|
+
<li className={curr === '48' ? `current row-menu__list--item` : `row-menu__list--item`} onClick={() => setRowLayout([4, 8])} key='48' title='2 Columns'>
|
|
111
|
+
<FourEightColIcon />
|
|
116
112
|
</li>,
|
|
117
|
-
<li className={curr === '84' ? `current row-menu__list--item` : `row-menu__list--item`}
|
|
118
|
-
|
|
119
|
-
<EightFourColIcon/>
|
|
113
|
+
<li className={curr === '84' ? `current row-menu__list--item` : `row-menu__list--item`} onClick={() => setRowLayout([8, 4])} key='84' title='2 Columns'>
|
|
114
|
+
<EightFourColIcon />
|
|
120
115
|
</li>
|
|
121
116
|
]
|
|
122
117
|
|
|
123
118
|
const rowSettings = (
|
|
124
119
|
<Modal>
|
|
125
|
-
<Modal.Header>
|
|
126
|
-
Row Settings
|
|
127
|
-
</Modal.Header>
|
|
120
|
+
<Modal.Header>Row Settings</Modal.Header>
|
|
128
121
|
<Modal.Content>
|
|
129
|
-
<InputToggle
|
|
130
|
-
label="Visualizations in this row should be equal height"
|
|
131
|
-
fieldName={`toggleEqualHeight${rowIdx}`}
|
|
132
|
-
value={row.equalHeight ? row.equalHeight : false}
|
|
133
|
-
updateField={rowItemsHeight}
|
|
134
|
-
></InputToggle>
|
|
122
|
+
<InputToggle label='Visualizations in this row should be equal height' fieldName={`toggleEqualHeight${rowIdx}`} value={row.equalHeight ? row.equalHeight : false} updateField={rowItemsHeight}></InputToggle>
|
|
135
123
|
</Modal.Content>
|
|
136
124
|
</Modal>
|
|
137
125
|
)
|
|
138
126
|
|
|
139
127
|
return (
|
|
140
|
-
<nav className=
|
|
141
|
-
<div className=
|
|
142
|
-
<ul className=
|
|
143
|
-
{layoutList}
|
|
144
|
-
</ul>
|
|
128
|
+
<nav className='row-menu'>
|
|
129
|
+
<div className='row-menu__btn'>
|
|
130
|
+
<ul className='row-menu__flyout'>{layoutList}</ul>
|
|
145
131
|
</div>
|
|
146
|
-
<div className=
|
|
132
|
+
<div className='spacer'></div>
|
|
147
133
|
{/*<button className={'row-menu__btn'} title="Row Settings"*/}
|
|
148
134
|
{/* onClick={() => overlay?.actions.openOverlay(rowSettings)}>*/}
|
|
149
135
|
{/* <Icon display="edit" color="#fff" size={25}/>*/}
|
|
150
136
|
{/*</button>*/}
|
|
151
|
-
<button className={rowIdx === 0 ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'} title=
|
|
152
|
-
|
|
153
|
-
<Icon display="caretUp" color="#fff" size={25}/>
|
|
137
|
+
<button className={rowIdx === 0 ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'} title='Move Row Up' onClick={() => moveRow('up')}>
|
|
138
|
+
<Icon display='caretUp' color='#fff' size={25} />
|
|
154
139
|
</button>
|
|
155
|
-
<button className={rowIdx + 1 === rows.length ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'}
|
|
156
|
-
|
|
157
|
-
<Icon display="caretDown" color="#fff" size={25}/>
|
|
140
|
+
<button className={rowIdx + 1 === rows.length ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'} title='Move Row Down' onClick={() => moveRow('down')}>
|
|
141
|
+
<Icon display='caretDown' color='#fff' size={25} />
|
|
158
142
|
</button>
|
|
159
|
-
<button
|
|
160
|
-
|
|
161
|
-
title="Delete Row" onClick={deleteRow}>
|
|
162
|
-
<Icon display="close" color="#fff" size={25}/>
|
|
143
|
+
<button className={rowIdx === 0 && rows.length === 1 ? 'row-menu__btn row-menu__btn--remove row-menu__btn-disabled' : 'row-menu__btn row-menu__btn--remove'} title='Delete Row' onClick={deleteRow}>
|
|
144
|
+
<Icon display='close' color='#fff' size={25} />
|
|
163
145
|
</button>
|
|
164
146
|
</nav>
|
|
165
147
|
)
|
|
@@ -167,12 +149,14 @@ const RowMenu = ({ rowIdx, row }) => {
|
|
|
167
149
|
|
|
168
150
|
const Row = ({ row, idx: rowIdx, uuid }) => {
|
|
169
151
|
return (
|
|
170
|
-
<div className=
|
|
171
|
-
<RowMenu rowIdx={rowIdx} row={row}/>
|
|
172
|
-
<div className=
|
|
173
|
-
{row
|
|
174
|
-
|
|
175
|
-
|
|
152
|
+
<div className='builder-row' data-row-id={rowIdx}>
|
|
153
|
+
<RowMenu rowIdx={rowIdx} row={row} />
|
|
154
|
+
<div className='column-container'>
|
|
155
|
+
{row
|
|
156
|
+
.filter(column => column.width)
|
|
157
|
+
.map((column, colIdx) => (
|
|
158
|
+
<Column data={column} key={`row-${uuid}-col-${colIdx}`} rowIdx={rowIdx} colIdx={colIdx} />
|
|
159
|
+
))}
|
|
176
160
|
</div>
|
|
177
161
|
</div>
|
|
178
162
|
)
|
package/src/components/Widget.js
CHANGED
|
@@ -1,50 +1,49 @@
|
|
|
1
|
-
import React, { useContext } from 'react'
|
|
2
|
-
import { useDrag } from 'react-dnd'
|
|
3
|
-
import CloseIcon from '../images/icon-close.svg'
|
|
4
|
-
import GridIcon from '../images/icon-grid.svg'
|
|
5
|
-
import CodeIcon from '../images/icon-code.svg'
|
|
6
|
-
import EditIcon from '../images/icon-edit.svg'
|
|
7
|
-
import MoveIcon from '../images/icon-move.svg'
|
|
8
|
-
import BiteIcon from '@cdc/core/assets/data-bite-graphic.svg'
|
|
9
|
-
import BarIcon from '@cdc/core/assets/chart-bar-solid.svg'
|
|
10
|
-
import LineIcon from '@cdc/core/assets/chart-line-solid.svg'
|
|
11
|
-
import PieIcon from '@cdc/core/assets/chart-pie-solid.svg'
|
|
12
|
-
import UsaIcon from '@cdc/core/assets/usa-graphic.svg'
|
|
13
|
-
import WorldIcon from '@cdc/core/assets/world-graphic.svg'
|
|
14
|
-
import AlabamaIcon from '@cdc/core/assets/alabama-graphic.svg'
|
|
15
|
-
import FilteredText from '@cdc/core/assets/filtered-text.svg'
|
|
16
|
-
|
|
17
|
-
import Context from '../context'
|
|
1
|
+
import React, { useContext } from 'react'
|
|
2
|
+
import { useDrag } from 'react-dnd'
|
|
3
|
+
import CloseIcon from '../images/icon-close.svg'
|
|
4
|
+
import GridIcon from '../images/icon-grid.svg'
|
|
5
|
+
import CodeIcon from '../images/icon-code.svg'
|
|
6
|
+
import EditIcon from '../images/icon-edit.svg'
|
|
7
|
+
import MoveIcon from '../images/icon-move.svg'
|
|
8
|
+
import BiteIcon from '@cdc/core/assets/data-bite-graphic.svg'
|
|
9
|
+
import BarIcon from '@cdc/core/assets/chart-bar-solid.svg'
|
|
10
|
+
import LineIcon from '@cdc/core/assets/chart-line-solid.svg'
|
|
11
|
+
import PieIcon from '@cdc/core/assets/chart-pie-solid.svg'
|
|
12
|
+
import UsaIcon from '@cdc/core/assets/usa-graphic.svg'
|
|
13
|
+
import WorldIcon from '@cdc/core/assets/world-graphic.svg'
|
|
14
|
+
import AlabamaIcon from '@cdc/core/assets/alabama-graphic.svg'
|
|
15
|
+
import FilteredText from '@cdc/core/assets/filtered-text.svg'
|
|
16
|
+
|
|
17
|
+
import Context from '../context'
|
|
18
18
|
|
|
19
19
|
const iconHash = {
|
|
20
|
-
'data-bite'
|
|
21
|
-
|
|
20
|
+
'data-bite': <BiteIcon />,
|
|
21
|
+
Bar: <BarIcon />,
|
|
22
22
|
'Spark Line': <LineIcon />,
|
|
23
|
-
'waffle-chart'
|
|
24
|
-
'markup-include'
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
'waffle-chart': <GridIcon />,
|
|
24
|
+
'markup-include': <CodeIcon />,
|
|
25
|
+
Line: <LineIcon />,
|
|
26
|
+
Pie: <PieIcon />,
|
|
27
|
+
us: <UsaIcon />,
|
|
28
28
|
'us-county': <UsaIcon />,
|
|
29
|
-
|
|
29
|
+
world: <WorldIcon />,
|
|
30
30
|
'single-state': <AlabamaIcon />,
|
|
31
|
-
'filtered-text'
|
|
31
|
+
'filtered-text': <FilteredText />
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const labelHash = {
|
|
35
35
|
'data-bite': 'Data Bite',
|
|
36
|
-
'waffle-chart'
|
|
37
|
-
'markup-include'
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
'Spark Line'
|
|
42
|
-
|
|
36
|
+
'waffle-chart': 'Waffle Chart',
|
|
37
|
+
'markup-include': 'Markup Include',
|
|
38
|
+
Bar: 'Bar',
|
|
39
|
+
Line: 'Line',
|
|
40
|
+
Pie: 'Pie',
|
|
41
|
+
'Spark Line': 'Spark Line',
|
|
42
|
+
us: 'United States (State- or County-Level)',
|
|
43
43
|
'us-county': 'United States (State- or County-Level)',
|
|
44
|
-
|
|
44
|
+
world: 'World',
|
|
45
45
|
'single-state': 'U.S. State',
|
|
46
|
-
'filtered-text':'Filtered Text'
|
|
47
|
-
|
|
46
|
+
'filtered-text': 'Filtered Text'
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
const Widget = ({ data = {}, addVisualization, type }) => {
|
|
@@ -53,30 +52,30 @@ const Widget = ({ data = {}, addVisualization, type }) => {
|
|
|
53
52
|
console.log('type', type)
|
|
54
53
|
|
|
55
54
|
const handleWidgetMove = (item, monitor) => {
|
|
56
|
-
|
|
55
|
+
let result = monitor.getDropResult()
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
if (!result) return null
|
|
59
58
|
|
|
60
|
-
|
|
59
|
+
const { rowIdx, colIdx } = result
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
if (undefined !== data.rowIdx) {
|
|
62
|
+
rows[data.rowIdx][data.colIdx].widget = null // Wipe from old position
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
rows[rowIdx][colIdx].widget = data.uid // Add to new row and col
|
|
65
|
+
} else {
|
|
66
|
+
// Item does not exist, instantiate a new one
|
|
67
|
+
const newViz = addVisualization()
|
|
68
|
+
visualizations[newViz.uid] = newViz // Add to widgets collection
|
|
69
|
+
rows[rowIdx][colIdx].widget = newViz.uid // Store reference in rows collection under the specific column
|
|
70
|
+
}
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
updateConfig({ ...config, rows, visualizations })
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
const [
|
|
75
|
+
const [{ isDragging, ...collected }, drag] = useDrag({
|
|
77
76
|
type: 'vis-widget',
|
|
78
77
|
end: handleWidgetMove,
|
|
79
|
-
collect:
|
|
78
|
+
collect: monitor => ({
|
|
80
79
|
isDragging: monitor.isDragging()
|
|
81
80
|
})
|
|
82
81
|
})
|
|
@@ -86,28 +85,36 @@ const Widget = ({ data = {}, addVisualization, type }) => {
|
|
|
86
85
|
|
|
87
86
|
delete visualizations[data.uid]
|
|
88
87
|
|
|
89
|
-
updateConfig({...config, rows, visualizations})
|
|
88
|
+
updateConfig({ ...config, rows, visualizations })
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
const editWidget = () => {
|
|
93
|
-
visualizations[data.uid].editing = true
|
|
92
|
+
visualizations[data.uid].editing = true
|
|
94
93
|
|
|
95
|
-
updateConfig({...config, visualizations})
|
|
94
|
+
updateConfig({ ...config, visualizations })
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
return (
|
|
99
|
-
<div className=
|
|
100
|
-
<MoveIcon className=
|
|
101
|
-
<div className=
|
|
98
|
+
<div className='widget' ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }} {...collected}>
|
|
99
|
+
<MoveIcon className='drag-icon' />
|
|
100
|
+
<div className='widget__content'>
|
|
102
101
|
{data.rowIdx !== undefined && (
|
|
103
|
-
<div className=
|
|
104
|
-
<div className=
|
|
105
|
-
|
|
102
|
+
<div className='widget-menu'>
|
|
103
|
+
<div className='widget-menu-item' onClick={editWidget}>
|
|
104
|
+
<EditIcon />
|
|
105
|
+
</div>
|
|
106
|
+
<div className='widget-menu-item' onClick={deleteWidget}>
|
|
107
|
+
<CloseIcon />
|
|
108
|
+
</div>
|
|
106
109
|
</div>
|
|
107
110
|
)}
|
|
108
111
|
{iconHash[type]}
|
|
109
112
|
<span>{labelHash[type]}</span>
|
|
110
|
-
{data.newViz &&
|
|
113
|
+
{data.newViz && (
|
|
114
|
+
<span onClick={editWidget} className='config-needed'>
|
|
115
|
+
Configuration needed
|
|
116
|
+
</span>
|
|
117
|
+
)}
|
|
111
118
|
</div>
|
|
112
119
|
</div>
|
|
113
120
|
)
|
|
@@ -12,43 +12,43 @@ import Icon from '@cdc/core/components/ui/Icon'
|
|
|
12
12
|
import Modal from '@cdc/core/components/ui/Modal'
|
|
13
13
|
|
|
14
14
|
const iconHash = {
|
|
15
|
-
'data-bite': <Icon display=
|
|
16
|
-
|
|
17
|
-
'Spark Line': <Icon display=
|
|
18
|
-
'waffle-chart': <Icon display=
|
|
19
|
-
'markup-include': <Icon display=
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'us-county': <Icon display=
|
|
24
|
-
|
|
25
|
-
'single-state': <Icon display=
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'filtered-text': <Icon display='filtered-text' base/>
|
|
15
|
+
'data-bite': <Icon display='databite' base />,
|
|
16
|
+
Bar: <Icon display='chartBar' base />,
|
|
17
|
+
'Spark Line': <Icon display='chartLine' />,
|
|
18
|
+
'waffle-chart': <Icon display='grid' base />,
|
|
19
|
+
'markup-include': <Icon display='code' base />,
|
|
20
|
+
Line: <Icon display='chartLine' base />,
|
|
21
|
+
Pie: <Icon display='chartPie' base />,
|
|
22
|
+
us: <Icon display='mapUsa' base />,
|
|
23
|
+
'us-county': <Icon display='mapUsa' base />,
|
|
24
|
+
world: <Icon display='mapWorld' base />,
|
|
25
|
+
'single-state': <Icon display='mapAl' base />,
|
|
26
|
+
gear: <Icon display='gear' base />,
|
|
27
|
+
tools: <Icon display='tools' base />,
|
|
28
|
+
'filtered-text': <Icon display='filtered-text' base />
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const labelHash = {
|
|
32
32
|
'data-bite': 'Data Bite',
|
|
33
33
|
'waffle-chart': 'Waffle Chart',
|
|
34
34
|
'markup-include': 'Markup Include',
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
Bar: 'Bar',
|
|
36
|
+
Line: 'Line',
|
|
37
37
|
'Spark Line': 'Spark Line',
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
Pie: 'Pie',
|
|
39
|
+
us: 'United States (State- or County-Level)',
|
|
40
40
|
'us-county': 'United States (State- or County-Level)',
|
|
41
|
-
|
|
41
|
+
world: 'World',
|
|
42
42
|
'single-state': 'U.S. State',
|
|
43
|
-
'filtered-text':'filtered-text'
|
|
43
|
+
'filtered-text': 'filtered-text'
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
const Widget = ({ data = {}, addVisualization, type }) => {
|
|
47
47
|
const { overlay } = useGlobalContext()
|
|
48
48
|
const { rows, visualizations, config, updateConfig } = useContext(ConfigContext)
|
|
49
49
|
|
|
50
|
-
const dataRef = useRef()
|
|
51
|
-
dataRef.current = data
|
|
50
|
+
const dataRef = useRef()
|
|
51
|
+
dataRef.current = data
|
|
52
52
|
|
|
53
53
|
const transform = new DataTransform()
|
|
54
54
|
|
|
@@ -73,10 +73,10 @@ const Widget = ({ data = {}, addVisualization, type }) => {
|
|
|
73
73
|
updateConfig({ ...config, rows, visualizations })
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
const [
|
|
76
|
+
const [{ isDragging, ...collected }, drag] = useDrag({
|
|
77
77
|
type: 'vis-widget',
|
|
78
78
|
end: handleWidgetMove,
|
|
79
|
-
collect:
|
|
79
|
+
collect: monitor => ({
|
|
80
80
|
isDragging: monitor.isDragging()
|
|
81
81
|
})
|
|
82
82
|
})
|
|
@@ -86,12 +86,12 @@ const Widget = ({ data = {}, addVisualization, type }) => {
|
|
|
86
86
|
|
|
87
87
|
delete visualizations[data.uid]
|
|
88
88
|
|
|
89
|
-
if(config.dashboard.sharedFilters && config.dashboard.sharedFilters.length > 0){
|
|
89
|
+
if (config.dashboard.sharedFilters && config.dashboard.sharedFilters.length > 0) {
|
|
90
90
|
config.dashboard.sharedFilters.forEach(sharedFilter => {
|
|
91
|
-
if(sharedFilter.usedBy.indexOf(data.uid) !== -1){
|
|
92
|
-
sharedFilter.usedBy.splice(sharedFilter.usedBy.indexOf(data.uid), 1)
|
|
91
|
+
if (sharedFilter.usedBy.indexOf(data.uid) !== -1) {
|
|
92
|
+
sharedFilter.usedBy.splice(sharedFilter.usedBy.indexOf(data.uid), 1)
|
|
93
93
|
}
|
|
94
|
-
})
|
|
94
|
+
})
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
updateConfig({ ...config, rows, visualizations })
|
|
@@ -132,34 +132,44 @@ const Widget = ({ data = {}, addVisualization, type }) => {
|
|
|
132
132
|
|
|
133
133
|
overlay?.actions.openOverlay(dataDesignerModal(newVisualizations[visualizationKey]))
|
|
134
134
|
}
|
|
135
|
-
|
|
135
|
+
|
|
136
136
|
const dataDesignerModal = (configureData, dataKeyOverride) => {
|
|
137
|
-
const dataKey = !dataKeyOverride && dataKeyOverride !== '' ?
|
|
137
|
+
const dataKey = !dataKeyOverride && dataKeyOverride !== '' ? data.dataKey || dataRef.current.dataKey : dataKeyOverride
|
|
138
138
|
|
|
139
|
-
overlay?.actions.toggleOverlay()
|
|
139
|
+
overlay?.actions.toggleOverlay()
|
|
140
140
|
|
|
141
141
|
return (
|
|
142
142
|
<Modal>
|
|
143
143
|
<Modal.Content>
|
|
144
|
-
<div className=
|
|
144
|
+
<div className='dataset-selector-container'>
|
|
145
145
|
Select a dataset:
|
|
146
|
-
<select
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
146
|
+
<select
|
|
147
|
+
className='dataset-selector'
|
|
148
|
+
defaultValue={dataKey}
|
|
149
|
+
onChange={e => {
|
|
150
|
+
changeDataset(data.uid, e.target.value)
|
|
151
|
+
overlay?.actions.openOverlay(dataDesignerModal(data, e.target.value || ''))
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
154
|
+
<option value=''>Select a dataset</option>
|
|
155
|
+
{config.datasets && Object.keys(config.datasets).map(datasetKey => <option key={datasetKey}>{datasetKey}</option>)}
|
|
154
156
|
</select>
|
|
155
157
|
</div>
|
|
156
|
-
{dataKey &&
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
{dataKey && (
|
|
159
|
+
<DataDesigner
|
|
160
|
+
{...{
|
|
161
|
+
configureData,
|
|
162
|
+
visualizationKey: data.uid,
|
|
163
|
+
dataKey: dataKey,
|
|
164
|
+
updateDescriptionProp
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
)}
|
|
168
|
+
{configureData.formattedData && (
|
|
169
|
+
<button style={{ margin: '1em' }} className='cove-button' onClick={() => overlay?.actions.toggleOverlay()}>
|
|
170
|
+
Continue
|
|
171
|
+
</button>
|
|
172
|
+
)}
|
|
163
173
|
</Modal.Content>
|
|
164
174
|
</Modal>
|
|
165
175
|
)
|
|
@@ -167,7 +177,7 @@ const Widget = ({ data = {}, addVisualization, type }) => {
|
|
|
167
177
|
|
|
168
178
|
useEffect(() => {
|
|
169
179
|
if (data.openModal) {
|
|
170
|
-
|
|
180
|
+
overlay?.actions.openOverlay(dataDesignerModal(dataRef.current))
|
|
171
181
|
|
|
172
182
|
visualizations[data.uid].openModal = false
|
|
173
183
|
|
|
@@ -177,26 +187,39 @@ const Widget = ({ data = {}, addVisualization, type }) => {
|
|
|
177
187
|
|
|
178
188
|
return (
|
|
179
189
|
<>
|
|
180
|
-
<div className=
|
|
181
|
-
<Icon display=
|
|
182
|
-
<div className=
|
|
190
|
+
<div className='widget' ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }} {...collected}>
|
|
191
|
+
<Icon display='move' className='drag-icon' />
|
|
192
|
+
<div className='widget__content'>
|
|
183
193
|
{data.rowIdx !== undefined && (
|
|
184
|
-
<div className=
|
|
185
|
-
{((data.dataKey && data.dataDescription && data.formattedData) || type === 'markup-include') &&
|
|
186
|
-
<button title=
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
+
<div className='widget-menu'>
|
|
195
|
+
{((data.dataKey && data.dataDescription && data.formattedData) || type === 'markup-include') && (
|
|
196
|
+
<button title='Configure Visualization' className='btn btn-configure' onClick={editWidget}>
|
|
197
|
+
{iconHash['tools']}
|
|
198
|
+
</button>
|
|
199
|
+
)}
|
|
200
|
+
{type !== 'markup-include' && (
|
|
201
|
+
<button
|
|
202
|
+
title='Configure Data'
|
|
203
|
+
className='btn btn-configure'
|
|
204
|
+
onClick={() => {
|
|
205
|
+
overlay?.actions.openOverlay(dataDesignerModal(data))
|
|
206
|
+
}}
|
|
207
|
+
>
|
|
208
|
+
{iconHash['gear']}
|
|
209
|
+
</button>
|
|
210
|
+
)}
|
|
211
|
+
<div className='widget-menu-item' onClick={deleteWidget}>
|
|
212
|
+
<Icon display='close' base />
|
|
194
213
|
</div>
|
|
195
214
|
</div>
|
|
196
215
|
)}
|
|
197
216
|
{iconHash[type]}
|
|
198
217
|
<span>{labelHash[type]}</span>
|
|
199
|
-
{data.newViz &&
|
|
218
|
+
{data.newViz && (
|
|
219
|
+
<span onClick={editWidget} className='config-needed'>
|
|
220
|
+
Configuration needed
|
|
221
|
+
</span>
|
|
222
|
+
)}
|
|
200
223
|
</div>
|
|
201
224
|
</div>
|
|
202
225
|
</>
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
dashboard: {
|
|
3
|
-
|
|
3
|
+
theme: 'theme-blue'
|
|
4
4
|
},
|
|
5
|
-
rows: [
|
|
6
|
-
[
|
|
7
|
-
{width: 12},
|
|
8
|
-
{},
|
|
9
|
-
{}
|
|
10
|
-
]
|
|
11
|
-
],
|
|
5
|
+
rows: [[{ width: 12 }, {}, {}]],
|
|
12
6
|
visualizations: {},
|
|
13
7
|
table: {
|
|
14
8
|
label: 'Data Table',
|
|
15
|
-
show: true
|
|
9
|
+
show: true,
|
|
10
|
+
showDownloadUrl: false
|
|
16
11
|
}
|
|
17
|
-
}
|
|
12
|
+
}
|
package/src/index.html
CHANGED
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
</head>
|
|
21
21
|
|
|
22
22
|
<body>
|
|
23
|
-
<div class="react-container" data-config="/examples/default.json"></div>
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
<!-- <div class="react-container" data-config="/examples/default.json"></div> -->
|
|
24
|
+
<!-- <div class="react-container" data-config="/examples/default-multi-dataset.json"></div> -->
|
|
25
|
+
<div class="react-container" data-config="/examples/default-filter-control.json"></div>
|
|
26
26
|
<!-- <div class="react-container" data-config="/examples/private/totals.json"></div> -->
|
|
27
27
|
<!-- <div class="react-container" data-config="/examples/private/totals-two.json"></div> -->
|
|
28
28
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
package/src/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { render } from 'react-dom'
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from 'react-dom'
|
|
3
3
|
|
|
4
|
-
import CdcDashboard from './CdcDashboard'
|
|
4
|
+
import CdcDashboard from './CdcDashboard'
|
|
5
5
|
|
|
6
|
-
const domContainers = document.querySelectorAll('.react-container')
|
|
6
|
+
const domContainers = document.querySelectorAll('.react-container')
|
|
7
7
|
|
|
8
|
-
let isEditor = window.location.href.includes('editor=true')
|
|
8
|
+
let isEditor = window.location.href.includes('editor=true')
|
|
9
9
|
|
|
10
|
-
domContainers.forEach(
|
|
11
|
-
render(
|
|
10
|
+
domContainers.forEach(domContainer => {
|
|
11
|
+
render(
|
|
12
12
|
<React.StrictMode>
|
|
13
|
-
<CdcDashboard configUrl={domContainer.attributes['data-config'].value} isEditor={isEditor} />
|
|
14
|
-
</React.StrictMode>,
|
|
15
|
-
domContainer
|
|
16
|
-
)
|
|
17
|
-
})
|
|
13
|
+
<CdcDashboard configUrl={domContainer.attributes['data-config'].value} isEditor={isEditor} />
|
|
14
|
+
</React.StrictMode>,
|
|
15
|
+
domContainer
|
|
16
|
+
)
|
|
17
|
+
})
|