@cdc/map 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.
@@ -27,6 +27,9 @@ import AlabamaGraphic from '@cdc/core/assets/icon-map-alabama.svg'
27
27
  import worldDefaultConfig from '../../examples/default-world.json'
28
28
  import usaDefaultConfig from '../../examples/default-usa.json'
29
29
  import countyDefaultConfig from '../../examples/default-county.json'
30
+ import useMapLayers from '../hooks/useMapLayers'
31
+
32
+ import { useFilters } from '@cdc/core/components/Filters'
30
33
 
31
34
  const TextField = ({ label, section = null, subsection = null, fieldName, updateField, value: stateValue, type = 'input', tooltip, ...attributes }) => {
32
35
  const [value, setValue] = useState(stateValue)
@@ -65,9 +68,9 @@ const TextField = ({ label, section = null, subsection = null, fieldName, update
65
68
  }
66
69
 
67
70
  const EditorPanel = props => {
68
- const { state, columnsInData = [], loadConfig, setState, isDashboard, setParentConfig, setRuntimeFilters, runtimeFilters, runtimeLegend, changeFilterActive } = props
71
+ const { state, columnsInData = [], loadConfig, setState, isDashboard, setParentConfig, runtimeFilters, runtimeLegend, changeFilterActive, isDebug, setRuntimeFilters } = props
69
72
 
70
- const { general, columns, legend, dataTable, tooltips } = state
73
+ const { general, columns, legend, table, tooltips } = state
71
74
 
72
75
  const [requiredColumns, setRequiredColumns] = useState(null) // Simple state so we know if we need more information before parsing the map
73
76
 
@@ -79,8 +82,22 @@ const EditorPanel = props => {
79
82
 
80
83
  const [activeFilterValueForDescription, setActiveFilterValueForDescription] = useState([0, 0])
81
84
 
85
+ const { handleFilterOrder, filterOrderOptions, filterStyleOptions } = useFilters({ config: state, setConfig: setState, filteredData: runtimeFilters, setFilteredData: setRuntimeFilters })
86
+
82
87
  const headerColors = ['theme-blue', 'theme-purple', 'theme-brown', 'theme-teal', 'theme-pink', 'theme-orange', 'theme-slate', 'theme-indigo', 'theme-cyan', 'theme-green', 'theme-amber']
83
88
 
89
+ const {
90
+ // prettier-ignore
91
+ MapLayerHandlers: {
92
+ handleAddLayer,
93
+ handleMapLayerName,
94
+ handleMapLayerUrl,
95
+ handleRemoveLayer,
96
+ handleMapLayerNamespace,
97
+ handleMapLayerTooltip
98
+ }
99
+ } = useMapLayers(state, setState, false, true)
100
+
84
101
  const categoryMove = (idx1, idx2) => {
85
102
  let categoryValuesOrder = [...state.legend.categoryValuesOrder]
86
103
 
@@ -119,7 +136,7 @@ const EditorPanel = props => {
119
136
  }
120
137
 
121
138
  const CheckBox = memo(({ label, value, fieldName, section = null, subsection = null, tooltip, updateField, ...attributes }) => (
122
- <label className='checkbox'>
139
+ <label className='checkbox column-heading'>
123
140
  <input
124
141
  type='checkbox'
125
142
  name={fieldName}
@@ -136,23 +153,6 @@ const EditorPanel = props => {
136
153
  </label>
137
154
  ))
138
155
 
139
- const handleFilterOrder = (idx1, idx2, filterIndex, filter) => {
140
- let filterOrder = filter.values
141
- let [movedItem] = filterOrder.splice(idx1, 1)
142
- filterOrder.splice(idx2, 0, movedItem)
143
- let filters = [...runtimeFilters]
144
- let filterItem = { ...runtimeFilters[filterIndex] }
145
- filterItem.active = filter.values[0]
146
- filterItem.values = filterOrder
147
- filterItem.order = 'cust'
148
- filters[filterIndex] = filterItem
149
-
150
- setState({
151
- ...state,
152
- filters
153
- })
154
- }
155
-
156
156
  const DynamicDesc = ({ label, fieldName, value: stateValue, type = 'input', ...attributes }) => {
157
157
  const [value, setValue] = useState(stateValue)
158
158
 
@@ -201,6 +201,17 @@ const EditorPanel = props => {
201
201
  }
202
202
  })
203
203
  break
204
+
205
+ case 'toggleDataTableLink':
206
+ setState({
207
+ ...state,
208
+ table: {
209
+ ...state.table,
210
+ showDataTableLink: value
211
+ }
212
+ })
213
+ break
214
+
204
215
  case 'toggleDataUrl':
205
216
  setState({
206
217
  ...state,
@@ -276,9 +287,9 @@ const EditorPanel = props => {
276
287
  case 'expandDataTable':
277
288
  setState({
278
289
  ...state,
279
- general: {
280
- ...state.general,
281
- expandDataTable: value
290
+ table: {
291
+ ...state.table,
292
+ expanded: value
282
293
  }
283
294
  })
284
295
  break
@@ -409,6 +420,11 @@ const EditorPanel = props => {
409
420
  general: {
410
421
  ...state.general,
411
422
  showDownloadButton: !state.general.showDownloadButton
423
+ },
424
+ table: {
425
+ // setting both bc DataTable new core needs it here
426
+ ...state.table,
427
+ download: !state.general.showDownloadButton
412
428
  }
413
429
  })
414
430
  break
@@ -498,7 +514,7 @@ const EditorPanel = props => {
498
514
  })
499
515
  break
500
516
  default:
501
- console.warn('Map type not set')
517
+ console.warn('COVE: Map type not set') // eslint-disable-line
502
518
  break
503
519
  }
504
520
  break
@@ -528,8 +544,8 @@ const EditorPanel = props => {
528
544
  geoType: 'us',
529
545
  type: state.type === 'us-geocode' ? 'data' : state.type
530
546
  },
531
- dataTable: {
532
- ...state.dataTable,
547
+ table: {
548
+ ...state.table,
533
549
  forceDisplay: true
534
550
  }
535
551
  })
@@ -541,8 +557,8 @@ const EditorPanel = props => {
541
557
  ...state.general,
542
558
  geoType: 'us-region'
543
559
  },
544
- dataTable: {
545
- ...state.dataTable,
560
+ table: {
561
+ ...state.table,
546
562
  forceDisplay: true
547
563
  }
548
564
  })
@@ -554,8 +570,8 @@ const EditorPanel = props => {
554
570
  ...state.general,
555
571
  geoType: 'world'
556
572
  },
557
- dataTable: {
558
- ...state.dataTable,
573
+ table: {
574
+ ...state.table,
559
575
  forceDisplay: true
560
576
  }
561
577
  })
@@ -565,11 +581,11 @@ const EditorPanel = props => {
565
581
  ...state,
566
582
  general: {
567
583
  ...state.general,
568
- geoType: 'us-county',
569
- expandDataTable: false
584
+ geoType: 'us-county'
570
585
  },
571
- dataTable: {
572
- ...state.dataTable,
586
+ table: {
587
+ ...state.table,
588
+ expanded: false,
573
589
  forceDisplay: true
574
590
  }
575
591
  })
@@ -579,11 +595,11 @@ const EditorPanel = props => {
579
595
  ...state,
580
596
  general: {
581
597
  ...state.general,
582
- geoType: 'single-state',
583
- expandDataTable: false
598
+ geoType: 'single-state'
584
599
  },
585
- dataTable: {
586
- ...state.dataTable,
600
+ table: {
601
+ ...state.table,
602
+ expanded: false,
587
603
  forceDisplay: true
588
604
  }
589
605
  })
@@ -687,8 +703,8 @@ const EditorPanel = props => {
687
703
  case 'showDataTable':
688
704
  setState({
689
705
  ...state,
690
- dataTable: {
691
- ...state.dataTable,
706
+ table: {
707
+ ...state.table,
692
708
  forceDisplay: value
693
709
  }
694
710
  })
@@ -696,8 +712,8 @@ const EditorPanel = props => {
696
712
  case 'limitDataTableHeight':
697
713
  setState({
698
714
  ...state,
699
- dataTable: {
700
- ...state.dataTable,
715
+ table: {
716
+ ...state.table,
701
717
  limitHeight: value
702
718
  }
703
719
  })
@@ -733,8 +749,14 @@ const EditorPanel = props => {
733
749
  }
734
750
  })
735
751
  break
752
+ case 'filterBehavior':
753
+ setState({
754
+ ...state,
755
+ filterBehavior: value
756
+ })
757
+ break
736
758
  default:
737
- console.warn(`Did not recognize editor property.`)
759
+ console.warn(`COVE: Did not recognize editor property.`) // eslint-disable-line
738
760
  break
739
761
  }
740
762
  }
@@ -857,6 +879,10 @@ const EditorPanel = props => {
857
879
  newFilters.splice(idx, 1)
858
880
  }
859
881
  break
882
+ case 'filterStyle':
883
+ newFilters[idx] = { ...newFilters[idx] }
884
+ newFilters[idx].filterStyle = value
885
+ break
860
886
  case 'columnName':
861
887
  newFilters[idx] = { ...newFilters[idx] }
862
888
  newFilters[idx].columnName = value
@@ -889,6 +915,7 @@ const EditorPanel = props => {
889
915
  })
890
916
  }
891
917
 
918
+ // just adds a new column but not set to any data yet
892
919
  const addAdditionalColumn = number => {
893
920
  const columnKey = `additionalColumn${number}`
894
921
 
@@ -907,6 +934,33 @@ const EditorPanel = props => {
907
934
  })
908
935
  }
