@cdc/dashboard 4.22.10 → 4.23.1

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.
@@ -1,5 +1,5 @@
1
- import { createContext } from 'react';
1
+ import { createContext } from 'react'
2
2
 
3
- const ConfigContext = createContext({});
3
+ const ConfigContext = createContext({})
4
4
 
5
- export default ConfigContext;
5
+ export default ConfigContext
@@ -7,7 +7,7 @@ import Widget from './Widget'
7
7
  const Column = ({ data, rowIdx, colIdx }) => {
8
8
  const { visualizations } = useContext(ConfigContext)
9
9
 
10
- const [ { isOver, canDrop }, drop ] = useDrop(() => ({
10
+ const [{ isOver, canDrop }, drop] = useDrop(() => ({
11
11
  accept: 'vis-widget',
12
12
  drop: () => ({
13
13
  rowIdx,
@@ -15,7 +15,7 @@ const Column = ({ data, rowIdx, colIdx }) => {
15
15
  canDrop
16
16
  }),
17
17
  canDrop: () => !data.widget,
18
- collect: (monitor) => ({
18
+ collect: monitor => ({
19
19
  isOver: monitor.isOver(),
20
20
  canDrop: !!monitor.canDrop()
21
21
  })
@@ -23,10 +23,7 @@ const Column = ({ data, rowIdx, colIdx }) => {
23
23
 
24
24
  const widget = data.widget ? visualizations[data.widget] : null
25
25
 
26
- let classNames = [
27
- 'builder-column',
28
- 'column-size--' + data.width,
29
- ]
26
+ let classNames = ['builder-column', 'column-size--' + data.width]
30
27
 
31
28
  if (isOver && canDrop) {
32
29
  classNames.push('column--drop')
@@ -38,9 +35,13 @@ const Column = ({ data, rowIdx, colIdx }) => {
38
35
 
39
36
  return (
40
37
  <div className={classNames.join(' ')} ref={drop}>
41
- {widget ?
42
- <Widget data={{ rowIdx, colIdx, ...widget }} type={widget.visualizationType ?? widget.general?.geoType}/> :
43
- <p className="builder-column__text">Drag and drop <br/> visualization</p>}
38
+ {widget ? (
39
+ <Widget data={{ rowIdx, colIdx, ...widget }} type={widget.visualizationType ?? widget.general?.geoType} />
40
+ ) : (
41
+ <p className='builder-column__text'>
42
+ Drag and drop <br /> visualization
43
+ </p>
44
+ )}
44
45
  </div>
45
46
  )
46
47
  }
@@ -1,170 +1,159 @@
1
- import React, {
2
- useContext,
3
- useEffect,
4
- useState,
5
- useMemo,
6
- memo } from 'react';
7
- import {
8
- useTable,
9
- useSortBy,
10
- useResizeColumns,
11
- useBlockLayout
12
- } from 'react-table';
13
- import Papa from 'papaparse';
14
- import { Base64 } from 'js-base64';
15
-
16
- import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
1
+ import React, { useContext, useEffect, useState, useMemo, memo } from 'react'
2
+ import { useTable, useSortBy, useResizeColumns, useBlockLayout } from 'react-table'
3
+ import Papa from 'papaparse'
4
+ import { Base64 } from 'js-base64'
5
+ import CoveMediaControls from '@cdc/core/helpers/CoveMediaControls'
17
6
 
18
- export default function DataTable(props) {
19
-
20
- const { data, datasetKey, config } = props;
7
+ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
21
8
 
22
- const [tableExpanded, setTableExpanded] = useState<boolean>(config.table ? config.table.expanded : false);
23
- const [accessibilityLabel, setAccessibilityLabel] = useState('');
9
+ export default function DataTable(props) {
10
+ const { data, datasetKey, config, imageRef, dataFileSourceType } = props
11
+ const [tableExpanded, setTableExpanded] = useState<boolean>(config.table ? config.table.expanded : false)
12
+ const [accessibilityLabel, setAccessibilityLabel] = useState('')
24
13
 
25
14
  const DownloadButton = memo(({ data }: any) => {
26
- const fileName = `${config.title ? config.title.substring(0, 50) : 'cdc-open-viz'}.csv`;
15
+ const fileName = `${config.title ? config.title.substring(0, 50) : 'cdc-open-viz'}.csv`
27
16
 
28
- const csvData = Papa.unparse(data);
17
+ const csvData = Papa.unparse(data)
29
18
 
30
19
  const saveBlob = () => {
31
20
  //@ts-ignore
32
21
  if (typeof window.navigator.msSaveBlob === 'function') {
33
- const dataBlob = new Blob([csvData], { type: "text/csv;charset=utf-8;" });
22
+ const dataBlob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' })
34
23
  //@ts-ignore
35
- window.navigator.msSaveBlob(dataBlob, fileName);
24
+ window.navigator.msSaveBlob(dataBlob, fileName)
36
25
  }
37
26
  }
38
27
 
39
28
  return (
40
- <a
41
- download={fileName}
42
- onClick={saveBlob}
43
- href={`data:text/csv;base64,${Base64.encode(csvData)}`}
44
- aria-label="Download this data in a CSV file format."
45
- className={`btn btn-download no-border`}
46
- >
29
+ <a download={fileName} onClick={saveBlob} href={`data:text/csv;base64,${Base64.encode(csvData)}`} aria-label='Download this data in a CSV file format.' className={`no-border dashboard-download-link`}>
47
30
  Download {datasetKey ? `"${datasetKey}"` : 'Data'} (CSV)
48
31
  </a>
49
32
  )
50
- });
51
-
33
+ })
34
+
52
35
  // Creates columns structure for the table
53
36
  const tableColumns = useMemo(() => {
54
- const newTableColumns = [];
37
+ const newTableColumns = []
55
38
 
56
39
  // catch no data errors and update the table header.
57
- if(data.length === 0) {
58
- return [{
59
- Header : 'No Data Found'
60
- }];
40
+ if (data.length === 0) {
41
+ return [
42
+ {
43
+ Header: 'No Data Found'
44
+ }
45
+ ]
61
46
  } else {
62
- Object.keys(data[0]).map((key) => {
63
- const newCol = {
64
- Header: key,
65
- Cell: ({ row }) => {
66
- return (
67
- <>
68
- {row.original[key]}
69
- </>
70
- );
71
- },
72
- id: key,
73
- canSort: true
74
- };
75
-
76
- newTableColumns.push(newCol);
77
- });
47
+ Object.keys(data[0]).map(key => {
48
+ const newCol = {
49
+ Header: key,
50
+ Cell: ({ row }) => {
51
+ return <>{row.original[key]}</>
52
+ },
53
+ id: key,
54
+ canSort: true
55
+ }
56
+
57
+ newTableColumns.push(newCol)
58
+ })
78
59
  }
79
60
 
80
- return newTableColumns;
81
- }, [config]);
61
+ return newTableColumns
62
+ }, [config])
82
63
 
83
- const tableData = useMemo(
84
- () => data,
85
- [data]
86
- );
64
+ const tableData = useMemo(() => data, [data])
87
65
 
88
66
  // Change accessibility label depending on expanded status
89
67
  useEffect(() => {
90
- const expandedLabel = 'Accessible data table.';
91
- const collapsedLabel = 'Accessible data table. This table is currently collapsed visually but can still be read using a screen reader.';
68
+ const expandedLabel = 'Accessible data table.'
69
+ const collapsedLabel = 'Accessible data table. This table is currently collapsed visually but can still be read using a screen reader.'
92
70
 
93
71
  if (tableExpanded === true && accessibilityLabel !== expandedLabel) {
94
- setAccessibilityLabel(expandedLabel);
72
+ setAccessibilityLabel(expandedLabel)
95
73
  }
96
74
 
97
75
  if (tableExpanded === false && accessibilityLabel !== collapsedLabel) {
98
- setAccessibilityLabel(collapsedLabel);
76
+ setAccessibilityLabel(collapsedLabel)
99
77
  }
100
78
  // eslint-disable-next-line react-hooks/exhaustive-deps
101
- }, [tableExpanded]);
79
+ }, [tableExpanded])
102
80
 
103
81
  const defaultColumn = useMemo(
104
82
  () => ({
105
83
  minWidth: 150,
106
84
  width: 200,
107
- maxWidth: 400,
85
+ maxWidth: 400
108
86
  }),
109
87
  []
110
- );
88
+ )
111
89
 
112
- const {
113
- getTableProps,
114
- getTableBodyProps,
115
- headerGroups,
116
- rows,
117
- prepareRow,
118
- } = useTable({ columns: tableColumns, data: tableData, defaultColumn }, useSortBy, useBlockLayout, useResizeColumns);
90
+ const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({ columns: tableColumns, data: tableData, defaultColumn }, useSortBy, useBlockLayout, useResizeColumns)
119
91
 
120
92
  return (
121
- <ErrorBoundary component="DataTable">
122
- <section className={`data-table-container`} aria-label={accessibilityLabel}>
93
+ <ErrorBoundary component='DataTable'>
94
+ <CoveMediaControls.Section classes={['download-links']}>
95
+ {config.table.showDownloadUrl && dataFileSourceType === 'url' && (
96
+ <a className='dashboard-download-link' href={config.datasets[datasetKey].dataFileName} title='Link to View Dataset' target='_blank'>
97
+ Link to View Dataset
98
+ </a>
99
+ )}
100
+ {config.table.download && <DownloadButton data={data} />}
101
+ </CoveMediaControls.Section>
102
+ {config.table.show && (
103
+ <section className={`data-table-container`} aria-label={accessibilityLabel}>
123
104
  <div
124
- role="button"
105
+ role='button'
125
106
  className={tableExpanded ? 'data-table-heading' : 'collapsed data-table-heading'}
126
- onClick={() => { setTableExpanded(!tableExpanded); }}
107
+ onClick={() => {
108
+ setTableExpanded(!tableExpanded)
109
+ }}
127
110
  tabIndex={0}
128
- onKeyDown={(e) => { if (e.keyCode === 13) { setTableExpanded(!tableExpanded); } }}
111
+ onKeyDown={e => {
112
+ if (e.keyCode === 13) {
113
+ setTableExpanded(!tableExpanded)
114
+ }
115
+ }}
129
116
  >
130
- {config.table.label}{datasetKey ? `: ${datasetKey}` : ''}
117
+ {config.table.label}
118
+ {datasetKey ? `: ${datasetKey}` : ''}
131
119
  </div>
132
- <div className="table-container"
133
- style={ { maxHeight: config.table && config.table.limitHeight && `${config.table.height}px`, overflowY: 'scroll' } }>
134
- <table className={tableExpanded ? 'data-table' : 'data-table cdcdataviz-sr-only'} hidden={!tableExpanded} {...getTableProps()}>
135
- <caption className="visually-hidden">{config.table.label}</caption>
120
+ <div className='table-container' style={{ maxHeight: config.table && config.table.limitHeight && `${config.table.height}px`, overflowY: 'scroll' }}>
121
+ <table className={tableExpanded ? 'data-table' : 'data-table cdcdataviz-sr-only'} hidden={!tableExpanded} {...getTableProps()}>
122
+ <caption className='visually-hidden'>{config.table.label}</caption>
136
123
  <thead>
137
- {headerGroups && headerGroups.map((headerGroup) => (
138
- <tr {...headerGroup.getHeaderGroupProps()}>
139
- {headerGroup.headers.map((column) => (
140
- <th tabIndex="0" {...column.getHeaderProps(column.getSortByToggleProps())} className={column.isSorted ? column.isSortedDesc ? 'sort sort-desc' : 'sort sort-asc' : 'sort'} title={column.Header}>
141
- {column.render('Header')}
142
- <div {...column.getResizerProps()} className="resizer" />
143
- </th>
144
- ))}
145
- </tr>
146
- ))}
124
+ {headerGroups &&
125
+ headerGroups.map(headerGroup => (
126
+ <tr {...headerGroup.getHeaderGroupProps()}>
127
+ {headerGroup.headers.map(column => (
128
+ <th tabIndex='0' {...column.getHeaderProps(column.getSortByToggleProps())} className={column.isSorted ? (column.isSortedDesc ? 'sort sort-desc' : 'sort sort-asc') : 'sort'} title={column.Header}>
129
+ {column.render('Header')}
130
+ <div {...column.getResizerProps()} className='resizer' />
131
+ </th>
132
+ ))}
133
+ </tr>
134
+ ))}
147
135
  </thead>
148
- {rows &&
136
+ {rows && (
149
137
  <tbody {...getTableBodyProps()}>
150
- {rows.map((row) => {
151
- prepareRow(row);
138
+ {rows.map(row => {
139
+ prepareRow(row)
152
140
  return (
153
141
  <tr {...row.getRowProps()}>
154
- {row.cells && row.cells.map((cell) => (
155
- <td tabIndex="0" {...cell.getCellProps()}>
156
- {cell.render('Cell')}
157
- </td>
158
- ))}
142
+ {row.cells &&
143
+ row.cells.map(cell => (
144
+ <td tabIndex='0' {...cell.getCellProps()}>
145
+ {cell.render('Cell')}
146
+ </td>
147
+ ))}
159
148
  </tr>
160
- );
149
+ )
161
150
  })}
162
151
  </tbody>
163
- }
152
+ )}
164
153
  </table>
165
154
  </div>
166
- {config.table.download && <DownloadButton data={data} />}
167
- </section>
155
+ </section>
156
+ )}
168
157
  </ErrorBoundary>
169
- );
158
+ )
170
159
  }