@cdc/map 4.25.3 → 4.25.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/.idea/map.iml +12 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/vcs.xml +6 -0
  4. package/dist/cdcmap.js +31254 -32242
  5. package/examples/hex-colors.json +3 -3
  6. package/examples/m2.json +32904 -0
  7. package/examples/private/test.json +470 -1457
  8. package/examples/private/{mmr.json → wastewatermap.json} +86 -115
  9. package/index.html +36 -63
  10. package/package.json +7 -19
  11. package/src/CdcMap.tsx +56 -1552
  12. package/src/CdcMapComponent.tsx +608 -0
  13. package/src/_stories/CdcMap.Legend.Gradient.stories.tsx +10 -0
  14. package/src/_stories/CdcMap.Legend.stories.tsx +67 -0
  15. package/src/_stories/CdcMap.Table.stories.tsx +19 -0
  16. package/src/_stories/CdcMap.stories.tsx +12 -1
  17. package/src/_stories/UsaMap.NoData.stories.tsx +4 -4
  18. package/src/_stories/_mock/default-patterns.json +8 -5
  19. package/src/_stories/_mock/legend-bins.json +428 -0
  20. package/{examples/private/default-patterns.json → src/_stories/_mock/legends/legend-tests.json} +36 -131
  21. package/src/cdcMapComponent.styles.css +9 -0
  22. package/src/components/Annotation/Annotation.Draggable.tsx +27 -26
  23. package/src/components/Annotation/AnnotationDropdown.tsx +5 -6
  24. package/src/components/BubbleList.tsx +135 -49
  25. package/src/components/CityList.tsx +89 -87
  26. package/src/components/DataTable.tsx +8 -8
  27. package/src/components/EditorPanel/components/EditorPanel.tsx +823 -885
  28. package/src/components/EditorPanel/components/Error.tsx +9 -2
  29. package/src/components/EditorPanel/components/HexShapeSettings.tsx +127 -141
  30. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +55 -86
  31. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +89 -75
  32. package/src/components/EditorPanel/components/editorPanel.styles.css +95 -0
  33. package/src/components/Geo.tsx +9 -1
  34. package/src/components/GoogleMap/components/GoogleMap.tsx +1 -1
  35. package/src/components/Legend/components/Legend.tsx +92 -87
  36. package/src/components/Legend/components/LegendGroup/Legend.Group.tsx +128 -0
  37. package/src/components/Legend/components/LegendGroup/legend.group.css +27 -0
  38. package/src/components/Legend/components/LegendItem.Hex.tsx +4 -1
  39. package/src/components/Legend/components/index.scss +74 -17
  40. package/src/components/Modal.tsx +17 -7
  41. package/src/components/NavigationMenu.tsx +11 -9
  42. package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +12 -8
  43. package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +4 -4
  44. package/src/components/UsaMap/components/TerritoriesSection.tsx +33 -10
  45. package/src/components/UsaMap/components/Territory/Territory.Hexagon.tsx +12 -10
  46. package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +12 -14
  47. package/src/components/UsaMap/components/Territory/TerritoryShape.ts +2 -1
  48. package/src/components/UsaMap/components/UsaMap.County.tsx +138 -96
  49. package/src/components/UsaMap/components/UsaMap.Region.styles.css +72 -0
  50. package/src/components/UsaMap/components/UsaMap.Region.tsx +56 -103
  51. package/src/components/UsaMap/components/UsaMap.SingleState.styles.css +10 -0
  52. package/src/components/UsaMap/components/UsaMap.SingleState.tsx +65 -74
  53. package/src/components/UsaMap/components/UsaMap.State.tsx +112 -91
  54. package/src/components/UsaMap/helpers/map.ts +1 -1
  55. package/src/components/UsaMap/helpers/shapes.ts +20 -7
  56. package/src/components/WorldMap/WorldMap.tsx +64 -118
  57. package/src/components/WorldMap/worldMap.styles.css +28 -0
  58. package/src/components/ZoomControls.tsx +15 -13
  59. package/src/components/zoomControls.styles.css +53 -0
  60. package/src/context.ts +17 -9
  61. package/src/data/initial-state.js +5 -2
  62. package/src/helpers/addUIDs.ts +150 -0
  63. package/src/helpers/applyColorToLegend.ts +39 -64
  64. package/src/helpers/applyLegendToRow.ts +51 -0
  65. package/src/helpers/colorDistributions.ts +12 -0
  66. package/src/helpers/constants.ts +44 -0
  67. package/src/helpers/displayGeoName.ts +9 -2
  68. package/src/helpers/formatLegendLocation.ts +3 -2
  69. package/src/helpers/generateColorsArray.ts +2 -1
  70. package/src/helpers/generateRuntimeData.ts +78 -0
  71. package/src/helpers/generateRuntimeFilters.ts +63 -0
  72. package/src/helpers/generateRuntimeLegend.ts +566 -0
  73. package/src/helpers/generateRuntimeLegendHash.ts +16 -15
  74. package/src/helpers/getColumnNames.ts +19 -0
  75. package/src/helpers/getMapContainerClasses.ts +23 -0
  76. package/src/helpers/getStatePicked.ts +8 -0
  77. package/src/helpers/handleMapTabbing.ts +31 -0
  78. package/src/helpers/hashObj.ts +1 -1
  79. package/src/helpers/index.ts +22 -0
  80. package/src/helpers/navigationHandler.ts +3 -3
  81. package/src/helpers/resetLegendToggles.ts +13 -0
  82. package/src/helpers/setBinNumbers.ts +5 -0
  83. package/src/helpers/sortSpecialClassesLast.ts +7 -0
  84. package/src/helpers/tests/getColumnNames.test.ts +52 -0
  85. package/src/helpers/titleCase.ts +1 -1
  86. package/src/helpers/toggleLegendActive.ts +25 -0
  87. package/src/hooks/useApplyTooltipsToGeo.tsx +51 -0
  88. package/src/hooks/useColumnsRequiredChecker.ts +51 -0
  89. package/src/hooks/useGeoClickHandler.ts +45 -0
  90. package/src/hooks/useLegendSeparators.ts +26 -0
  91. package/src/hooks/useMapLayers.tsx +34 -60
  92. package/src/hooks/useModal.ts +22 -0
  93. package/src/hooks/useResizeObserver.ts +4 -5
  94. package/src/hooks/useStateZoom.tsx +52 -75
  95. package/src/hooks/useTooltip.ts +2 -3
  96. package/src/index.jsx +3 -9
  97. package/src/scss/editor-panel.scss +3 -99
  98. package/src/scss/main.scss +1 -19
  99. package/src/scss/map.scss +15 -220
  100. package/src/store/map.actions.ts +46 -0
  101. package/src/store/map.reducer.ts +96 -0
  102. package/src/types/Annotations.ts +24 -0
  103. package/src/types/MapConfig.ts +23 -3
  104. package/src/types/MapContext.ts +36 -35
  105. package/src/types/Modal.ts +1 -0
  106. package/src/types/RuntimeData.ts +3 -0
  107. package/examples/private/DEV-9644.json +0 -184
  108. package/examples/private/DEV-9989.json +0 -229
  109. package/examples/private/ardi.json +0 -180
  110. package/examples/private/colors 2.json +0 -416
  111. package/examples/private/colors.json +0 -416
  112. package/examples/private/colors.json.zip +0 -0
  113. package/examples/private/customColors.json +0 -45348
  114. package/examples/test.json +0 -183
  115. package/src/helpers/closeModal.ts +0 -9
  116. package/src/scss/btn.scss +0 -69
  117. package/src/scss/filters.scss +0 -27
  118. package/src/scss/variables.scss +0 -1
  119. /package/src/hooks/{useActiveElement.js → useActiveElement.ts} +0 -0