909
936
 
937
+ const MapFilters = () => {
938
+ return (
939
+ <>
940
+ <label>
941
+ Filter Behavior
942
+ <select
943
+ value={state.filterBehavior}
944
+ onChange={e => {
945
+ setState({
946
+ ...state,
947
+ filterBehavior: e.target.value
948
+ })
949
+ }}
950
+ >
951
+ <option key='Apply Button' value='Apply Button'>
952
+ Apply Button
953
+ </option>
954
+ <option key='Filter Change' value='Filter Change'>
955
+ Filter Change
956
+ </option>
957
+ </select>
958
+ </label>
959
+ {filtersJSX}
960
+ </>
961
+ )
962
+ }
963
+
910
964
  const removeAdditionalColumn = columnName => {
911
965
  const newColumns = state.columns
912
966
 
@@ -1008,7 +1062,7 @@ const EditorPanel = props => {
1008
1062
  if (!isReversed && state.color.endsWith('reverse')) {
1009
1063
  paletteName = state.color.slice(0, -7)
1010
1064
  }
1011
- if(paletteName){
1065
+ if (paletteName) {
1012
1066
  handleEditorChanges('color', paletteName)
1013
1067
  }
1014
1068
  }, [isReversed])
@@ -1136,103 +1190,110 @@ const EditorPanel = props => {
1136
1190
  const usedFilterColumns = {}
1137
1191
 
1138
1192
  const filtersJSX = state.filters.map((filter, index) => {
1193
+ if (filter.type === 'url') return <></>
1194
+
1139
1195
  if (filter.columnName) {
1140
1196
  usedFilterColumns[filter.columnName] = true
1141
1197
  }
1142
1198
 
1143
- const filterOptions = [
1144
- {
1145
- label: 'Ascending Alphanumeric',
1146
- value: 'asc'
1147
- },
1148
- {
1149
- label: 'Descending Alphanumeric',
1150
- value: 'desc'
1151
- },
1152
- {
1153
- label: 'Custom',
1154
- value: 'cust'
1155
- }
1156
- ]
1157
-
1158
1199
  return (
1159
- <fieldset className='edit-block' key={`filter-${index}`}>
1160
- <button
1161
- className='remove-column'
1162
- onClick={e => {
1163
- e.preventDefault()
1164
- changeFilter(index, 'remove')
1165
- }}
1166
- >
1167
- Remove
1168
- </button>
1169
- <TextField value={state.filters[index].label} section='filters' subsection={index} fieldName='label' label='Label' updateField={updateField} />
1170
- <label>
1171
- <span className='edit-label column-heading'>
1172
- Filter Column
1173
- <Tooltip style={{ textTransform: 'none' }}>
1174
- <Tooltip.Target>
1175
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1176
- </Tooltip.Target>
1177
- <Tooltip.Content>
1178
- <p>Selecting a column will add a dropdown menu below the map legend and allow users to filter based on the values in this column.</p>
1179
- </Tooltip.Content>
1180
- </Tooltip>
1181
- </span>
1182
- <select
1183
- value={filter.columnName}
1184
- onChange={event => {
1185
- changeFilter(index, 'columnName', event.target.value)
1186
- }}
1187
- >
1188
- {columnsOptions.filter(({ key }) => undefined === usedFilterColumns[key] || filter.columnName === key)}
1189
- </select>
1190
- </label>
1191
-
1192
- <label>
1193
- <span className='edit-filterOrder column-heading'>Filter Order</span>
1194
- <select
1195
- value={filter.order}
1196
- onChange={e => {
1197
- changeFilter(index, 'filterOrder', e.target.value)
1198
- changeFilterActive(index, filter.values[0])
1200
+ <>
1201
+ <fieldset className='edit-block' key={`filter-${index}`}>
1202
+ <button
1203
+ className='remove-column'
1204
+ onClick={e => {
1205
+ e.preventDefault()
1206
+ changeFilter(index, 'remove')
1199
1207
  }}
1200
1208
  >
1201
- {filterOptions.map((option, index) => {
1202
- return (
1203
- <option value={option.value} key={`filter-${index}`}>
1204
- {option.label}
1205
- </option>
1206
- )
1207
- })}
1208
- </select>
1209
- </label>
1210
-
1211
- {filter.order === 'cust' && (
1212
- <DragDropContext onDragEnd={({ source, destination }) => handleFilterOrder(source.index, destination.index, index, runtimeFilters[index])}>
1213
- <Droppable droppableId='filter_order'>
1214
- {provided => (
1215
- <ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
1216
- {runtimeFilters[index]?.values.map((value, index) => {
1217
- return (
1218
- <Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
1219
- {(provided, snapshot) => (
1220
- <li>
1221
- <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
1222
- {value}
1223
- </div>
1224
- </li>
1225
- )}
1226
- </Draggable>
1227
- )
1228
- })}
1229
- {provided.placeholder}
1230
- </ul>
1231
- )}
1232
- </Droppable>
1233
- </DragDropContext>
1234
- )}
1235
- </fieldset>
1209
+ Remove
1210
+ </button>
1211
+ <TextField value={state.filters[index].label} section='filters' subsection={index} fieldName='label' label='Label' updateField={updateField} />
1212
+ <label>
1213
+ <span className='edit-label column-heading'>
1214
+ Filter Column
1215
+ <Tooltip style={{ textTransform: 'none' }}>
1216
+ <Tooltip.Target>
1217
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1218
+ </Tooltip.Target>
1219
+ <Tooltip.Content>
1220
+ <p>Selecting a column will add a dropdown menu below the map legend and allow users to filter based on the values in this column.</p>
1221
+ </Tooltip.Content>
1222
+ </Tooltip>
1223
+ </span>
1224
+ <select
1225
+ value={filter.columnName}
1226
+ onChange={event => {
1227
+ changeFilter(index, 'columnName', event.target.value)
1228
+ }}
1229
+ >
1230
+ {columnsOptions.filter(({ key }) => undefined === usedFilterColumns[key] || filter.columnName === key)}
1231
+ </select>
1232
+ </label>
1233
+
1234
+ <label>
1235
+ <span className='edit-filterOrder column-heading'>Filter Style</span>
1236
+ <select
1237
+ value={filter.filterStyle}
1238
+ onChange={e => {
1239
+ changeFilter(index, 'filterStyle', e.target.value)
1240
+ }}
1241
+ >
1242
+ {filterStyleOptions.map((option, index) => {
1243
+ return (
1244
+ <option value={option} key={`filter-${option}--${index}`}>
1245
+ {option}
1246
+ </option>
1247
+ )
1248
+ })}
1249
+ </select>
1250
+ </label>
1251
+
1252
+ <label>
1253
+ <span className='edit-filterOrder column-heading'>Filter Order</span>
1254
+ <select
1255
+ value={filter.order}
1256
+ onChange={e => {
1257
+ changeFilter(index, 'filterOrder', e.target.value)
1258
+ changeFilterActive(index, filter.values[0])
1259
+ }}
1260
+ >
1261
+ {filterOrderOptions.map((option, index) => {
1262
+ return (
1263
+ <option value={option.value} key={`filter-${index}`}>
1264
+ {option.label}
1265
+ </option>
1266
+ )
1267
+ })}
1268
+ </select>
1269
+ </label>
1270
+
1271
+ {filter.order === 'cust' && (
1272
+ <DragDropContext onDragEnd={({ source, destination }) => handleFilterOrder(source.index, destination.index, index, state.filters[index])}>
1273
+ <Droppable droppableId='filter_order'>
1274
+ {provided => (
1275
+ <ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
1276
+ {state.filters[index]?.values.map((value, index) => {
1277
+ return (
1278
+ <Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
1279
+ {(provided, snapshot) => (
1280
+ <li>
1281
+ <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
1282
+ {value}
1283
+ </div>
1284
+ </li>
1285
+ )}
1286
+ </Draggable>
1287
+ )
1288
+ })}
1289
+ {provided.placeholder}
1290
+ </ul>
1291
+ )}
1292
+ </Droppable>
1293
+ </DragDropContext>
1294
+ )}
1295
+ </fieldset>
1296
+ </>
1236
1297
  )
1237
1298
  })
1238
1299
 
@@ -1315,6 +1376,24 @@ const EditorPanel = props => {
1315
1376
  )
1316
1377
  }
1317
1378
 
1379
+ const isLoadedFromUrl = state?.dataKey?.includes('http://') || state?.dataKey?.includes('https://')
1380
+
1381
+ // if isDebug = true, then try to set the Geography Col and Data col to reduce clicking
1382
+ const setGeoColumn = () => {
1383
+ // only for debug mode
1384
+ let geoColFound = columnsInData.includes(state.columns.geo.name)
1385
+ if (undefined !== isDebug && isDebug && !geoColFound) {
1386
+ // then try to set the x axis to appropriate value so we dont have to manually do it
1387
+ let mapcols = columnsInData[0]
1388
+ if (mapcols !== '') editColumn('geo', 'name', mapcols)
1389
+
1390
+ if (!state.columns.hasOwnProperty('primary') || undefined === state.columns.primary.name || '' === state.columns.primary.name || !state.columns.primary.name) {
1391
+ editColumn('primary', 'name', columnsInData[1]) // blindly picks first value col
1392
+ }
1393
+ }
1394
+ }
1395
+ if (isDebug) setGeoColumn()
1396
+
1318
1397
  return (
1319
1398
  <ErrorBoundary component='EditorPanel'>
1320
1399
  {state?.runtime?.editorErrorMessage.length > 0 && <Error />}
@@ -2131,6 +2210,7 @@ const EditorPanel = props => {
2131
2210
  </label>
2132
2211
  )}
2133
2212
  {/* always show */}
2213
+ {/*
2134
2214
  <label className='checkbox'>
2135
2215
  <input
2136
2216
  type='checkbox'
@@ -2140,7 +2220,7 @@ const EditorPanel = props => {
2140
2220
  }}
2141
2221
  />
2142
2222
  <span className='edit-label'>Show Special Classes Last</span>
2143
- </label>
2223
+ </label> */}
2144
2224
  {'category' !== legend.type && (
2145
2225
  <label className='checkbox'>
2146
2226
  <input type='checkbox' checked={legend.separateZero || false} onChange={event => handleEditorChanges('separateZero', event.target.checked)} />
@@ -2158,7 +2238,6 @@ const EditorPanel = props => {
2158
2238
  </label>
2159
2239
  )}
2160
2240
  {/* Temp Checkbox */}
2161
-
2162
2241
  {state.legend.type === 'equalnumber' && (
2163
2242
  <label className='checkbox mt-4'>
2164
2243
  <input
@@ -2322,7 +2401,7 @@ const EditorPanel = props => {
2322
2401
  <AccordionItemButton>Filters</AccordionItemButton>
2323
2402
  </AccordionItemHeading>
2324
2403
  <AccordionItemPanel>
2325
- {filtersJSX.length > 0 ? filtersJSX : <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
2404
+ {filtersJSX.length > 0 ? <MapFilters /> : <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
2326
2405
  <button
2327
2406
  className={'btn full-width'}
2328
2407
  onClick={event => {
@@ -2344,10 +2423,10 @@ const EditorPanel = props => {
2344
2423
  </AccordionItemHeading>
2345
2424
  <AccordionItemPanel>
2346
2425
  <TextField
2347
- value={dataTable.title}
2426
+ value={table.label}
2348
2427
  updateField={updateField}
2349
- section='dataTable'
2350
- fieldName='title'
2428
+ section='table'
2429
+ fieldName='label'
2351
2430
  id='dataTableTitle'
2352
2431
  label='Data Table Title'
2353
2432
  placeholder='Data Table'
@@ -2365,16 +2444,16 @@ const EditorPanel = props => {
2365
2444
  <label className='checkbox'>
2366
2445
  <input
2367
2446
  type='checkbox'
2368
- checked={state.dataTable.forceDisplay !== undefined ? state.dataTable.forceDisplay : !isDashboard}
2447
+ checked={state.table.forceDisplay !== undefined ? state.table.forceDisplay : !isDashboard}
2369
2448
  onChange={event => {
2370
2449
  handleEditorChanges('showDataTable', event.target.checked)
2371
2450
  }}
2372
2451
  />
2373
- <span className='edit-label'>
2374
- Show Table
2452
+ <span className='edit-label column-heading'>
2453
+ Show Data Table
2375
2454
  <Tooltip style={{ textTransform: 'none' }}>
2376
2455
  <Tooltip.Target>
2377
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2456
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2378
2457
  </Tooltip.Target>
2379
2458
  <Tooltip.Content>
2380
2459
  <p>Data tables are required for 508 compliance. When choosing to hide this data table, replace with your own version.</p>
@@ -2383,9 +2462,9 @@ const EditorPanel = props => {
2383
2462
  </span>
2384
2463
  </label>
2385
2464
  <TextField
2386
- value={dataTable.indexLabel || ''}
2465
+ value={table.indexLabel || ''}
2387
2466
  updateField={updateField}
2388
- section='dataTable'
2467
+ section='table'
2389
2468
  fieldName='indexLabel'
2390
2469
  label='Index Column Header'
2391
2470
  placeholder='Location'
@@ -2401,9 +2480,9 @@ const EditorPanel = props => {
2401
2480
  }
2402
2481
  />
2403
2482
  <TextField
2404
- value={dataTable.caption}
2483
+ value={state.table.caption}
2405
2484
  updateField={updateField}
2406
- section='dataTable'
2485
+ section='table'
2407
2486
  fieldName='caption'
2408
2487
  label='Data Table Caption'
2409
2488
  placeholder='Data Table'
@@ -2422,34 +2501,48 @@ const EditorPanel = props => {
2422
2501
  <label className='checkbox'>
2423
2502
  <input
2424
2503
  type='checkbox'
2425
- checked={state.dataTable.limitHeight}
2504
+ checked={state.table.limitHeight}
2426
2505
  onChange={event => {
2427
2506
  handleEditorChanges('limitDataTableHeight', event.target.checked)
2428
2507
  }}
2429
2508
  />
2430
2509
  <span className='edit-label'>Limit Table Height</span>
2431
2510
  </label>
2432
- {state.dataTable.limitHeight && <TextField value={dataTable.height} updateField={updateField} section='dataTable' fieldName='height' label='Data Table Height' placeholder='Height(px)' type='number' min='0' max='500' />}
2511
+ {state.table.limitHeight && <TextField value={table.height} updateField={updateField} section='table' fieldName='height' label='Data Table Height' placeholder='Height(px)' type='number' min='0' max='500' />}
2433
2512
  <label className='checkbox'>
2434
2513
  <input
2435
2514
  type='checkbox'
2436
- checked={state.general.expandDataTable || false}
2515
+ checked={state.table.expanded || false}
2437
2516
  onChange={event => {
2438
2517
  handleEditorChanges('expandDataTable', event.target.checked)
2439
2518
  }}
2440
2519
  />
2441
2520
  <span className='edit-label'>Map loads with data table expanded</span>
2442
2521
  </label>
2443
- <label className='checkbox'>
2444
- <input
2445
- type='checkbox'
2446
- checked={state.table.showDownloadUrl}
2447
- onChange={event => {
2448
- handleEditorChanges('toggleDataUrl', event.target.checked)
2449
- }}
2450
- />
2451
- <span className='edit-label'>Enable Link to Dataset</span>
2452
- </label>
2522
+ {isDashboard && (
2523
+ <label className='checkbox'>
2524
+ <input
2525
+ type='checkbox'
2526
+ checked={state.table.showDataTableLink}
2527
+ onChange={event => {
2528
+ handleEditorChanges('toggleDataTableLink', event.target.checked)
2529
+ }}
2530
+ />
2531
+ <span className='edit-label'>Show Data Table Name & Link</span>
2532
+ </label>
2533
+ )}
2534
+ {isLoadedFromUrl && (
2535
+ <label className='checkbox'>
2536
+ <input
2537
+ type='checkbox'
2538
+ checked={state.table.showDownloadUrl}
2539
+ onChange={event => {
2540
+ handleEditorChanges('toggleDataUrl', event.target.checked)
2541
+ }}
2542
+ />
2543
+ <span className='edit-label'>Show URL to Automatically Updated Data</span>
2544
+ </label>
2545
+ )}
2453
2546
  <label className='checkbox'>
2454
2547
  <input
2455
2548
  type='checkbox'
@@ -2458,7 +2551,7 @@ const EditorPanel = props => {
2458
2551
  handleEditorChanges('toggleDownloadButton', event.target.checked)
2459
2552
  }}
2460
2553
  />
2461
- <span className='edit-label'>Enable Download CSV Button</span>
2554
+ <span className='edit-label'>Show Download CSV Link</span>
2462
2555
  </label>
2463
2556
  {/* <label className='checkbox'>
2464
2557
  <input
@@ -2722,6 +2815,44 @@ const EditorPanel = props => {
2722
2815
  ))}
2723
2816
  </AccordionItemPanel>
2724
2817
  </AccordionItem>
2818
+ {/* <AccordionItem>
2819
+ <AccordionItemHeading>
2820
+ <AccordionItemButton>Custom Map Layers</AccordionItemButton>
2821
+ </AccordionItemHeading>
2822
+ <AccordionItemPanel>
2823
+ {state.map.layers.length === 0 && <p>There are currently no layers.</p>}
2824
+
2825
+ {state.map.layers.map((layer, index) => {
2826
+ return (
2827
+ <>
2828
+ <Accordion allowZeroExpanded>
2829
+ <AccordionItem className='series-item map-layers-list'>
2830
+ <AccordionItemHeading className='series-item__title map-layers-list--title'>
2831
+ <AccordionItemButton>{`Layer ${index + 1}: ${layer.name}`}</AccordionItemButton>
2832
+ </AccordionItemHeading>
2833
+ <AccordionItemPanel>
2834
+ <div className='map-layers-panel'>
2835
+ <label htmlFor='layerName'>Layer Name:</label>
2836
+ <input type='text' name='layerName' value={layer.name} onChange={e => handleMapLayerName(e, index)} />
2837
+ <label htmlFor='layerFilename'>File:</label>
2838
+ <input type='text' name='layerFilename' value={layer.url} onChange={e => handleMapLayerUrl(e, index)} />
2839
+ <label htmlFor='layerNamespace'>TOPOJSON Namespace:</label>
2840
+ <input type='text' name='layerNamespace' value={layer.namespace} onChange={e => handleMapLayerNamespace(e, index)} />
2841
+ <label htmlFor='layerTooltip'>Tooltip:</label>
2842
+ <textarea name='layerTooltip' value={layer.tooltip} onChange={e => handleMapLayerTooltip(e, index)}></textarea>
2843
+ <button onClick={e => handleRemoveLayer(e, index)}>Remove Layer</button>
2844
+ </div>
2845
+ </AccordionItemPanel>
2846
+ </AccordionItem>
2847
+ </Accordion>
2848
+ </>
2849
+ )
2850
+ })}
2851
+ <button className={'btn full-width'} onClick={handleAddLayer}>
2852
+ Add Map Layer
2853
+ </button>
2854
+ </AccordionItemPanel>
2855
+ </AccordionItem> */}
2725
2856
  </Accordion>
2726
2857
  </form>
2727
2858
  <AdvancedEditor loadConfig={loadConfig} state={state} convertStateToConfig={convertStateToConfig} />