@cdc/editor 4.26.1 → 4.26.3

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,373 @@
1
+ [
2
+ {
3
+ "Date": "01/01/2022",
4
+ "Data 1": "2",
5
+ "Data 2": "3",
6
+ "Data 3": "2",
7
+ "Data 4": "2"
8
+ },
9
+ {
10
+ "Date": "01/08/2022",
11
+ "Data 1": "3",
12
+ "Data 2": "4",
13
+ "Data 3": "3",
14
+ "Data 4": "2"
15
+ },
16
+ {
17
+ "Date": "01/15/2022",
18
+ "Data 1": "4",
19
+ "Data 2": "5",
20
+ "Data 3": "4",
21
+ "Data 4": "3"
22
+ },
23
+ {
24
+ "Date": "01/22/2022",
25
+ "Data 1": "6",
26
+ "Data 2": "7",
27
+ "Data 3": "6",
28
+ "Data 4": "5"
29
+ },
30
+ {
31
+ "Date": "01/29/2022",
32
+ "Data 1": "8",
33
+ "Data 2": "10",
34
+ "Data 3": "8",
35
+ "Data 4": "7"
36
+ },
37
+ {
38
+ "Date": "02/05/2022",
39
+ "Data 1": "15",
40
+ "Data 2": "18",
41
+ "Data 3": "14",
42
+ "Data 4": "12"
43
+ },
44
+ {
45
+ "Date": "02/12/2022",
46
+ "Data 1": "25",
47
+ "Data 2": "28",
48
+ "Data 3": "22",
49
+ "Data 4": "20"
50
+ },
51
+ {
52
+ "Date": "02/19/2022",
53
+ "Data 1": "45",
54
+ "Data 2": "40",
55
+ "Data 3": "35",
56
+ "Data 4": "32"
57
+ },
58
+ {
59
+ "Date": "02/26/2022",
60
+ "Data 1": "80",
61
+ "Data 2": "55",
62
+ "Data 3": "60",
63
+ "Data 4": "58"
64
+ },
65
+ {
66
+ "Date": "03/05/2022",
67
+ "Data 1": "150",
68
+ "Data 2": "70",
69
+ "Data 3": "85",
70
+ "Data 4": "95"
71
+ },
72
+ {
73
+ "Date": "03/12/2022",
74
+ "Data 1": "230",
75
+ "Data 2": "85",
76
+ "Data 3": "110",
77
+ "Data 4": "120"
78
+ },
79
+ {
80
+ "Date": "03/19/2022",
81
+ "Data 1": "300",
82
+ "Data 2": "95",
83
+ "Data 3": "130",
84
+ "Data 4": "145"
85
+ },
86
+ {
87
+ "Date": "03/26/2022",
88
+ "Data 1": "260",
89
+ "Data 2": "105",
90
+ "Data 3": "145",
91
+ "Data 4": "160"
92
+ },
93
+ {
94
+ "Date": "04/02/2022",
95
+ "Data 1": "230",
96
+ "Data 2": "120",
97
+ "Data 3": "165",
98
+ "Data 4": "175"
99
+ },
100
+ {
101
+ "Date": "04/09/2022",
102
+ "Data 1": "210",
103
+ "Data 2": "135",
104
+ "Data 3": "185",
105
+ "Data 4": "190"
106
+ },
107
+ {
108
+ "Date": "04/16/2022",
109
+ "Data 1": "190",
110
+ "Data 2": "150",
111
+ "Data 3": "205",
112
+ "Data 4": "205"
113
+ },
114
+ {
115
+ "Date": "04/23/2022",
116
+ "Data 1": "175",
117
+ "Data 2": "165",
118
+ "Data 3": "225",
119
+ "Data 4": "215"
120
+ },
121
+ {
122
+ "Date": "04/30/2022",
123
+ "Data 1": "160",
124
+ "Data 2": "180",
125
+ "Data 3": "245",
126
+ "Data 4": "225"
127
+ },
128
+ {
129
+ "Date": "05/07/2022",
130
+ "Data 1": "145",
131
+ "Data 2": "200",
132
+ "Data 3": "265",
133
+ "Data 4": "240"
134
+ },
135
+ {
136
+ "Date": "05/14/2022",
137
+ "Data 1": "135",
138
+ "Data 2": "220",
139
+ "Data 3": "285",
140
+ "Data 4": "255"
141
+ },
142
+ {
143
+ "Date": "05/21/2022",
144
+ "Data 1": "125",
145
+ "Data 2": "240",
146
+ "Data 3": "305",
147
+ "Data 4": "270"
148
+ },
149
+ {
150
+ "Date": "05/28/2022",
151
+ "Data 1": "115",
152
+ "Data 2": "260",
153
+ "Data 3": "325",
154
+ "Data 4": "285"
155
+ },
156
+ {
157
+ "Date": "06/04/2022",
158
+ "Data 1": "105",
159
+ "Data 2": "280",
160
+ "Data 3": "345",
161
+ "Data 4": "300"
162
+ },
163
+ {
164
+ "Date": "06/11/2022",
165
+ "Data 1": "95",
166
+ "Data 2": "300",
167
+ "Data 3": "365",
168
+ "Data 4": "315"
169
+ },
170
+ {
171
+ "Date": "06/18/2022",
172
+ "Data 1": "90",
173
+ "Data 2": "320",
174
+ "Data 3": "385",
175
+ "Data 4": "330"
176
+ },
177
+ {
178
+ "Date": "06/25/2022",
179
+ "Data 1": "85",
180
+ "Data 2": "340",
181
+ "Data 3": "405",
182
+ "Data 4": "340"
183
+ },
184
+ {
185
+ "Date": "07/02/2022",
186
+ "Data 1": "80",
187
+ "Data 2": "360",
188
+ "Data 3": "420",
189
+ "Data 4": "350"
190
+ },
191
+ {
192
+ "Date": "07/09/2022",
193
+ "Data 1": "75",
194
+ "Data 2": "380",
195
+ "Data 3": "435",
196
+ "Data 4": "360"
197
+ },
198
+ {
199
+ "Date": "07/16/2022",
200
+ "Data 1": "70",
201
+ "Data 2": "400",
202
+ "Data 3": "450",
203
+ "Data 4": "365"
204
+ },
205
+ {
206
+ "Date": "07/23/2022",
207
+ "Data 1": "65",
208
+ "Data 2": "420",
209
+ "Data 3": "460",
210
+ "Data 4": "370"
211
+ },
212
+ {
213
+ "Date": "07/30/2022",
214
+ "Data 1": "60",
215
+ "Data 2": "440",
216
+ "Data 3": "470",
217
+ "Data 4": "372"
218
+ },
219
+ {
220
+ "Date": "08/06/2022",
221
+ "Data 1": "55",
222
+ "Data 2": "470",
223
+ "Data 3": "460",
224
+ "Data 4": "370"
225
+ },
226
+ {
227
+ "Date": "08/13/2022",
228
+ "Data 1": "50",
229
+ "Data 2": "495",
230
+ "Data 3": "445",
231
+ "Data 4": "365"
232
+ },
233
+ {
234
+ "Date": "08/20/2022",
235
+ "Data 1": "48",
236
+ "Data 2": "480",
237
+ "Data 3": "430",
238
+ "Data 4": "355"
239
+ },
240
+ {
241
+ "Date": "08/27/2022",
242
+ "Data 1": "45",
243
+ "Data 2": "455",
244
+ "Data 3": "410",
245
+ "Data 4": "345"
246
+ },
247
+ {
248
+ "Date": "09/03/2022",
249
+ "Data 1": "42",
250
+ "Data 2": "420",
251
+ "Data 3": "380",
252
+ "Data 4": "325"
253
+ },
254
+ {
255
+ "Date": "09/10/2022",
256
+ "Data 1": "38",
257
+ "Data 2": "380",
258
+ "Data 3": "345",
259
+ "Data 4": "300"
260
+ },
261
+ {
262
+ "Date": "09/17/2022",
263
+ "Data 1": "34",
264
+ "Data 2": "330",
265
+ "Data 3": "300",
266
+ "Data 4": "270"
267
+ },
268
+ {
269
+ "Date": "09/24/2022",
270
+ "Data 1": "30",
271
+ "Data 2": "280",
272
+ "Data 3": "255",
273
+ "Data 4": "240"
274
+ },
275
+ {
276
+ "Date": "10/01/2022",
277
+ "Data 1": "25",
278
+ "Data 2": "230",
279
+ "Data 3": "210",
280
+ "Data 4": "205"
281
+ },
282
+ {
283
+ "Date": "10/08/2022",
284
+ "Data 1": "20",
285
+ "Data 2": "185",
286
+ "Data 3": "165",
287
+ "Data 4": "170"
288
+ },
289
+ {
290
+ "Date": "10/15/2022",
291
+ "Data 1": "15",
292
+ "Data 2": "140",
293
+ "Data 3": "120",
294
+ "Data 4": "130"
295
+ },
296
+ {
297
+ "Date": "10/22/2022",
298
+ "Data 1": "10",
299
+ "Data 2": "95",
300
+ "Data 3": "80",
301
+ "Data 4": "90"
302
+ },
303
+ {
304
+ "Date": "10/29/2022",
305
+ "Data 1": "8",
306
+ "Data 2": "70",
307
+ "Data 3": "55",
308
+ "Data 4": "65"
309
+ },
310
+ {
311
+ "Date": "11/05/2022",
312
+ "Data 1": "6",
313
+ "Data 2": "45",
314
+ "Data 3": "35",
315
+ "Data 4": "40"
316
+ },
317
+ {
318
+ "Date": "11/12/2022",
319
+ "Data 1": "5",
320
+ "Data 2": "30",
321
+ "Data 3": "22",
322
+ "Data 4": "28"
323
+ },
324
+ {
325
+ "Date": "11/19/2022",
326
+ "Data 1": "4",
327
+ "Data 2": "18",
328
+ "Data 3": "12",
329
+ "Data 4": "15"
330
+ },
331
+ {
332
+ "Date": "11/26/2022",
333
+ "Data 1": "3",
334
+ "Data 2": "10",
335
+ "Data 3": "6",
336
+ "Data 4": "8"
337
+ },
338
+ {
339
+ "Date": "12/03/2022",
340
+ "Data 1": "3",
341
+ "Data 2": "8",
342
+ "Data 3": "5",
343
+ "Data 4": "6"
344
+ },
345
+ {
346
+ "Date": "12/10/2022",
347
+ "Data 1": "2",
348
+ "Data 2": "6",
349
+ "Data 3": "4",
350
+ "Data 4": "4"
351
+ },
352
+ {
353
+ "Date": "12/17/2022",
354
+ "Data 1": "2",
355
+ "Data 2": "5",
356
+ "Data 3": "3",
357
+ "Data 4": "3"
358
+ },
359
+ {
360
+ "Date": "12/24/2022",
361
+ "Data 1": "1",
362
+ "Data 2": "3",
363
+ "Data 3": "2",
364
+ "Data 4": "2"
365
+ },
366
+ {
367
+ "Date": "12/31/2022",
368
+ "Data 1": "1",
369
+ "Data 2": "2",
370
+ "Data 3": "1",
371
+ "Data 4": "1"
372
+ }
373
+ ]
@@ -0,0 +1,3 @@
1
+ Program,Reach,Engagement,Effectiveness,Adoption,Maintenance,Cost Efficiency
2
+ Program A,85,70,90,65,75,80
3
+ Program B,60,85,70,90,80,55
@@ -1,4 +1,4 @@
1
- import React, { useState, useContext, useMemo, useCallback, useEffect, memo } from 'react'
1
+ import React, { useState, useContext, useMemo, useCallback, useEffect, useRef, memo } from 'react'
2
2
  import {
3
3
  useTable,
4
4
  useBlockLayout,
@@ -20,16 +20,19 @@ import { errorMessages } from '../helpers/errorMessages'
20
20
  import { DataSet } from '@cdc/core/types/DataSet'
21
21
  import Icon from '@cdc/core/components/ui/Icon'
22
22
 
23
- const TableFilter = memo(({ globalFilter, setGlobalFilter, disabled = false }: any) => {
24
- const [filterValue, setFilterValue] = useState(globalFilter)
23
+ const TableFilter = memo(({ globalFilter, setGlobalFilter = () => {}, disabled = false }: any) => {
24
+ const [filterValue, setFilterValue] = useState(globalFilter ?? '')
25
25
 
26
26
  const [debouncedValue] = useDebounce(filterValue, 200)
27
27
 
28
28
  useEffect(() => {
29
- if ('string' === typeof debouncedValue && debouncedValue !== globalFilter) {
30
- setGlobalFilter(debouncedValue ?? '')
29
+ if ('string' === typeof debouncedValue && typeof setGlobalFilter === 'function') {
30
+ const nextFilter = debouncedValue.trim() ? debouncedValue : undefined
31
+ if (nextFilter !== globalFilter) {
32
+ setGlobalFilter(nextFilter)
33
+ }
31
34
  }
32
- }, [debouncedValue])
35
+ }, [debouncedValue, globalFilter, setGlobalFilter])
33
36
 
34
37
  const onChange = e => {
35
38
  setFilterValue(e.target.value)
@@ -86,30 +89,40 @@ const Footer = memo(({ previousPage, nextPage, canPreviousPage, canNextPage, pag
86
89
  ))
87
90
 
88
91
  const PreviewDataTable = () => {
89
- const { config } = useContext(ConfigContext)
92
+ const { config, errors } = useContext(ConfigContext)
90
93
  const previewData = useMemo(() => {
91
94
  if (config.type === 'dashboard') {
92
- return Object.values(config.datasets).find((dataset: DataSet) => {
95
+ const previewDataset = Object.values(config.datasets).find((dataset: DataSet) => {
93
96
  return dataset.preview && Array.isArray(dataset.data)
94
97
  })
98
+ return previewDataset?.data
95
99
  }
96
100
  return config.data
97
101
  }, [config.type, config.data, config.datasets])
98
- const [tableData, _setTableData] = useState(previewData)
102
+ const [tableData, _setTableData] = useState(Array.isArray(previewData) ? previewData : null)
103
+ const lastDataSourceRef = useRef<any[]>(null)
99
104
  const runSideEffects = (td: any[]) => {
105
+ if (!Array.isArray(td) || td.length === 0) return td
106
+
100
107
  const isSankey = Object.keys(td[0]).includes('tableData')
101
- const newData = generateColumns(isSankey ? td[0].tableData : td)
102
- validateFipsCodeLength(newData)
103
- return newData
108
+ const normalizedData = isSankey ? td[0].tableData : td
109
+ validateFipsCodeLength(normalizedData)
110
+ return normalizedData
111
+ }
112
+ const setTableData = td => {
113
+ if (!Array.isArray(td) || td.length === 0) return
114
+ if (lastDataSourceRef.current === td) return
115
+
116
+ lastDataSourceRef.current = td
117
+ _setTableData(runSideEffects(td))
104
118
  }
105
- const setTableData = td => _setTableData(runSideEffects(td))
106
119
 
107
120
  const dispatch = useContext(EditorDispatchContext)
108
121
 
109
122
  const fetchDatasetData = async (datasetKey, datasetConfig) => {
110
123
  if (datasetConfig.preview) {
111
124
  if (datasetConfig.dataUrl) {
112
- const remoteData = await fetchRemoteData(datasetConfig.dataUrl)
125
+ const { data: remoteData } = await fetchRemoteData(datasetConfig.dataUrl)
113
126
  if (Array.isArray(remoteData)) {
114
127
  setTableData(remoteData)
115
128
  }
@@ -132,7 +145,7 @@ const PreviewDataTable = () => {
132
145
  await handleDashboardData(config.datasets)
133
146
  } else {
134
147
  if (config.dataUrl) {
135
- const remoteData = await fetchRemoteData(config.dataUrl)
148
+ const { data: remoteData } = await fetchRemoteData(config.dataUrl)
136
149
  if (Array.isArray(remoteData)) {
137
150
  setTableData(remoteData)
138
151
  }
@@ -144,16 +157,11 @@ const PreviewDataTable = () => {
144
157
  }
145
158
 
146
159
  loadData()
147
- }, [config, config.data, previewData]) // eslint-disable-line
160
+ }, [config.data, config.dataUrl, config.datasets, config.type, previewData]) // eslint-disable-line
148
161
 
149
162
  const tableColumns = useMemo(() => {
150
- if (!tableData) return []
151
- const columns = tableData.columns ?? []
152
- if (columns.length > 0 && columns.includes('')) {
153
- // todo find a way to call the errors. Currently they are in DataImport.js
154
- // maybe these can be moved to a file? but then we need a way to add settings like size...
155
- dispatch({ type: 'EDITOR_SET_ERRORS', payload: [errorMessages.emptyCols] })
156
- }
163
+ if (!Array.isArray(tableData)) return []
164
+ const columns = Object.keys(tableData[0] ?? {})
157
165
 
158
166
  return columns.map(columnName => {
159
167
  const columnConfig = {
@@ -166,27 +174,13 @@ const PreviewDataTable = () => {
166
174
  })
167
175
  }, [tableData])
168
176
 
169
- // This adds a columns property just like the D3 function for JSON parsing.
170
- const generateColumns = data => {
171
- let columns = []
172
-
173
- data.forEach(rowObj => {
174
- Object.keys(rowObj).forEach(columnHeading => {
175
- if (false === columns.includes(columnHeading)) {
176
- columns.push(columnHeading)
177
- }
178
- })
179
- })
180
-
181
- // D3 uses a weird quirk where it attaches a named property to an array. Replicating here.
182
- type D3Data = any[] & { columns }
183
- const newData: D3Data = [...data] as D3Data
184
-
185
- if (Array.isArray(newData)) {
186
- newData.columns = columns
187
- return newData
177
+ useEffect(() => {
178
+ if (!tableData) return
179
+ const columns = Object.keys(tableData[0] ?? {})
180
+ if (columns.length > 0 && columns.includes('') && !errors?.includes(errorMessages.emptyCols)) {
181
+ dispatch({ type: 'EDITOR_SET_ERRORS', payload: [errorMessages.emptyCols] })
188
182
  }
189
- }
183
+ }, [dispatch, errors, tableData])
190
184
 
191
185
  const {
192
186
  getTableProps,
@@ -245,7 +239,8 @@ const PreviewDataTable = () => {
245
239
  )
246
240
  }
247
241
 
248
- if (!tableData) return [<Header key='header' />, <PlaceholderTable key='table' />]
242
+ if (!Array.isArray(tableData) || tableData.length === 0)
243
+ return [<Header key='header' />, <PlaceholderTable key='table' />]
249
244
 
250
245
  const footerProps = {
251
246
  previousPage,
@@ -1,5 +1,4 @@
1
1
  import React, { useEffect } from 'react'
2
- // import FocusLock from "react-focus-lock";
3
2
  import ReactDOM from 'react-dom'
4
3
  import CloseIcon from '../../assets/icons/close.svg'
5
4
 
@@ -21,7 +20,6 @@ export const Modal = ({ isShown, hide, modalContent, headerText }) => {
21
20
  const modal = (
22
21
  <>
23
22
  <div className='modal-backdrop' onClick={hide} />
24
- {/* <FocusLock> */}
25
23
  <div className='modal-wrapper' aria-modal aria-labelledby={headerText} tabIndex={-1} role='dialog'>
26
24
  <div className='modal'>
27
25
  <div className='modal-header'>
@@ -31,7 +29,6 @@ export const Modal = ({ isShown, hide, modalContent, headerText }) => {
31
29
  <div className='modal-content'>{modalContent}</div>
32
30
  </div>
33
31
  </div>
34
- {/* </FocusLock> */}
35
32
  </>
36
33
  )
37
34
 
@@ -14,7 +14,7 @@
14
14
  display: grid;
15
15
  gap: 1em;
16
16
  &.category_general {
17
- grid-template-columns: repeat(5, 160px);
17
+ grid-template-columns: repeat(6, 160px);
18
18
  }
19
19
  &.category_charts {
20
20
  grid-template-columns: repeat(7, 160px);
@@ -1,6 +1,6 @@
1
1
  @import 'variables';
2
2
 
3
- .cdc-open-viz-module.cdc-editor {
3
+ .cove-visualization.cdc-editor {
4
4
  min-height: inherit;
5
5
  display: flex;
6
6
  flex-direction: column;
package/vite.config.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import GenerateViteConfig from '@cdc/core/generateViteConfig.js'
2
2
  import { moduleName } from './package.json'
3
3
 
4
- export default GenerateViteConfig(moduleName)
4
+ // Editor doesn't want the default padding CSS
5
+ export default GenerateViteConfig(moduleName, {}, {}, { css: '' })