@cdc/dashboard 1.1.4 → 9.22.9

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.
@@ -0,0 +1,181 @@
1
+ import React, { useContext, useState } from 'react'
2
+
3
+ import { useGlobalContext } from '@cdc/core/components/GlobalContext'
4
+ import ConfigContext from '../ConfigContext'
5
+
6
+ import Modal from '@cdc/core/components/ui/Modal'
7
+ import InputToggle from '@cdc/core/components/inputs/InputToggle'
8
+ import Icon from '@cdc/core/components/ui/Icon'
9
+
10
+ import Column from './Column'
11
+
12
+ import OneColIcon from '../images/icon-col-12.svg'
13
+ import TwoColIcon from '../images/icon-col-6.svg'
14
+ import ThreeColIcon from '../images/icon-col-4.svg'
15
+ import FourEightColIcon from '../images/icon-col-4-8.svg'
16
+ import EightFourColIcon from '../images/icon-col-8-4.svg'
17
+
18
+ const RowMenu = ({ rowIdx, row }) => {
19
+ const { overlay } = useGlobalContext()
20
+ const { rows, config, updateConfig } = useContext(ConfigContext)
21
+
22
+ const getCurr = () => {
23
+ let res = []
24
+
25
+ for (let i = 0; i < row.length; i++) {
26
+ if (row[i].width) res.push(row[i].width)
27
+ }
28
+
29
+ return res.join('')
30
+ }
31
+
32
+ const [ curr, setCurr ] = useState(getCurr())
33
+ const [ equalHeight, setEqualHeight ] = useState(false)
34
+
35
+ const setRowLayout = (layout) => {
36
+ const newRows = [ ...rows ]
37
+ const r = newRows[rowIdx]
38
+
39
+ for (let i = 0; i < r.length; i++) {
40
+ r[i].width = layout[i] ?? null
41
+ }
42
+
43
+ updateConfig({ ...config, rows: newRows })
44
+ setCurr(layout.join(''))
45
+ }
46
+
47
+ const moveRow = (dir = 'down') => {
48
+ if (rowIdx === rows.length - 1 && dir === 'down') return
49
+
50
+ let newIdx = dir === 'down' ? rowIdx + 1 : rowIdx - 1
51
+
52
+ // Swap
53
+ const temp = rows[newIdx]
54
+
55
+ rows[newIdx] = row
56
+ rows[rowIdx] = temp
57
+
58
+ rows[newIdx].uuid = Date.now()
59
+ rows[rowIdx].uuid = Date.now()
60
+
61
+ updateConfig({ ...config, rows })
62
+
63
+ // TODO: Migrate this animation to a React animation library once one is selected for COVE. This is pretty minor so can stay for now.
64
+ let calcRowMove = dir === 'down' ? 202 : -202
65
+ let calcRowMove2 = dir === 'down' ? -202 : 202
66
+
67
+ let rowEle = document.querySelector('[data-row-id=\'' + rowIdx + '\']')
68
+ let rowNewEle = document.querySelector('[data-row-id=\'' + newIdx + '\']')
69
+
70
+ rowEle.style.pointerEvents = 'none'
71
+ rowNewEle.style.pointerEvents = 'none'
72
+ rowEle.style.top = calcRowMove + 'px'
73
+ rowNewEle.style.top = calcRowMove2 + 'px'
74
+
75
+ setTimeout(() => {
76
+ rowEle.style.transition = 'top 500ms cubic-bezier(0.16, 1, 0.3, 1)'
77
+ rowNewEle.style.transition = 'top 500ms cubic-bezier(0.16, 1, 0.3, 1)'
78
+ rowEle.style.top = '0'
79
+ rowNewEle.style.top = '0'
80
+ }, 0)
81
+
82
+ setTimeout(() => {
83
+ rowEle.style = null
84
+ rowNewEle.style = null
85
+ }, 500)
86
+ }
87
+
88
+ const deleteRow = () => {
89
+ rows.splice(rowIdx, 1) // Just delete the row. Don't delete the instantiated widgets for now.
90
+
91
+ updateConfig({ ...config, rows })
92
+ }
93
+
94
+ const rowItemsHeight = () => {
95
+ setEqualHeight(!equalHeight)
96
+
97
+ row.equalHeight = !equalHeight
98
+ }
99
+
100
+ const layoutList = [
101
+ <li className={curr === '12' ? `current row-menu__list--item` : `row-menu__list--item`}
102
+ onClick={() => setRowLayout([ 12 ])} key="12" title="1 Column">
103
+ <OneColIcon/>
104
+ </li>,
105
+ <li className={curr === '66' ? `current row-menu__list--item` : `row-menu__list--item`}
106
+ onClick={() => setRowLayout([ 6, 6 ])} key="66" title="2 Columns">
107
+ <TwoColIcon/>
108
+ </li>,
109
+ <li className={curr === '444' ? `current row-menu__list--item` : `row-menu__list--item`}
110
+ onClick={() => setRowLayout([ 4, 4, 4 ])} key="444" title="3 Columns">
111
+ <ThreeColIcon/>
112
+ </li>,
113
+ <li className={curr === '48' ? `current row-menu__list--item` : `row-menu__list--item`}
114
+ onClick={() => setRowLayout([ 4, 8 ])} key="48" title="2 Columns">
115
+ <FourEightColIcon/>
116
+ </li>,
117
+ <li className={curr === '84' ? `current row-menu__list--item` : `row-menu__list--item`}
118
+ onClick={() => setRowLayout([ 8, 4 ])} key="84" title="2 Columns">
119
+ <EightFourColIcon/>
120
+ </li>
121
+ ]
122
+
123
+ const rowSettings = (
124
+ <Modal>
125
+ <Modal.Header>
126
+ Row Settings
127
+ </Modal.Header>
128
+ <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>
135
+ </Modal.Content>
136
+ </Modal>
137
+ )
138
+
139
+ return (
140
+ <nav className="row-menu">
141
+ <div className="row-menu__btn">
142
+ <ul className="row-menu__flyout">
143
+ {layoutList}
144
+ </ul>
145
+ </div>
146
+ <div className="spacer"></div>
147
+ {/*<button className={'row-menu__btn'} title="Row Settings"*/}
148
+ {/* onClick={() => overlay?.actions.openOverlay(rowSettings)}>*/}
149
+ {/* <Icon display="edit" color="#fff" size={25}/>*/}
150
+ {/*</button>*/}
151
+ <button className={rowIdx === 0 ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'} title="Move Row Up"
152
+ onClick={() => moveRow('up')}>
153
+ <Icon display="caretUp" color="#fff" size={25}/>
154
+ </button>
155
+ <button className={rowIdx + 1 === rows.length ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'}
156
+ title="Move Row Down" onClick={() => moveRow('down')}>
157
+ <Icon display="caretDown" color="#fff" size={25}/>
158
+ </button>
159
+ <button
160
+ className={rowIdx === 0 && rows.length === 1 ? 'row-menu__btn row-menu__btn--remove row-menu__btn-disabled' : 'row-menu__btn row-menu__btn--remove'}
161
+ title="Delete Row" onClick={deleteRow}>
162
+ <Icon display="close" color="#fff" size={25}/>
163
+ </button>
164
+ </nav>
165
+ )
166
+ }
167
+
168
+ const Row = ({ row, idx: rowIdx, uuid }) => {
169
+ return (
170
+ <div className="builder-row" data-row-id={rowIdx}>
171
+ <RowMenu rowIdx={rowIdx} row={row}/>
172
+ <div className="column-container">
173
+ {row.filter(column => column.width).map((column, colIdx) => <Column data={column}
174
+ key={`row-${uuid}-col-${colIdx}`}
175
+ rowIdx={rowIdx} colIdx={colIdx}/>)}
176
+ </div>
177
+ </div>
178
+ )
179
+ }
180
+
181
+ export default Row
@@ -0,0 +1,212 @@
1
+ import React, { useContext, useState } from 'react'
2
+
3
+ import { useGlobalContext } from '@cdc/core/components/GlobalContext'
4
+ import ConfigContext from '../ConfigContext'
5
+
6
+ import Modal from '@cdc/core/components/ui/Modal'
7
+ import InputToggle from '@cdc/core/components/inputs/InputToggle'
8
+ import Icon from '@cdc/core/components/ui/Icon'
9
+
10
+ import Column from './Column'
11
+ <<<<<<< HEAD:packages/dashboard/src/components/Row.jsx
12
+
13
+ =======
14
+ import Context from '../context'
15
+ import CloseIcon from '../images/icon-close.svg'
16
+ import RowUp from '../images/icon-up.svg'
17
+ import RowDown from '../images/icon-down.svg'
18
+ >>>>>>> test:packages/dashboard/src/components/Row.js
19
+ import OneColIcon from '../images/icon-col-12.svg'
20
+ import TwoColIcon from '../images/icon-col-6.svg'
21
+ import ThreeColIcon from '../images/icon-col-4.svg'
22
+ import FourEightColIcon from '../images/icon-col-4-8.svg'
23
+ import EightFourColIcon from '../images/icon-col-8-4.svg'
24
+
25
+ const RowMenu = ({ rowIdx, row }) => {
26
+ <<<<<<< HEAD:packages/dashboard/src/components/Row.jsx
27
+ const { overlay } = useGlobalContext()
28
+ const { rows, config, updateConfig } = useContext(ConfigContext)
29
+ =======
30
+ const { rows, config, updateConfig } = useContext(Context)
31
+ >>>>>>> test:packages/dashboard/src/components/Row.js
32
+
33
+ const getCurr = () => {
34
+ let res = []
35
+
36
+ for (let i = 0; i < row.length; i++) {
37
+ if (row[i].width) res.push(row[i].width)
38
+ }
39
+
40
+ return res.join('')
41
+ }
42
+
43
+ <<<<<<< HEAD:packages/dashboard/src/components/Row.jsx
44
+ const [ curr, setCurr ] = useState(getCurr())
45
+ const [ equalHeight, setEqualHeight ] = useState(false)
46
+ =======
47
+ const [curr, setCurr] = useState(getCurr())
48
+ >>>>>>> test:packages/dashboard/src/components/Row.js
49
+
50
+ const setRowLayout = (layout) => {
51
+ const newRows = [ ...rows ]
52
+ const r = newRows[rowIdx]
53
+
54
+ for (let i = 0; i < r.length; i++) {
55
+ r[i].width = layout[i] ?? null
56
+ }
57
+
58
+ updateConfig({ ...config, rows: newRows })
59
+ setCurr(layout.join(''))
60
+ }
61
+
62
+ const moveRow = (dir = 'down') => {
63
+ if (rowIdx === rows.length - 1 && dir === 'down') return
64
+
65
+ let newIdx = dir === 'down' ? rowIdx + 1 : rowIdx - 1
66
+
67
+ // Swap
68
+ const temp = rows[newIdx]
69
+
70
+ rows[newIdx] = row
71
+ rows[rowIdx] = temp
72
+
73
+ rows[newIdx].uuid = Date.now()
74
+ rows[rowIdx].uuid = Date.now()
75
+
76
+ updateConfig({ ...config, rows })
77
+
78
+ // TODO: Migrate this animation to a React animation library once one is selected for COVE. This is pretty minor so can stay for now.
79
+ let calcRowMove = dir === 'down' ? 202 : -202
80
+ let calcRowMove2 = dir === 'down' ? -202 : 202
81
+
82
+ let rowEle = document.querySelector('[data-row-id=\'' + rowIdx + '\']')
83
+ let rowNewEle = document.querySelector('[data-row-id=\'' + newIdx + '\']')
84
+
85
+ rowEle.style.pointerEvents = 'none'
86
+ rowNewEle.style.pointerEvents = 'none'
87
+ rowEle.style.top = calcRowMove + 'px'
88
+ rowNewEle.style.top = calcRowMove2 + 'px'
89
+
90
+ setTimeout(() => {
91
+ rowEle.style.transition = 'top 500ms cubic-bezier(0.16, 1, 0.3, 1)'
92
+ rowNewEle.style.transition = 'top 500ms cubic-bezier(0.16, 1, 0.3, 1)'
93
+ rowEle.style.top = '0'
94
+ rowNewEle.style.top = '0'
95
+ }, 0)
96
+
97
+ setTimeout(() => {
98
+ rowEle.style = null
99
+ rowNewEle.style = null
100
+ }, 500)
101
+ }
102
+
103
+ const deleteRow = () => {
104
+ rows.splice(rowIdx, 1) // Just delete the row. Don't delete the instantiated widgets for now.
105
+
106
+ updateConfig({ ...config, rows })
107
+ }
108
+
109
+ <<<<<<< HEAD:packages/dashboard/src/components/Row.jsx
110
+ const rowItemsHeight = () => {
111
+ console.log('hit')
112
+ setEqualHeight(!equalHeight)
113
+
114
+ row.equalHeight = !equalHeight
115
+
116
+ console.log('equalHeight var', equalHeight)
117
+ console.log('equalHeight', row.equalHeight)
118
+ }
119
+ console.log('equal height var', row.equalHeight)
120
+
121
+ =======
122
+ >>>>>>> test:packages/dashboard/src/components/Row.js
123
+ const layoutList = [
124
+ <li className={curr === '12' ? `current row-menu__list--item` : `row-menu__list--item`}
125
+ onClick={() => setRowLayout([ 12 ])} key="12" title="1 Column">
126
+ <OneColIcon/>
127
+ </li>,
128
+ <li className={curr === '66' ? `current row-menu__list--item` : `row-menu__list--item`}
129
+ onClick={() => setRowLayout([ 6, 6 ])} key="66" title="2 Columns">
130
+ <TwoColIcon/>
131
+ </li>,
132
+ <li className={curr === '444' ? `current row-menu__list--item` : `row-menu__list--item`}
133
+ onClick={() => setRowLayout([ 4, 4, 4 ])} key="444" title="3 Columns">
134
+ <ThreeColIcon/>
135
+ </li>,
136
+ <li className={curr === '48' ? `current row-menu__list--item` : `row-menu__list--item`}
137
+ onClick={() => setRowLayout([ 4, 8 ])} key="48" title="2 Columns">
138
+ <FourEightColIcon/>
139
+ </li>,
140
+ <li className={curr === '84' ? `current row-menu__list--item` : `row-menu__list--item`}
141
+ onClick={() => setRowLayout([ 8, 4 ])} key="84" title="2 Columns">
142
+ <EightFourColIcon/>
143
+ </li>
144
+ ]
145
+
146
+ <<<<<<< HEAD:packages/dashboard/src/components/Row.jsx
147
+ const rowSettings = (
148
+ <Modal>
149
+ <Modal.Header>
150
+ Row Settings
151
+ </Modal.Header>
152
+ <Modal.Content>
153
+ <InputToggle
154
+ label="Visualizations in this row should be equal height"
155
+ fieldName={`toggleEqualHeight${rowIdx}`}
156
+ value={row.equalHeight ? row.equalHeight : false}
157
+ updateField={rowItemsHeight}
158
+ ></InputToggle>
159
+ </Modal.Content>
160
+ </Modal>
161
+ )
162
+
163
+ =======
164
+ >>>>>>> test:packages/dashboard/src/components/Row.js
165
+ return (
166
+ <nav className="row-menu">
167
+ <div className="row-menu__btn">
168
+ <ul className="row-menu__flyout">
169
+ {layoutList}
170
+ </ul>
171
+ </div>
172
+ <div className="spacer"></div>
173
+ <<<<<<< HEAD:packages/dashboard/src/components/Row.jsx
174
+ <button className={'row-menu__btn'} title="Row Settings"
175
+ onClick={() => overlay?.actions.openOverlay(rowSettings)}>
176
+ <Icon display="edit" color="#fff" size={25}/>
177
+ </button>
178
+ <button className={rowIdx === 0 ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'} title="Move Row Up"
179
+ onClick={() => moveRow('up')}>
180
+ <Icon display="caretUp" color="#fff" size={25}/>
181
+ =======
182
+ <button className={rowIdx === 0 ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'} title="Move Row Up" onClick={() => moveRow('up')}>
183
+ <RowUp />
184
+ >>>>>>> test:packages/dashboard/src/components/Row.js
185
+ </button>
186
+ <button className={rowIdx + 1 === rows.length ? 'row-menu__btn row-menu__btn-disabled' : 'row-menu__btn'}
187
+ title="Move Row Down" onClick={() => moveRow('down')}>
188
+ <Icon display="caretDown" color="#fff" size={25}/>
189
+ </button>
190
+ <button
191
+ className={rowIdx === 0 && rows.length === 1 ? 'row-menu__btn row-menu__btn--remove row-menu__btn-disabled' : 'row-menu__btn row-menu__btn--remove'}
192
+ title="Delete Row" onClick={deleteRow}>
193
+ <Icon display="close" color="#fff" size={25}/>
194
+ </button>
195
+ </nav>
196
+ )
197
+ }
198
+
199
+ const Row = ({ row, idx: rowIdx, uuid }) => {
200
+ return (
201
+ <div className="builder-row" data-row-id={rowIdx}>
202
+ <RowMenu rowIdx={rowIdx} row={row}/>
203
+ <div className="column-container">
204
+ {row.filter(column => column.width).map((column, colIdx) => <Column data={column}
205
+ key={`row-${uuid}-col-${colIdx}`}
206
+ rowIdx={rowIdx} colIdx={colIdx}/>)}
207
+ </div>
208
+ </div>
209
+ )
210
+ }
211
+
212
+ export default Row
@@ -12,6 +12,7 @@ import PieIcon from '@cdc/core/assets/chart-pie-solid.svg';
12
12
  import UsaIcon from '@cdc/core/assets/usa-graphic.svg';
13
13
  import WorldIcon from '@cdc/core/assets/world-graphic.svg';
14
14
  import AlabamaIcon from '@cdc/core/assets/alabama-graphic.svg';
15
+ import FilteredText from '@cdc/core/assets/filtered-text.svg';
15
16
 
16
17
  import Context from '../context';
17
18
 
@@ -26,7 +27,8 @@ const iconHash = {
26
27
  'us' : <UsaIcon />,
27
28
  'us-county': <UsaIcon />,
28
29
  'world' : <WorldIcon />,
29
- 'single-state': <AlabamaIcon />
30
+ 'single-state': <AlabamaIcon />,
31
+ 'filtered-text' : <FilteredText />,
30
32
  }
31
33
 
32
34
  const labelHash = {
@@ -40,7 +42,9 @@ const labelHash = {
40
42
  'us': 'United States (State- or County-Level)',
41
43
  'us-county': 'United States (State- or County-Level)',
42
44
  'world' : 'World',
43
- 'single-state': 'U.S. State'
45
+ 'single-state': 'U.S. State',
46
+ 'filtered-text':'Filtered Text'
47
+
44
48
  }
45
49
 
46
50
  const Widget = ({ data = {}, addVisualization, type }) => {
@@ -0,0 +1,191 @@
1
+ import React, { useContext, useRef, useEffect } from 'react'
2
+ import { useDrag } from 'react-dnd'
3
+
4
+ import { useGlobalContext } from '@cdc/core/components/GlobalContext'
5
+ import ConfigContext from '../ConfigContext'
6
+
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
+ import Icon from '@cdc/core/components/ui/Icon'
12
+ import Modal from '@cdc/core/components/ui/Modal'
13
+
14
+ const iconHash = {
15
+ 'data-bite': <Icon display="databite" base/>,
16
+ 'Bar': <Icon display="chartBar" base/>,
17
+ 'waffle-chart': <Icon display="grid" base/>,
18
+ 'markup-include': <Icon display="code" base/>,
19
+ 'Line': <Icon display="chartLine" base/>,
20
+ 'Pie': <Icon display="chartPie" base/>,
21
+ 'us': <Icon display="mapUsa" base/>,
22
+ 'us-county': <Icon display="mapUsa" base/>,
23
+ 'world': <Icon display="mapWorld" base/>,
24
+ 'single-state': <Icon display="mapAl" base/>,
25
+ 'gear': <Icon display="gear" base/>,
26
+ 'tools': <Icon display="tools" base/>
27
+ }
28
+
29
+ const labelHash = {
30
+ 'data-bite': 'Data Bite',
31
+ 'waffle-chart': 'Waffle Chart',
32
+ 'markup-include': 'Markup Include',
33
+ 'Bar': 'Bar',
34
+ 'Line': 'Line',
35
+ 'Pie': 'Pie',
36
+ 'us': 'United States (State- or County-Level)',
37
+ 'us-county': 'United States (State- or County-Level)',
38
+ 'world': 'World',
39
+ 'single-state': 'U.S. State'
40
+ }
41
+
42
+ const Widget = ({ data = {}, addVisualization, type }) => {
43
+ const { overlay } = useGlobalContext()
44
+ const { rows, visualizations, config, updateConfig } = useContext(ConfigContext)
45
+
46
+ const dataRef = useRef();
47
+ dataRef.current = data;
48
+
49
+ const transform = new DataTransform()
50
+
51
+ const handleWidgetMove = (item, monitor) => {
52
+ let result = monitor.getDropResult()
53
+
54
+ if (!result) return null
55
+
56
+ const { rowIdx, colIdx } = result
57
+
58
+ if (undefined !== data.rowIdx) {
59
+ rows[data.rowIdx][data.colIdx].widget = null // Wipe from old position
60
+
61
+ rows[rowIdx][colIdx].widget = data.uid // Add to new row and col
62
+ } else {
63
+ // Item does not exist, instantiate a new one
64
+ const newViz = addVisualization()
65
+ visualizations[newViz.uid] = newViz // Add to widgets collection
66
+ rows[rowIdx][colIdx].widget = newViz.uid // Store reference in rows collection under the specific column
67
+ }
68
+
69
+ updateConfig({ ...config, rows, visualizations })
70
+ }
71
+
72
+ const [ { isDragging, ...collected }, drag ] = useDrag({
73
+ type: 'vis-widget',
74
+ end: handleWidgetMove,
75
+ collect: (monitor) => ({
76
+ isDragging: monitor.isDragging()
77
+ })
78
+ })
79
+
80
+ const deleteWidget = () => {
81
+ rows[data.rowIdx][data.colIdx].widget = null
82
+
83
+ delete visualizations[data.uid]
84
+
85
+ updateConfig({ ...config, rows, visualizations })
86
+ }
87
+
88
+ const editWidget = () => {
89
+ visualizations[data.uid].editing = true
90
+
91
+ updateConfig({ ...config, visualizations })
92
+ }
93
+
94
+ const changeDataset = (uid, value) => {
95
+ delete visualizations[uid].dataDescription
96
+ delete visualizations[uid].formattedData
97
+
98
+ visualizations[uid].dataKey = value
99
+
100
+ updateConfig({ ...config, visualizations })
101
+ }
102
+
103
+ const updateDescriptionProp = async (visualizationKey, datasetKey, key, value) => {
104
+ let dataDescription = { ...dataRef.current.dataDescription, [key]: value }
105
+
106
+ let newData
107
+ if (!config.datasets[datasetKey].data && config.datasets[datasetKey].dataUrl) {
108
+ newData = await fetchRemoteData(config.datasets[datasetKey].dataUrl)
109
+ newData = transform.autoStandardize(newData)
110
+ } else {
111
+ newData = config.datasets[datasetKey].data
112
+ }
113
+
114
+ let formattedData = transform.developerStandardize(newData, dataDescription)
115
+
116
+ let newVisualizations = { ...config.visualizations }
117
+ newVisualizations[visualizationKey] = { ...newVisualizations[visualizationKey], data: newData, dataDescription, formattedData }
118
+
119
+ updateConfig({ ...config, visualizations: newVisualizations })
120
+
121
+ overlay?.actions.openOverlay(dataDesignerModal(newVisualizations[visualizationKey]))
122
+ }
123
+
124
+ const dataDesignerModal = (configureData, dataKeyOverride) => {
125
+ const dataKey = !dataKeyOverride && dataKeyOverride !== '' ? (data.dataKey || dataRef.current.dataKey) : dataKeyOverride;
126
+
127
+ return (
128
+ <Modal>
129
+ <Modal.Content>
130
+ <div className="dataset-selector-container">
131
+ Select a dataset:&nbsp;
132
+ <select className="dataset-selector" defaultValue={dataKey} onChange={(e) => {
133
+ changeDataset(data.uid, e.target.value)
134
+ overlay?.actions.openOverlay(dataDesignerModal(data, e.target.value || ''))
135
+ }}>
136
+ <option value="">Select a dataset</option>
137
+ {config.datasets && Object.keys(config.datasets).map(datasetKey => (
138
+ <option key={datasetKey}>{datasetKey}</option>
139
+ ))}
140
+ </select>
141
+ </div>
142
+ {dataKey && <DataDesigner {...{
143
+ configureData,
144
+ visualizationKey: data.uid,
145
+ dataKey: dataKey,
146
+ updateDescriptionProp
147
+ }}/>}
148
+ {configureData.formattedData && <button style={{margin: '1em'}} className="cove-button" onClick={() => overlay?.actions.toggleOverlay()}>Continue</button>}
149
+ </Modal.Content>
150
+ </Modal>
151
+ )
152
+ }
153
+
154
+ useEffect(() => {
155
+ if(data.openModal){
156
+ overlay?.actions.openOverlay(dataDesignerModal(dataRef.current))
157
+
158
+ visualizations[data.uid].openModal = false
159
+
160
+ updateConfig({ ...config, visualizations })
161
+ }
162
+ }, [data.openModal])
163
+
164
+ return (
165
+ <>
166
+ <div className="widget" ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }} {...collected}>
167
+ <Icon display="move" className="drag-icon"/>
168
+ <div className="widget__content">
169
+ {data.rowIdx !== undefined && (
170
+ <div className="widget-menu">
171
+ {data.dataKey && data.dataDescription && data.formattedData &&
172
+ <button title="Configure Visualization" className="btn btn-configure" onClick={editWidget}>{iconHash['tools']}</button>
173
+ }
174
+ <button title="Configure Data" className="btn btn-configure" onClick={() => {
175
+ overlay?.actions.openOverlay(dataDesignerModal(data))
176
+ }}>{iconHash['gear']}</button>
177
+ <div className="widget-menu-item" onClick={deleteWidget}>
178
+ <Icon display="close" base/>
179
+ </div>
180
+ </div>
181
+ )}
182
+ {iconHash[type]}
183
+ <span>{labelHash[type]}</span>
184
+ {data.newViz && <span onClick={editWidget} className="config-needed">Configuration needed</span>}
185
+ </div>
186
+ </div>
187
+ </>
188
+ )
189
+ }
190
+
191
+ export default Widget
package/src/index.html CHANGED
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html>
1
+ <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
@@ -20,8 +20,9 @@
20
20
  </style>
21
21
  </head>
22
22
  <body>
23
- <!-- <div class="react-container" data-config="/examples/default.json"></div> -->
24
- <div class="react-container" data-config="/examples/test-example.json"></div>
25
- <noscript>You need to enable JavaScript to run this app.</noscript>
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
+ <noscript>You need to enable JavaScript to run this app.</noscript>
26
27
  </body>
27
28
  </html>
@@ -183,7 +183,6 @@
183
183
  display: block;
184
184
  text-align: left;
185
185
  cursor: pointer;
186
- color: rgba(0,0,0,.5);
187
186
  text-decoration: underline;
188
187
  span {
189
188
  text-decoration: none;