@cdc/editor 4.23.3 → 4.23.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.
- package/dist/cdceditor.js +175728 -178759
- package/package.json +9 -9
- package/src/CdcEditor.jsx +3 -2
- package/src/components/ChooseTab.jsx +4 -3
- package/src/components/ConfigureTab.jsx +7 -7
- package/src/components/DataImport.jsx +202 -39
- package/src/components/SampleData.jsx +5 -5
- package/src/index.jsx +4 -2
- package/src/samples/valid-forecast-data.csv +366 -0
- package/src/scss/data-import.scss +55 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/editor",
|
|
3
|
-
"version": "4.23.
|
|
3
|
+
"version": "4.23.5",
|
|
4
4
|
"description": "React component for generating a new component entry",
|
|
5
5
|
"moduleName": "CdcEditor",
|
|
6
6
|
"main": "dist/cdceditor",
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
},
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@cdc/chart": "^4.23.
|
|
28
|
-
"@cdc/core": "^4.23.
|
|
29
|
-
"@cdc/dashboard": "^4.23.
|
|
30
|
-
"@cdc/data-bite": "^4.23.
|
|
31
|
-
"@cdc/map": "^4.23.
|
|
32
|
-
"@cdc/markup-include": "^4.23.
|
|
33
|
-
"@cdc/waffle-chart": "^4.23.
|
|
27
|
+
"@cdc/chart": "^4.23.5",
|
|
28
|
+
"@cdc/core": "^4.23.5",
|
|
29
|
+
"@cdc/dashboard": "^4.23.5",
|
|
30
|
+
"@cdc/data-bite": "^4.23.5",
|
|
31
|
+
"@cdc/map": "^4.23.5",
|
|
32
|
+
"@cdc/markup-include": "^4.23.5",
|
|
33
|
+
"@cdc/waffle-chart": "^4.23.5",
|
|
34
34
|
"axios": "^0.21.1",
|
|
35
35
|
"d3": "^7.0.0",
|
|
36
36
|
"html-react-parser": "^3.0.8",
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"react": "^18.2.0",
|
|
44
44
|
"react-dom": "^18.2.0"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "34add3436994ca3cf13e51f313add4d70377f53e"
|
|
47
47
|
}
|
package/src/CdcEditor.jsx
CHANGED
|
@@ -19,7 +19,7 @@ import Tabs from './components/Tabs'
|
|
|
19
19
|
|
|
20
20
|
import './scss/main.scss'
|
|
21
21
|
|
|
22
|
-
export default function CdcEditor({ config: configObj = { newViz: true }, hostname, containerEl, sharepath }) {
|
|
22
|
+
export default function CdcEditor({ config: configObj = { newViz: true }, hostname, containerEl, sharepath, isDebug }) {
|
|
23
23
|
const [config, setConfig] = useState(configObj)
|
|
24
24
|
const [tempConfig, setTempConfig] = useState(null)
|
|
25
25
|
const [errors, setErrors] = useState([])
|
|
@@ -146,7 +146,8 @@ export default function CdcEditor({ config: configObj = { newViz: true }, hostna
|
|
|
146
146
|
setGlobalActive,
|
|
147
147
|
tempConfig,
|
|
148
148
|
setTempConfig,
|
|
149
|
-
sharepath
|
|
149
|
+
sharepath,
|
|
150
|
+
isDebug
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
let configureDisabled = true
|
|
@@ -18,6 +18,7 @@ import PairedBarIcon from '@cdc/core/assets/icon-chart-bar-paired.svg'
|
|
|
18
18
|
import HorizontalStackIcon from '@cdc/core/assets/icon-chart-bar-stacked.svg'
|
|
19
19
|
import ScatterPlotIcon from '@cdc/core/assets/icon-chart-scatterplot.svg'
|
|
20
20
|
import BoxPlotIcon from '@cdc/core/assets/icon-chart-box-whisker.svg'
|
|
21
|
+
import AreaChartIcon from '@cdc/core/assets/icon-area-chart.svg'
|
|
21
22
|
|
|
22
23
|
export default function ChooseTab() {
|
|
23
24
|
const { config, setConfig, setGlobalActive, tempConfig, setTempConfig } = useContext(ConfigContext)
|
|
@@ -205,14 +206,14 @@ export default function ChooseTab() {
|
|
|
205
206
|
<Tooltip.Content>Display a scatter plot</Tooltip.Content>
|
|
206
207
|
</Tooltip>
|
|
207
208
|
</li>
|
|
208
|
-
|
|
209
|
+
<li>
|
|
209
210
|
<Tooltip>
|
|
210
211
|
<Tooltip.Target>
|
|
211
|
-
<IconButton label='Area Chart' type='chart' subType='Area Chart' orientation='vertical' icon={<
|
|
212
|
+
<IconButton label='Area Chart' type='chart' subType='Area Chart' orientation='vertical' icon={<AreaChartIcon />} />
|
|
212
213
|
</Tooltip.Target>
|
|
213
214
|
<Tooltip.Content>Display an area chart</Tooltip.Content>
|
|
214
215
|
</Tooltip>
|
|
215
|
-
</li>
|
|
216
|
+
</li>
|
|
216
217
|
</ul>
|
|
217
218
|
|
|
218
219
|
<div className='heading-2'>Maps</div>
|
|
@@ -13,7 +13,7 @@ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
|
13
13
|
import ConfigContext from '../ConfigContext'
|
|
14
14
|
|
|
15
15
|
export default function ConfigureTab({ containerEl }) {
|
|
16
|
-
const { config, setTempConfig, hostname } = useContext(ConfigContext)
|
|
16
|
+
const { config, setTempConfig, hostname, isDebug } = useContext(ConfigContext)
|
|
17
17
|
|
|
18
18
|
let { type } = config
|
|
19
19
|
|
|
@@ -21,37 +21,37 @@ export default function ConfigureTab({ containerEl }) {
|
|
|
21
21
|
case 'map':
|
|
22
22
|
return (
|
|
23
23
|
<ErrorBoundary component='CdcMap'>
|
|
24
|
-
<CdcMap isEditor={true} config={config} hostname={hostname} setConfig={setTempConfig} containerEl={containerEl} />
|
|
24
|
+
<CdcMap isEditor={true} isDebug={isDebug} config={config} hostname={hostname} setConfig={setTempConfig} containerEl={containerEl} />
|
|
25
25
|
</ErrorBoundary>
|
|
26
26
|
)
|
|
27
27
|
case 'chart':
|
|
28
28
|
return (
|
|
29
29
|
<ErrorBoundary component='CdcChart'>
|
|
30
|
-
<CdcChart isEditor={true} config={config} setConfig={setTempConfig} />
|
|
30
|
+
<CdcChart isEditor={true} isDebug={isDebug} config={config} setConfig={setTempConfig} />
|
|
31
31
|
</ErrorBoundary>
|
|
32
32
|
)
|
|
33
33
|
case 'dashboard':
|
|
34
34
|
return (
|
|
35
35
|
<ErrorBoundary component='CdcDashboard'>
|
|
36
|
-
<CdcDashboard isEditor={true} config={config} setConfig={setTempConfig} />
|
|
36
|
+
<CdcDashboard isEditor={true} isDebug={isDebug} config={config} setConfig={setTempConfig} />
|
|
37
37
|
</ErrorBoundary>
|
|
38
38
|
)
|
|
39
39
|
case 'data-bite':
|
|
40
40
|
return (
|
|
41
41
|
<ErrorBoundary component='CdcDashboard'>
|
|
42
|
-
<CdcDataBite isEditor={true} config={config} setConfig={setTempConfig} />
|
|
42
|
+
<CdcDataBite isEditor={true} isDebug={isDebug} config={config} setConfig={setTempConfig} />
|
|
43
43
|
</ErrorBoundary>
|
|
44
44
|
)
|
|
45
45
|
case 'waffle-chart':
|
|
46
46
|
return (
|
|
47
47
|
<ErrorBoundary component='CdcDashboard'>
|
|
48
|
-
<CdcWaffleChart isEditor={true} config={config} setConfig={setTempConfig} />
|
|
48
|
+
<CdcWaffleChart isEditor={true} isDebug={isDebug} config={config} setConfig={setTempConfig} />
|
|
49
49
|
</ErrorBoundary>
|
|
50
50
|
)
|
|
51
51
|
case 'markup-include':
|
|
52
52
|
return (
|
|
53
53
|
<ErrorBoundary component='CdcDashboard'>
|
|
54
|
-
<CdcMarkupInclude isEditor={true} config={config} setConfig={setTempConfig} />
|
|
54
|
+
<CdcMarkupInclude isEditor={true} isDebug={isDebug} config={config} setConfig={setTempConfig} />
|
|
55
55
|
</ErrorBoundary>
|
|
56
56
|
)
|
|
57
57
|
default:
|
|
@@ -17,7 +17,10 @@ import SampleData from './SampleData'
|
|
|
17
17
|
import FileUploadIcon from '../assets/icons/file-upload-solid.svg'
|
|
18
18
|
import CloseIcon from '@cdc/core/assets/icon-close.svg'
|
|
19
19
|
|
|
20
|
+
import fetchRemoteData from '@cdc/core/helpers/fetchRemoteData'
|
|
20
21
|
import DataDesigner from '@cdc/core/components/managers/DataDesigner'
|
|
22
|
+
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
23
|
+
import Icon from '@cdc/core/components/ui/Icon'
|
|
21
24
|
|
|
22
25
|
import '../scss/data-import.scss'
|
|
23
26
|
|
|
@@ -36,6 +39,8 @@ export default function DataImport() {
|
|
|
36
39
|
|
|
37
40
|
const [editingDataset, setEditingDataset] = useState()
|
|
38
41
|
|
|
42
|
+
const [asyncPreviewData, setAsyncPreviewData] = useState()
|
|
43
|
+
|
|
39
44
|
const supportedDataTypes = {
|
|
40
45
|
'.csv': 'text/csv',
|
|
41
46
|
'.json': 'application/json'
|
|
@@ -294,8 +299,6 @@ export default function DataImport() {
|
|
|
294
299
|
setEditingDataset(undefined)
|
|
295
300
|
}
|
|
296
301
|
setAddingDataset(false)
|
|
297
|
-
setExternalURL('')
|
|
298
|
-
setKeepURL(false)
|
|
299
302
|
} catch (err) {
|
|
300
303
|
setErrors(err)
|
|
301
304
|
}
|
|
@@ -320,6 +323,34 @@ export default function DataImport() {
|
|
|
320
323
|
setConfig(newConfig)
|
|
321
324
|
}, []) // eslint-disable-line
|
|
322
325
|
|
|
326
|
+
useEffect(() => {
|
|
327
|
+
const asyncWrapper = async () => {
|
|
328
|
+
if (config.type === 'dashboard') {
|
|
329
|
+
Object.keys(config.datasets).forEach(async datasetKey => {
|
|
330
|
+
if (config.datasets[datasetKey].preview) {
|
|
331
|
+
if (config.datasets[datasetKey].dataUrl) {
|
|
332
|
+
const remoteData = await fetchRemoteData(config.datasets[datasetKey].dataUrl)
|
|
333
|
+
if (Array.isArray(remoteData)) {
|
|
334
|
+
setAsyncPreviewData(remoteData)
|
|
335
|
+
}
|
|
336
|
+
} else if (Array.isArray(config.datasets[datasetKey].data)) {
|
|
337
|
+
setAsyncPreviewData(config.datasets[datasetKey].data)
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
})
|
|
341
|
+
} else {
|
|
342
|
+
if (config.dataUrl) {
|
|
343
|
+
const remoteData = await fetchRemoteData(config.dataUrl)
|
|
344
|
+
if (Array.isArray(remoteData)) {
|
|
345
|
+
setAsyncPreviewData(remoteData)
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
asyncWrapper()
|
|
352
|
+
}, [config.datasets]) // eslint-disable-line
|
|
353
|
+
|
|
323
354
|
const updateDescriptionProp = (visualizationKey, datasetKey, key, value) => {
|
|
324
355
|
if (config.type === 'dashboard') {
|
|
325
356
|
let dataDescription = { ...config.datasets[datasetKey].dataDescription, [key]: value }
|
|
@@ -395,9 +426,9 @@ export default function DataImport() {
|
|
|
395
426
|
return (
|
|
396
427
|
//todo convert to modal
|
|
397
428
|
<>
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
429
|
+
<button className='btn danger' onClick={() => resetEditor({ type: config.type, visualizationType: config.visualizationType }, 'Resetting will remove your data and settings. Do you want to continue?')}>
|
|
430
|
+
Clear
|
|
431
|
+
<CloseIcon />
|
|
401
432
|
</button>
|
|
402
433
|
{/* DEV-851 link to replace file should pop file dialog */}
|
|
403
434
|
{config.dataFileSourceType === 'file' && (
|
|
@@ -406,7 +437,8 @@ export default function DataImport() {
|
|
|
406
437
|
<p>
|
|
407
438
|
<span>or replace file</span>
|
|
408
439
|
</p>
|
|
409
|
-
</div>
|
|
440
|
+
</div>
|
|
441
|
+
)}
|
|
410
442
|
</>
|
|
411
443
|
)
|
|
412
444
|
}
|
|
@@ -475,7 +507,7 @@ export default function DataImport() {
|
|
|
475
507
|
if (config.type === 'dashboard') {
|
|
476
508
|
readyToConfigure = Object.keys(config.datasets).length > 0
|
|
477
509
|
Object.keys(config.datasets).forEach(datasetKey => {
|
|
478
|
-
if (config.datasets[datasetKey].preview) {
|
|
510
|
+
if (config.datasets[datasetKey].preview && Array.isArray(config.datasets[datasetKey].data)) {
|
|
479
511
|
previewData = config.datasets[datasetKey].data
|
|
480
512
|
}
|
|
481
513
|
})
|
|
@@ -491,6 +523,139 @@ export default function DataImport() {
|
|
|
491
523
|
readyToConfigure = true
|
|
492
524
|
}
|
|
493
525
|
|
|
526
|
+
const urlFilters = (
|
|
527
|
+
<>
|
|
528
|
+
{config.filters &&
|
|
529
|
+
config.filters.map((filter, i) =>
|
|
530
|
+
filter.type !== 'url' ? (
|
|
531
|
+
<></>
|
|
532
|
+
) : (
|
|
533
|
+
<fieldset key={filter.key} className='edit-block url-filters-block'>
|
|
534
|
+
<button
|
|
535
|
+
onClick={e => {
|
|
536
|
+
let newFilters = [...config.filters]
|
|
537
|
+
newFilters.splice(i, 1)
|
|
538
|
+
setConfig({ ...config, filters: newFilters, runtimeDataUrl: undefined })
|
|
539
|
+
}}
|
|
540
|
+
>
|
|
541
|
+
Remove
|
|
542
|
+
</button>
|
|
543
|
+
<label>
|
|
544
|
+
<span class='edit-label column-heading'>
|
|
545
|
+
Label
|
|
546
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
547
|
+
<Tooltip.Target>
|
|
548
|
+
<Icon display='question' />
|
|
549
|
+
</Tooltip.Target>
|
|
550
|
+
<Tooltip.Content>
|
|
551
|
+
<p style={{ padding: '0.5rem' }}>The label that will appear above the dropdown filter.</p>
|
|
552
|
+
</Tooltip.Content>
|
|
553
|
+
</Tooltip>
|
|
554
|
+
</span>{' '}
|
|
555
|
+
<input
|
|
556
|
+
type='text'
|
|
557
|
+
defaultValue={filter.label}
|
|
558
|
+
onChange={e => {
|
|
559
|
+
let newFilters = [...config.filters]
|
|
560
|
+
newFilters[i].label = e.target.value
|
|
561
|
+
setConfig({ ...config, filters: newFilters })
|
|
562
|
+
}}
|
|
563
|
+
/>
|
|
564
|
+
</label>
|
|
565
|
+
<label>
|
|
566
|
+
<span class='edit-label column-heading'>
|
|
567
|
+
Query string parameter
|
|
568
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
569
|
+
<Tooltip.Target>
|
|
570
|
+
<Icon display='question' />
|
|
571
|
+
</Tooltip.Target>
|
|
572
|
+
<Tooltip.Content>
|
|
573
|
+
<p style={{ padding: '0.5rem' }}>Name of the query string parameter that will be appended to the URL above with the values provided below.</p>
|
|
574
|
+
</Tooltip.Content>
|
|
575
|
+
</Tooltip>
|
|
576
|
+
</span>{' '}
|
|
577
|
+
<input
|
|
578
|
+
type='text'
|
|
579
|
+
defaultValue={filter.queryParameter}
|
|
580
|
+
onChange={e => {
|
|
581
|
+
let newFilters = [...config.filters]
|
|
582
|
+
newFilters[i].queryParameter = e.target.value
|
|
583
|
+
setConfig({ ...config, filters: newFilters })
|
|
584
|
+
}}
|
|
585
|
+
/>
|
|
586
|
+
</label>
|
|
587
|
+
<label>
|
|
588
|
+
<span class='edit-label column-heading'>Values</span>{' '}
|
|
589
|
+
</label>
|
|
590
|
+
<ul className='value-list'>
|
|
591
|
+
{filter.orderedValues &&
|
|
592
|
+
filter.orderedValues.map((value, valueIndex) => (
|
|
593
|
+
<li>
|
|
594
|
+
{value}
|
|
595
|
+
<input
|
|
596
|
+
type='text'
|
|
597
|
+
placeholder='Enter value display name here'
|
|
598
|
+
value={filter.labels ? filter.labels[value] : undefined}
|
|
599
|
+
className='url-value-label'
|
|
600
|
+
onChange={e => {
|
|
601
|
+
let newFilters = [...config.filters]
|
|
602
|
+
|
|
603
|
+
newFilters[i].labels = newFilters[i].labels || {}
|
|
604
|
+
newFilters[i].labels[value] = e.target.value
|
|
605
|
+
|
|
606
|
+
setConfig({ ...config, filters: newFilters })
|
|
607
|
+
}}
|
|
608
|
+
/>
|
|
609
|
+
<button
|
|
610
|
+
onClick={() => {
|
|
611
|
+
let newFilters = [...config.filters]
|
|
612
|
+
|
|
613
|
+
if (newFilters[i].labels) {
|
|
614
|
+
delete newFilters[i].labels[newFilters[i].orderedValues[valueIndex]]
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
newFilters[i].orderedValues.splice(valueIndex, 1)
|
|
618
|
+
setConfig({ ...config, filters: newFilters })
|
|
619
|
+
}}
|
|
620
|
+
>
|
|
621
|
+
X
|
|
622
|
+
</button>
|
|
623
|
+
</li>
|
|
624
|
+
))}
|
|
625
|
+
</ul>
|
|
626
|
+
<form
|
|
627
|
+
onSubmit={e => {
|
|
628
|
+
e.preventDefault()
|
|
629
|
+
if (!config.filters[i].orderedValues || config.filters[i].orderedValues.indexOf(e.target[0].value) === -1) {
|
|
630
|
+
let newFilters = [...config.filters]
|
|
631
|
+
newFilters[i].orderedValues = newFilters[i].orderedValues || []
|
|
632
|
+
newFilters[i].orderedValues.push(e.target[0].value)
|
|
633
|
+
newFilters[i].values = newFilters[i].orderedValues
|
|
634
|
+
if (!newFilters[i].active) newFilters[i].active = e.target[0].value
|
|
635
|
+
e.target[0].value = ''
|
|
636
|
+
setConfig({ ...config, filters: newFilters })
|
|
637
|
+
}
|
|
638
|
+
}}
|
|
639
|
+
>
|
|
640
|
+
<input type='text' placeholder='Enter new value name here' />{' '}
|
|
641
|
+
<button type='submit' style={{ marginTop: '1em' }}>
|
|
642
|
+
Add New Value
|
|
643
|
+
</button>
|
|
644
|
+
</form>
|
|
645
|
+
</fieldset>
|
|
646
|
+
)
|
|
647
|
+
)}
|
|
648
|
+
<button
|
|
649
|
+
className='btn full-width'
|
|
650
|
+
onClick={() => {
|
|
651
|
+
setConfig({ ...config, filters: config.filters ? [...config.filters, { type: 'url', key: Date.now() }] : [{ type: 'url', key: Date.now() }] })
|
|
652
|
+
}}
|
|
653
|
+
>
|
|
654
|
+
Add New URL Filter
|
|
655
|
+
</button>
|
|
656
|
+
</>
|
|
657
|
+
)
|
|
658
|
+
|
|
494
659
|
const showDataDesigner = config.visualizationType !== 'Box Plot' && config.visualizationType !== 'Scatter Plot'
|
|
495
660
|
|
|
496
661
|
return (
|
|
@@ -560,7 +725,7 @@ export default function DataImport() {
|
|
|
560
725
|
<>
|
|
561
726
|
<div className='heading-3'>Data Source</div>
|
|
562
727
|
<div className='file-loaded-area'>
|
|
563
|
-
{config.dataFileSourceType === 'file' && (
|
|
728
|
+
{(config.dataFileSourceType === 'file' || !config.dataFileSourceType) && (
|
|
564
729
|
<div className='data-source-options'>
|
|
565
730
|
<div className={isDragActive2 ? 'drag-active cdcdataviz-file-selector loaded-file' : 'cdcdataviz-file-selector loaded-file'} {...getRootProps2()}>
|
|
566
731
|
<input {...getInputProps2()} />
|
|
@@ -577,10 +742,13 @@ export default function DataImport() {
|
|
|
577
742
|
)}
|
|
578
743
|
|
|
579
744
|
{config.dataFileSourceType === 'url' && (
|
|
580
|
-
|
|
581
|
-
<div>
|
|
582
|
-
|
|
583
|
-
|
|
745
|
+
<>
|
|
746
|
+
<div className='url-source-options'>
|
|
747
|
+
<div>{loadFileFromUrl(externalURL)}</div>
|
|
748
|
+
<div>{resetButton()}</div>
|
|
749
|
+
</div>
|
|
750
|
+
{config.dataUrl && (config.type === 'chart' || config.type === 'map') && urlFilters}
|
|
751
|
+
</>
|
|
584
752
|
)}
|
|
585
753
|
</div>
|
|
586
754
|
</>
|
|
@@ -614,10 +782,10 @@ export default function DataImport() {
|
|
|
614
782
|
{errors &&
|
|
615
783
|
(errors.map
|
|
616
784
|
? errors.map((message, index) => (
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
785
|
+
<div className='error-box slim mt-2' key={`error-${message}`}>
|
|
786
|
+
<span>{message}</span> <CloseIcon className='inline-icon dismiss-error' onClick={() => setErrors(errors.filter((val, i) => i !== index))} />
|
|
787
|
+
</div>
|
|
788
|
+
))
|
|
621
789
|
: errors.message)}
|
|
622
790
|
<p className='footnote'>
|
|
623
791
|
Supported file types: {Object.keys(supportedDataTypes).join(', ')}. Maximum file size {maxFileSize}MB.
|
|
@@ -627,29 +795,24 @@ export default function DataImport() {
|
|
|
627
795
|
<SampleDataContext.Provider value={{ loadData, editingDataset, config }}>
|
|
628
796
|
<SampleData.Buttons />
|
|
629
797
|
</SampleDataContext.Provider>
|
|
630
|
-
</div
|
|
631
|
-
)
|
|
632
|
-
}
|
|
798
|
+
</div>
|
|
799
|
+
)}
|
|
633
800
|
|
|
634
|
-
{
|
|
635
|
-
|
|
636
|
-
<
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
)
|
|
642
|
-
}
|
|
801
|
+
{config.type === 'dashboard' && !addingDataset && (
|
|
802
|
+
<p>
|
|
803
|
+
<button className='btn btn-primary' onClick={() => setAddingDataset(true)}>
|
|
804
|
+
+ Add More Files
|
|
805
|
+
</button>
|
|
806
|
+
</p>
|
|
807
|
+
)}
|
|
643
808
|
|
|
644
|
-
{
|
|
645
|
-
|
|
646
|
-
<
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
)
|
|
652
|
-
}
|
|
809
|
+
{readyToConfigure && (
|
|
810
|
+
<p>
|
|
811
|
+
<button className='btn btn-primary' onClick={() => setGlobalActive(2)}>
|
|
812
|
+
Configure your visualization
|
|
813
|
+
</button>
|
|
814
|
+
</p>
|
|
815
|
+
)}
|
|
653
816
|
|
|
654
817
|
<a href='https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/data-map.html' target='_blank' rel='noopener noreferrer' className='guidance-link'>
|
|
655
818
|
<div>
|
|
@@ -657,9 +820,9 @@ export default function DataImport() {
|
|
|
657
820
|
<p>Documentation and examples on formatting data and configuring visualizations.</p>
|
|
658
821
|
</div>
|
|
659
822
|
</a>
|
|
660
|
-
</div
|
|
823
|
+
</div>
|
|
661
824
|
<div className='right-col'>
|
|
662
|
-
<PreviewDataTable data={previewData} />
|
|
825
|
+
<PreviewDataTable data={asyncPreviewData || previewData} />
|
|
663
826
|
</div>
|
|
664
827
|
</>
|
|
665
828
|
)
|
|
@@ -28,12 +28,12 @@ const sampleData = {
|
|
|
28
28
|
text: 'Scatter Plot Sample Data',
|
|
29
29
|
fileName: 'valid-scatterplot.csv',
|
|
30
30
|
data: validScatterPlot
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
text: 'Area Chart Sample Data',
|
|
34
|
+
fileName: 'valid-area-chart.json',
|
|
35
|
+
data: validAreaChart
|
|
31
36
|
}
|
|
32
|
-
// {
|
|
33
|
-
// text: 'Area Chart Sample Data',
|
|
34
|
-
// fileName: 'valid-area-chart.json',
|
|
35
|
-
// data: validAreaChart
|
|
36
|
-
// }
|
|
37
37
|
],
|
|
38
38
|
maps: [
|
|
39
39
|
{
|
package/src/index.jsx
CHANGED
|
@@ -9,8 +9,10 @@ let activeTab = Number.parseInt(standaloneParams.get('active')) - 1 || null
|
|
|
9
9
|
|
|
10
10
|
let domContainer = document.getElementsByClassName('react-container')[0]
|
|
11
11
|
|
|
12
|
+
let isDebug = window.location.href.includes('debug=true')
|
|
13
|
+
|
|
12
14
|
ReactDOM.createRoot(domContainer).render(
|
|
13
15
|
<React.StrictMode>
|
|
14
|
-
<CdcEditor startingTab={activeTab} containerEl={domContainer} />
|
|
15
|
-
</React.StrictMode
|
|
16
|
+
<CdcEditor startingTab={activeTab} containerEl={domContainer} isDebug={isDebug} />
|
|
17
|
+
</React.StrictMode>
|
|
16
18
|
)
|