@@ -1,9 +1,16 @@
1
- const Error = ({ state }) => {
1
+ import { useContext } from 'react'
2
+ import ConfigContext from '../../../context'
3
+
4
+ const Error = () => {
5
+
6
+ const { config } = useContext(ConfigContext)
7
+ const errorMessage = config.runtime.editorErrorMessage
8
+
2
9
  return (
3
10
  <section className='waiting'>
4
11
  <section className='waiting-container'>
5
12
  <h3>Error With Configuration</h3>
6
- <p>{state.runtime.editorErrorMessage}</p>
13
+ <p>{errorMessage}</p>
7
14
  </section>
8
15
  </section>
9
16
  )
@@ -1,8 +1,13 @@
1
- import React from 'react'
2
- import { Accordion, AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
3
- import parse from 'html-react-parser'
4
- import { AiOutlineArrowUp, AiOutlineArrowDown, AiOutlineArrowRight } from 'react-icons/ai'
5
- import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
1
+ import React, { useContext } from 'react'
2
+ import {
3
+ Accordion,
4
+ AccordionItem,
5
+ AccordionItemHeading,
6
+ AccordionItemPanel,
7
+ AccordionItemButton
8
+ } from 'react-accessible-accordion'
9
+ import ConfigContext from '../../../context'
10
+ import _ from 'lodash'
6
11
 
7
12
  const shapeOptions = ['Arrow Up', 'Arrow Down', 'Arrow Right', 'Arrow Left', 'None']
8
13
 
@@ -13,52 +18,14 @@ export const DATA_OPERATOR_LESSEQUAL = '<='
13
18
  export const DATA_OPERATOR_GREATEREQUAL = '>='
14
19
  export const DATA_OPERATOR_EQUAL = '='
15
20
  export const DATA_OPERATOR_NOTEQUAL = '≠'
16
-
17
- export const DATA_OPERATORS = [DATA_OPERATOR_LESS, DATA_OPERATOR_GREATER, DATA_OPERATOR_LESSEQUAL, DATA_OPERATOR_GREATEREQUAL, DATA_OPERATOR_EQUAL, DATA_OPERATOR_NOTEQUAL]
18
-
19
- const HexSettingDisplayShapesOnHex = props => {
20
- const { state, setState } = props
21
- if (!state.general.displayAsHex) return <></>
22
- return (
23
- <label className='checkbox mt-4'>
24
- <input
25
- type='checkbox'
26
- checked={state.hexMap.type === 'shapes'}
27
- onChange={event => {
28
- setState({
29
- ...state,
30
- hexMap: {
31
- ...state.hexMap,
32
- type: event.target.checked ? 'shapes' : 'standard'
33
- }
34
- })
35
- }}
36
- />
37
- <span className='edit-label'>Display Shapes on Hex Map</span>
38
- </label>
39
- )
40
- }
41
-
42
- const HexSettingDisplayAsHexMap = props => {
43
- const { state, handleEditorChanges } = props
44
-
45
- return (
46
- state.general.geoType === 'us' &&
47
- state.general.type !== ' navigation' &&
48
- state.general.type !== 'bubble' && (
49
- <label className='checkbox mt-4'>
50
- <input
51
- type='checkbox'
52
- checked={state.general.displayAsHex}
53
- onChange={event => {
54
- handleEditorChanges('displayAsHex', event.target.checked)
55
- }}
56
- />
57
- <span className='edit-label'>Display As Hex Map</span>
58
- </label>
59
- )
60
- )
61
- }
21
+ export const DATA_OPERATORS = [
22
+ DATA_OPERATOR_LESS,
23
+ DATA_OPERATOR_GREATER,
24
+ DATA_OPERATOR_LESSEQUAL,
25
+ DATA_OPERATOR_GREATEREQUAL,
26
+ DATA_OPERATOR_EQUAL,
27
+ DATA_OPERATOR_NOTEQUAL
28
+ ]
62
29
 
63
30
  /**
64
31
  * Notice: each shape Col has a legend title and description should the title/desc need to be different for different shapes.
@@ -66,14 +33,15 @@ const HexSettingDisplayAsHexMap = props => {
66
33
  * @returns
67
34
  */
68
35
  const HexSettingShapeColumns = props => {
69
- const { state, setState, columnsOptions } = props
36
+ const { columnsOptions } = props
37
+ const { config, setConfig } = useContext(ConfigContext)
70
38
 
71
39
  const handleItemUpdate = (key, value, shapeGroupIndex, itemIndex) => {
72
- setState({
73
- ...state,
40
+ setConfig({
41
+ ...config,
74
42
  hexMap: {
75
- ...state.hexMap,
76
- shapeGroups: state.hexMap.shapeGroups.map((group, groupIndex) => {
43
+ ...config.hexMap,
44
+ shapeGroups: config.hexMap.shapeGroups.map((group, groupIndex) => {
77
45
  if (groupIndex === shapeGroupIndex) {
78
46
  return {
79
47
  ...group,
@@ -97,11 +65,11 @@ const HexSettingShapeColumns = props => {
97
65
  }
98
66
 
99
67
  const handleRemoveShapeCondition = (shapeGroupIndex, itemIndex) => {
100
- setState({
101
- ...state,
68
+ setConfig({
69
+ ...config,
102
70
  hexMap: {
103
- ...state.hexMap,
104
- shapeGroups: state.hexMap.shapeGroups.map((group, groupIndex) => {
71
+ ...config.hexMap,
72
+ shapeGroups: config.hexMap.shapeGroups.map((group, groupIndex) => {
105
73
  if (groupIndex === shapeGroupIndex) {
106
74
  return {
107
75
  ...group,
@@ -116,15 +84,15 @@ const HexSettingShapeColumns = props => {
116
84
  }
117
85
 
118
86
  return (
119
- state.general.displayAsHex &&
120
- state.hexMap.type === 'shapes' && (
87
+ config.general.displayAsHex &&
88
+ config.hexMap.type === 'shapes' && (
121
89
  <>
122
90
  <fieldset className='edit-block'>
123
- {state.hexMap.shapeGroups && (
91
+ {config.hexMap.shapeGroups && (
124
92
  <>
125
93
  <Accordion allowZeroExpanded>
126
94
  <ul style={{ listStyle: 'none' }}>
127
- {state.hexMap.shapeGroups?.map((shapeGroup, shapeGroupIndex) => {
95
+ {config.hexMap.shapeGroups?.map((shapeGroup, shapeGroupIndex) => {
128
96
  return (
129
97
  <AccordionItem>
130
98
  <AccordionItemHeading>
@@ -136,24 +104,11 @@ const HexSettingShapeColumns = props => {
136
104
  <input
137
105
  type='text'
138
106
  value={shapeGroup.legendTitle || ''}
139
- onChange={e =>
140
- setState(prevState => ({
141
- ...prevState,
142
- hexMap: {
143
- ...prevState.hexMap,
144
- shapeGroups: prevState.hexMap.shapeGroups.map((group, groupIndex) => {
145
- if (groupIndex === shapeGroupIndex) {
146
- return {
147
- ...group,
148
- legendTitle: e.target.value
149
- }
150
- } else {
151
- return group
152
- }
153
- })
154
- }
155
- }))
156
- }
107
+ onChange={e => {
108
+ const newConfig = _.cloneDeep(config)
109
+ newConfig.hexMap.shapeGroups[shapeGroupIndex].legendTitle = e.target.value
110
+ setConfig(newConfig)
111
+ }}
157
112
  />
158
113
  </label>
159
114
 
@@ -162,24 +117,11 @@ const HexSettingShapeColumns = props => {
162
117
  <input
163
118
  type='text'
164
119
  value={shapeGroup.legendDescription || ''}
165
- onChange={e =>
166
- setState(prevState => ({
167
- ...prevState,
168
- hexMap: {
169
- ...prevState.hexMap,
170
- shapeGroups: prevState.hexMap.shapeGroups.map((group, groupIndex) => {
171
- if (groupIndex === shapeGroupIndex) {
172
- return {
173
- ...group,
174
- legendDescription: e.target.value
175
- }
176
- } else {
177
- return group
178
- }
179
- })
180
- }
181
- }))
182
- }
120
+ onChange={e => {
121
+ const newConfig = _.clone(config)
122
+ newConfig.hexMap.shapeGroups[shapeGroupIndex].legendDescription = e.target.value
123
+ setConfig(newConfig)
124
+ }}
183
125
  />
184
126
  </label>
185
127
 
@@ -195,7 +137,11 @@ const HexSettingShapeColumns = props => {
195
137
  <label>
196
138
  <span className='edit-label column-heading'>Shape Column</span>
197
139
  <select
198
- value={state.hexMap.shapeGroups[shapeGroupIndex].items[itemIndex].shape ? state.hexMap.shapeGroups[shapeGroupIndex].items[itemIndex].shape : 'select'}
140
+ value={
141
+ config.hexMap.shapeGroups[shapeGroupIndex].items[itemIndex].shape
142
+ ? config.hexMap.shapeGroups[shapeGroupIndex].items[itemIndex].shape
143
+ : 'select'
144
+ }
199
145
  onChange={e => {
200
146
  handleItemUpdate('shape', e.target.value, shapeGroupIndex, itemIndex)
201
147
  }}
@@ -212,12 +158,32 @@ const HexSettingShapeColumns = props => {
212
158
  </label>
213
159
  <div className='cove-accordion__panel-row cove-accordion__small-inputs'>
214
160
  <div className='cove-accordion__panel-col cove-input'>
215
- <select value={state.hexMap.shapeGroups[shapeGroupIndex].key === '' ? 'Select' : state.hexMap.shapeGroups[shapeGroupIndex].key} className='cove-input' onChange={e => handleItemUpdate('key', e.target.value, shapeGroupIndex, itemIndex)}>
161
+ <select
162
+ value={
163
+ config.hexMap.shapeGroups[shapeGroupIndex].key === ''
164
+ ? 'Select'
165
+ : config.hexMap.shapeGroups[shapeGroupIndex].key
166
+ }
167
+ className='cove-input'
168
+ onChange={e =>
169
+ handleItemUpdate('key', e.target.value, shapeGroupIndex, itemIndex)
170
+ }
171
+ >
216
172
  {columnsOptions}
217
173
  </select>
218
174
  </div>
219
175
  <div className='cove-accordion__panel-col cove-input'>
220
- <select value={state.hexMap.shapeGroups[shapeGroupIndex].items[itemIndex].operator || '-SELECT-'} initial='Select' className='cove-input' onChange={e => handleItemUpdate('operator', e.target.value, shapeGroupIndex, itemIndex)}>
176
+ <select
177
+ value={
178
+ config.hexMap.shapeGroups[shapeGroupIndex].items[itemIndex].operator ||
179
+ '-SELECT-'
180
+ }
181
+ initial='Select'
182
+ className='cove-input'
183
+ onChange={e =>
184
+ handleItemUpdate('operator', e.target.value, shapeGroupIndex, itemIndex)
185
+ }
186
+ >
221
187
  {[DATA_OPERATOR_EQUAL].map(option => {
222
188
  return <option value={option}>{option}</option>
223
189
  })}
@@ -239,11 +205,30 @@ const HexSettingShapeColumns = props => {
239
205
  </select>
240
206
  </div>
241
207
  <div className='cove-accordion__panel-col cove-input'>
242
- <input type='text' value={state.hexMap.shapeGroups[shapeGroupIndex].items[itemIndex].value || ''} className='cove-input' style={{ height: '100%' }} onChange={e => handleItemUpdate('value', e.target.value, shapeGroupIndex, itemIndex)} />
208
+ <input
209
+ type='text'
210
+ value={
211
+ config.hexMap.shapeGroups[shapeGroupIndex].items[itemIndex].value || ''
212
+ }
213
+ className='cove-input'
214
+ style={{ height: '100%' }}
215
+ onChange={e =>
216
+ handleItemUpdate('value', e.target.value, shapeGroupIndex, itemIndex)
217
+ }
218
+ />
243
219
  </div>
244
220
  </div>
245
221
  </div>
246
- <button className='cove-button cove-button--warn' style={{ background: 'none', border: '1px solid red', color: 'red', marginTop: '15px' }} onClick={e => handleRemoveShapeCondition(shapeGroupIndex, itemIndex)}>
222
+ <button
223
+ className='cove-button cove-button--warn'
224
+ style={{
225
+ background: 'none',
226
+ border: '1px solid red',
227
+ color: 'red',
228
+ marginTop: '15px'
229
+ }}
230
+ onClick={e => handleRemoveShapeCondition(shapeGroupIndex, itemIndex)}
231
+ >
247
232
  Remove Shape Conditional
248
233
  </button>
249
234
  </>
@@ -257,33 +242,33 @@ const HexSettingShapeColumns = props => {
257
242
  <button
258
243
  className='cove-button'
259
244
  style={{ marginTop: '15px' }}
260
- onClick={() =>
261
- setState({
262
- ...state,
263
- hexMap: {
264
- ...state.hexMap,
265
- shapeGroups: state.hexMap.shapeGroups.map((group, index) => {
266
- if (index === shapeGroupIndex) {
267
- return {
268
- ...group,
269
- items: [
270
- ...group.items,
271
- {
272
- key: '',
273
- shape: 'Arrow Up',
274
- column: '',
275
- operator: '=',
276
- value: ''
277
- }
278
- ]
279
- }
280
- } else {
281
- return group
245
+ onClick={() => {
246
+ const newConfig = _.cloneDeep(config)
247
+ _.set(
248
+ newConfig,
249
+ 'hexMap.shapeGroups',
250
+ _.map(newConfig.hexMap.shapeGroups, (group, index) => {
251
+ if (index === shapeGroupIndex) {
252
+ return {
253
+ ...group,
254
+ items: [
255
+ ...group.items,
256
+ {
257
+ key: '',
258
+ shape: 'Arrow Up',
259
+ column: '',
260
+ operator: '=',
261
+ value: ''
262
+ }
263
+ ]
282
264
  }
283
- })
284
- }
285
- })
286
- }
265
+ }
266
+ return group
267
+ })
268
+ )
269
+
270
+ setConfig(newConfig)
271
+ }}
287
272
  >
288
273
  Add Shape Condition
289
274
  </button>
@@ -292,12 +277,15 @@ const HexSettingShapeColumns = props => {
292
277
  className='cove-button cove-button--warn'
293
278
  style={{ background: 'none', border: '1px solid red', color: 'red', marginTop: '15px' }}
294
279
  onClick={(e, itemIndex) => {
295
- let newGroups = [...state.hexMap.shapeGroups.slice(0, shapeGroupIndex), ...state.hexMap.shapeGroups.slice(shapeGroupIndex + 1)]
280
+ let newGroups = [
281
+ ...config.hexMap.shapeGroups.slice(0, shapeGroupIndex),
282
+ ...config.hexMap.shapeGroups.slice(shapeGroupIndex + 1)
283
+ ]
296
284
 
297
- setState({
298
- ...state,
285
+ setConfig({
286
+ ...config,
299
287
  hexMap: {
300
- ...state.hexMap,
288
+ ...config.hexMap,
301
289
  shapeGroups: newGroups
302
290
  }
303
291
  })
@@ -320,7 +308,7 @@ const HexSettingShapeColumns = props => {
320
308
  className='cove-button'
321
309
  style={{ marginTop: '15px' }}
322
310
  onClick={index => {
323
- let copy = state.hexMap.shapeGroups
311
+ let copy = config.hexMap.shapeGroups
324
312
  copy.push({
325
313
  legendTitle: '',
326
314
  legendDescription: '',
@@ -328,10 +316,10 @@ const HexSettingShapeColumns = props => {
328
316
  })
329
317
  copy.legendTitle = ''
330
318
  copy.legendDescription = ''
331
- setState({
332
- ...state,
319
+ setConfig({
320
+ ...config,
333
321
  hexMap: {
334
- ...state.hexMap,
322
+ ...config.hexMap,
335
323
  shapeGroups: copy
336
324
  }
337
325
  })
@@ -347,8 +335,6 @@ const HexSettingShapeColumns = props => {
347
335
 
348
336
  const HexSetting = () => props.children
349
337
 
350
- HexSetting.DisplayShapesOnHex = HexSettingDisplayShapesOnHex
351
- HexSetting.DisplayAsHexMap = HexSettingDisplayAsHexMap
352
338
  HexSetting.ShapeColumns = HexSettingShapeColumns
353
339
 
354
340
  export default HexSetting
@@ -6,17 +6,13 @@ import Accordion from '@cdc/core/components/ui/Accordion'
6
6
  import Button from '@cdc/core/components/elements/Button'
7
7
  import { MapContext } from '../../../../types/MapContext'
8
8
  import ConfigContext from '../../../../context'
9
-
9
+ import { Select } from '@cdc/core/components/EditorPanel/Inputs'
10
+ import { setConfig } from 'dompurify'
10
11
  // types
11
12
  // styles
12
13
 
13
14
  const PanelAnnotate: React.FC = props => {
14
- const {
15
- state: config,
16
- setState: updateConfig,
17
- dimensions,
18
- isDraggingAnnotation
19
- } = useContext<MapContext>(ConfigContext)
15
+ const { config, setConfig, dimensions, isDraggingAnnotation } = useContext<MapContext>(ConfigContext)
20
16
  const getColumns = (filter = true) => {
21
17
  const columns = {}
22
18
  config.data.forEach(row => {
@@ -42,7 +38,7 @@ const PanelAnnotate: React.FC = props => {
42
38
  annotations[index][property] = value
43
39
  annotations[index].savedDimensions = [dimensions[0] * 0.73, dimensions[1]]
44
40
 
45
- updateConfig({
41
+ setConfig({
46
42
  ...config,
47
43
  annotations
48
44
  })
@@ -94,7 +90,7 @@ const PanelAnnotate: React.FC = props => {
94
90
 
95
91
  const annotations = Array.isArray(config.annotations) ? config.annotations : []
96
92
 
97
- updateConfig({
93
+ setConfig({
98
94
  ...config,
99
95
  annotations: [...annotations, newAnnotation]
100
96
  })
@@ -102,7 +98,7 @@ const PanelAnnotate: React.FC = props => {
102
98
 
103
99
  const handleRemoveAnnotation = (annotationIndex: number) => {
104
100
  const updated = config.annotations.filter((_, index) => index !== annotationIndex)
105
- updateConfig({
101
+ setConfig({
106
102
  ...config,
107
103
  annotations: updated
108
104
  })
@@ -117,7 +113,7 @@ const PanelAnnotate: React.FC = props => {
117
113
  type='checkbox'
118
114
  checked={config?.general?.showAnnotationDropdown}
119
115
  onClick={e => {
120
- updateConfig({
116
+ setConfig({
121
117
  ...config,
122
118
  general: {
123
119
  ...config.general,
@@ -135,7 +131,7 @@ const PanelAnnotate: React.FC = props => {
135
131
  style={{ marginBottom: '10px' }}
136
132
  value={config?.general?.annotationDropdownText}
137
133
  onChange={e => {
138
- updateConfig({
134
+ setConfig({
139
135
  ...config,
140
136
  general: {
141
137
  ...config.general,
@@ -200,7 +196,7 @@ const PanelAnnotate: React.FC = props => {
200
196
  onChange={e => {
201
197
  const updatedAnnotations = [...config?.annotations]
202
198
  updatedAnnotations[index].opacity = e.target.value
203
- updateConfig({
199
+ setConfig({
204
200
  ...config,
205
201
  annotations: updatedAnnotations
206
202
  })
@@ -217,7 +213,7 @@ const PanelAnnotate: React.FC = props => {
217
213
  onClick={e => {
218
214
  const updatedAnnotations = [...config?.annotations]
219
215
  updatedAnnotations[index].edit.subject = e.target.checked
220
- updateConfig({
216
+ setConfig({
221
217
  ...config,
222
218
  annotations: updatedAnnotations
223
219
  })
@@ -232,7 +228,7 @@ const PanelAnnotate: React.FC = props => {
232
228
  onClick={e => {
233
229
  const updatedAnnotations = [...config?.annotations]
234
230
  updatedAnnotations[index].edit.label = e.target.checked
235
- updateConfig({
231
+ setConfig({
236
232
  ...config,
237
233
  annotations: updatedAnnotations
238
234
  })
@@ -240,85 +236,58 @@ const PanelAnnotate: React.FC = props => {
240
236
  />
241
237
  </label>
242
238
 
243
- <label>
244
- Connection Type:
245
- <select
246
- onChange={e => {
247
- const updatedAnnotations = [...config?.annotations]
248
- updatedAnnotations[index].connectionType = e.target.value
249
- updateConfig({
250
- ...config,
251
- annotations: updatedAnnotations
252
- })
253
- }}
254
- >
255
- {['curve', 'line', 'elbow', 'none'].map((side, index) => (
256
- <option key={side} value={side}>
257
- {side}
258
- </option>
259
- ))}
260
- </select>
261
- </label>
239
+ <Select
240
+ label='Connection Type'
241
+ value={config?.annotations[index]?.connectionType || ''}
242
+ options={['curve', 'line', 'elbow', 'none'].map(side => ({
243
+ value: side,
244
+ label: side
245
+ }))}
246
+ onChange={event => {
247
+ const updatedAnnotations = [...config?.annotations]
248
+ updatedAnnotations[index].connectionType = event.target.value
249
+ setConfig({
250
+ ...config,
251
+ annotations: updatedAnnotations
252
+ })
253
+ }}
254
+ />
262
255
 
263
256
  {annotation.connectionType === 'curve' && (
264
- <label>
265
- Line Type:
266
- <select
267
- onChange={e => {
268
- const updatedAnnotations = [...config?.annotations]
269
- updatedAnnotations[index].lineType = e.target.value
270
- updateConfig({
271
- ...config,
272
- annotations: updatedAnnotations
273
- })
274
- }}
275
- >
276
- {Object.entries(approvedCurveTypes).map(([value, key]) => (
277
- <option key={key} value={key}>
278
- {value}
279
- </option>
280
- ))}
281
- </select>
282
- </label>
283
- )}
284
-
285
- {/* <label>
286
- Connection Location:
287
- <select
288
- onChange={e => {
257
+ <Select
258
+ label='Line Type'
259
+ value={config?.annotations[index]?.lineType || ''}
260
+ options={Object.entries(approvedCurveTypes).map(([value, key]) => ({
261
+ value: key,
262
+ label: value
263
+ }))}
264
+ onChange={event => {
289
265
  const updatedAnnotations = [...config?.annotations]
290
- updatedAnnotations[index].connectionLocation = e.target.value
291
- updateConfig({
266
+ updatedAnnotations[index].lineType = event.target.value
267
+ setConfig({
292
268
  ...config,
293
269
  annotations: updatedAnnotations
294
270
  })
295
271
  }}
296
- >
297
- {['auto', 'left', 'top', 'bottom', 'right'].map((side, index) => (
298
- <option key={side} value={side}>
299
- {side}
300
- </option>
301
- ))}
302
- </select>
303
- </label> */}
272
+ />
273
+ )}
304
274
 
305
- <label>
306
- Marker
307
- <select
308
- onChange={e => {
309
- const updatedAnnotations = [...config?.annotations]
310
- updatedAnnotations[index].marker = e.target.value
311
- updateConfig({
312
- ...config,
313
- annotations: updatedAnnotations
314
- })
315
- }}
316
- >
317
- {['circle', 'arrow'].map((column, columnIndex) => {
318
- return <option>{column}</option>
319
- })}
320
- </select>
321
- </label>
275
+ <Select
276
+ label='Marker'
277
+ value={config?.annotations[index]?.marker || ''}
278
+ options={['circle', 'arrow'].map(option => ({
279
+ value: option,
280
+ label: option
281
+ }))}
282
+ onChange={event => {
283
+ const updatedAnnotations = [...config?.annotations]
284
+ updatedAnnotations[index].marker = event.target.value
285
+ setConfig({
286
+ ...config,
287
+ annotations: updatedAnnotations
288
+ })
289
+ }}
290
+ />
322
291
 
323
292
  <Button className='btn btn-danger' onClick={() => handleRemoveAnnotation(index)}>
324
293
  Delete Annotation