@cdc/core 4.24.12-2 → 4.25.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.
- package/components/DataTable/DataTable.tsx +26 -36
- package/components/DataTable/components/ChartHeader.tsx +3 -2
- package/components/DataTable/components/ExpandCollapse.tsx +1 -4
- package/components/DataTable/data-table.css +2 -7
- package/components/DataTable/helpers/customSort.ts +2 -2
- package/components/DataTable/helpers/mapCellMatrix.tsx +83 -60
- package/components/DataTable/types/TableConfig.ts +0 -1
- package/components/EditorPanel/FootnotesEditor.tsx +49 -7
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +3 -2
- package/components/Filters/Filters.tsx +16 -9
- package/components/Footnotes/Footnotes.tsx +1 -1
- package/components/Layout/components/Visualization/index.tsx +18 -4
- package/components/Layout/components/Visualization/visualizations.scss +1 -1
- package/components/Legend/Legend.Gradient.tsx +1 -4
- package/components/Legend/index.tsx +1 -1
- package/components/LegendShape.tsx +2 -3
- package/components/MediaControls.jsx +32 -8
- package/components/NestedDropdown/NestedDropdown.tsx +7 -12
- package/components/NestedDropdown/nesteddropdown.styles.css +11 -5
- package/components/Table/Table.tsx +0 -6
- package/components/Table/components/Row.tsx +2 -5
- package/components/_stories/DataTable.stories.tsx +1 -2
- package/components/elements/Button.jsx +38 -19
- package/components/elements/Confirm.tsx +45 -0
- package/components/elements/Error.tsx +24 -0
- package/components/managers/DataDesigner.tsx +198 -143
- package/components/ui/Title/Title.scss +12 -5
- package/components/ui/Title/index.tsx +1 -1
- package/dist/cove-main.css +77 -591
- package/dist/cove-main.css.map +1 -1
- package/helpers/DataTransform.ts +55 -63
- package/helpers/addValuesToFilters.ts +24 -9
- package/helpers/cove/accessibility.ts +24 -0
- package/helpers/cove/fontSettings.ts +1 -1
- package/helpers/cove/number.ts +1 -7
- package/helpers/coveUpdateWorker.ts +5 -1
- package/helpers/displayDataAsText.ts +64 -0
- package/helpers/formatConfigBeforeSave.ts +1 -1
- package/helpers/isOlderVersion.ts +20 -0
- package/helpers/missingRequiredSections.ts +20 -0
- package/helpers/tests/addValuesToFilters.test.ts +13 -0
- package/helpers/useDataVizClasses.ts +8 -4
- package/helpers/ver/4.24.11.ts +18 -0
- package/helpers/ver/4.25.1.ts +18 -0
- package/package.json +2 -2
- package/styles/_button-section.scss +2 -5
- package/styles/_global-variables.scss +17 -7
- package/styles/_global.scss +8 -12
- package/styles/_reset.scss +4 -5
- package/styles/_typography.scss +0 -20
- package/styles/_variables.scss +0 -3
- package/styles/base.scss +44 -5
- package/styles/cove-main.scss +1 -1
- package/styles/filters.scss +5 -6
- package/styles/v2/base/_general.scss +3 -2
- package/styles/v2/components/button.scss +0 -1
- package/styles/v2/main.scss +3 -4
- package/styles/v2/utils/index.scss +0 -1
- package/types/BoxPlot.ts +1 -0
- package/types/Runtime.ts +1 -0
- package/types/Table.ts +0 -1
- package/types/Version.ts +1 -1
- package/styles/v2/utils/_spacers.scss +0 -31
|
@@ -42,13 +42,30 @@ const generateMedia = (state, type, elementToCapture) => {
|
|
|
42
42
|
// Apparently some packages use state.title where others use state.general.title
|
|
43
43
|
const handleFileName = state => {
|
|
44
44
|
// dashboard titles
|
|
45
|
-
if (state?.dashboard?.title)
|
|
45
|
+
if (state?.dashboard?.title)
|
|
46
|
+
return (
|
|
47
|
+
state.dashboard.title.replace(/\s+/g, '-').toLowerCase() +
|
|
48
|
+
'-' +
|
|
49
|
+
date.getDate() +
|
|
50
|
+
date.getMonth() +
|
|
51
|
+
date.getFullYear()
|
|
52
|
+
)
|
|
46
53
|
|
|
47
54
|
// map titles
|
|
48
|
-
if (state?.general?.title)
|
|
55
|
+
if (state?.general?.title)
|
|
56
|
+
return (
|
|
57
|
+
state.general.title.replace(/\s+/g, '-').toLowerCase() +
|
|
58
|
+
'-' +
|
|
59
|
+
date.getDate() +
|
|
60
|
+
date.getMonth() +
|
|
61
|
+
date.getFullYear()
|
|
62
|
+
)
|
|
49
63
|
|
|
50
64
|
// chart titles
|
|
51
|
-
if (state?.title)
|
|
65
|
+
if (state?.title)
|
|
66
|
+
return (
|
|
67
|
+
state.title.replace(/\s+/g, '-').toLowerCase() + '-' + date.getDate() + date.getMonth() + date.getFullYear()
|
|
68
|
+
)
|
|
52
69
|
|
|
53
70
|
return 'no-title'
|
|
54
71
|
}
|
|
@@ -59,7 +76,10 @@ const generateMedia = (state, type, elementToCapture) => {
|
|
|
59
76
|
|
|
60
77
|
switch (type) {
|
|
61
78
|
case 'image':
|
|
62
|
-
html2canvas(baseSvg, {
|
|
79
|
+
html2canvas(baseSvg, {
|
|
80
|
+
ignoreElements: el =>
|
|
81
|
+
el.className?.indexOf && el.className.search(/download-buttons|download-links|data-table-container/) !== -1
|
|
82
|
+
}).then(canvas => {
|
|
63
83
|
saveImageAs(canvas.toDataURL(), filename + '.png')
|
|
64
84
|
})
|
|
65
85
|
return
|
|
@@ -98,9 +118,14 @@ const handleTheme = state => {
|
|
|
98
118
|
|
|
99
119
|
// Download CSV
|
|
100
120
|
const Button = ({ state, text, type, title, elementToCapture }) => {
|
|
101
|
-
const buttonClasses = ['btn', 'btn-
|
|
121
|
+
const buttonClasses = ['btn', 'btn-primary']
|
|
102
122
|
return (
|
|
103
|
-
<button
|
|
123
|
+
<button
|
|
124
|
+
className={buttonClasses.join(' ')}
|
|
125
|
+
title={title}
|
|
126
|
+
onClick={() => generateMedia(state, type, elementToCapture)}
|
|
127
|
+
style={{ lineHeight: '1.4em' }}
|
|
128
|
+
>
|
|
104
129
|
{buttonText[type]}
|
|
105
130
|
</button>
|
|
106
131
|
)
|
|
@@ -108,7 +133,7 @@ const Button = ({ state, text, type, title, elementToCapture }) => {
|
|
|
108
133
|
|
|
109
134
|
// Link to CSV/JSON data
|
|
110
135
|
const Link = ({ config, dashboardDataConfig }) => {
|
|
111
|
-
let dataConfig = dashboardDataConfig || config
|
|
136
|
+
let dataConfig = dashboardDataConfig || config
|
|
112
137
|
// Handles Maps & Charts
|
|
113
138
|
if (dataConfig.dataFileSourceType === 'url' && dataConfig.dataFileName && config.table.showDownloadUrl) {
|
|
114
139
|
return (
|
|
@@ -126,7 +151,6 @@ const Link = ({ config, dashboardDataConfig }) => {
|
|
|
126
151
|
) : null
|
|
127
152
|
}
|
|
128
153
|
|
|
129
|
-
// TODO: convert to standardized COVE section
|
|
130
154
|
const Section = ({ children, classes }) => {
|
|
131
155
|
return (
|
|
132
156
|
<section className={classes.join(' ')}>
|
|
@@ -124,25 +124,21 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
|
|
|
124
124
|
}) => {
|
|
125
125
|
const dropdownId = useId()
|
|
126
126
|
|
|
127
|
-
const [userSearchTerm, setUserSearchTerm] = useState(
|
|
128
|
-
const [inputValue, setInputValue] = useState('')
|
|
127
|
+
const [userSearchTerm, setUserSearchTerm] = useState(null)
|
|
129
128
|
|
|
130
|
-
const
|
|
129
|
+
const inputValue = useMemo(() => {
|
|
131
130
|
// value from props
|
|
132
131
|
return activeSubGroup ? `${activeGroup} - ${activeSubGroup}` : ''
|
|
133
|
-
}, [activeSubGroup])
|
|
132
|
+
}, [activeGroup, activeSubGroup])
|
|
134
133
|
const [inputHasFocus, setInputHasFocus] = useState(false)
|
|
135
134
|
const [isListOpened, setIsListOpened] = useState(false)
|
|
136
|
-
|
|
137
135
|
const searchInput = useRef(null)
|
|
138
136
|
const searchDropdown = useRef(null)
|
|
139
137
|
|
|
140
138
|
const chooseSelectedSubGroup = (tierOne: string | number, tierTwo: string | number) => {
|
|
141
139
|
searchInput.current.focus()
|
|
142
|
-
|
|
143
|
-
setUserSearchTerm('')
|
|
140
|
+
setUserSearchTerm(null)
|
|
144
141
|
setIsListOpened(false)
|
|
145
|
-
setInputValue(selectedItemValue)
|
|
146
142
|
handleSelectedItems([String(tierOne), String(tierTwo)])
|
|
147
143
|
}
|
|
148
144
|
|
|
@@ -220,14 +216,13 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
|
|
|
220
216
|
}
|
|
221
217
|
|
|
222
218
|
const filterOptions = useMemo(() => {
|
|
223
|
-
return filterSearchTerm(userSearchTerm, options)
|
|
219
|
+
return filterSearchTerm(userSearchTerm || '', options)
|
|
224
220
|
}, [userSearchTerm, options])
|
|
225
221
|
|
|
226
222
|
const handleSearchTermChange = e => {
|
|
227
223
|
const newSearchTerm = e.target.value
|
|
228
224
|
setIsListOpened(true)
|
|
229
225
|
setUserSearchTerm(newSearchTerm)
|
|
230
|
-
setInputValue(newSearchTerm)
|
|
231
226
|
}
|
|
232
227
|
|
|
233
228
|
const handleOnBlur = e => {
|
|
@@ -265,7 +260,7 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
|
|
|
265
260
|
aria-haspopup='true'
|
|
266
261
|
aria-hidden='false'
|
|
267
262
|
tabIndex={0}
|
|
268
|
-
value={
|
|
263
|
+
value={userSearchTerm !== null ? userSearchTerm : inputValue}
|
|
269
264
|
onChange={handleSearchTermChange}
|
|
270
265
|
placeholder={loading ? 'Loading...' : '- Select -'}
|
|
271
266
|
disabled={loading || !options.length}
|
|
@@ -303,7 +298,7 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
|
|
|
303
298
|
chooseSelectedSubGroup(groupValue, subGroupValue)
|
|
304
299
|
}}
|
|
305
300
|
userSelectedLabel={activeGroup + activeSubGroup}
|
|
306
|
-
userSearchTerm={userSearchTerm}
|
|
301
|
+
userSearchTerm={userSearchTerm || ''}
|
|
307
302
|
/>
|
|
308
303
|
)
|
|
309
304
|
})
|
|
@@ -10,23 +10,31 @@
|
|
|
10
10
|
list-style: none;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
* {
|
|
14
|
+
font-family: var(--app-font-secondary) !important;
|
|
15
|
+
font-size: var(--filter-select-font-size) !important;
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
.search-input {
|
|
19
|
+
color: var(--cool-gray-90);
|
|
20
|
+
font-weight: 300;
|
|
21
|
+
|
|
14
22
|
border: none;
|
|
15
23
|
position: relative;
|
|
16
24
|
display: inline-block;
|
|
17
25
|
width: 100%;
|
|
18
26
|
padding: 0;
|
|
19
27
|
&::placeholder {
|
|
20
|
-
color: var(--
|
|
28
|
+
color: var(--cool-gray-90);
|
|
21
29
|
}
|
|
22
30
|
}
|
|
23
31
|
|
|
24
32
|
.main-nested-dropdown-container,
|
|
25
33
|
.nested-dropdown-input-container {
|
|
26
|
-
border: 1px solid var(--
|
|
34
|
+
border: 1px solid var(--cool-gray-10);
|
|
27
35
|
min-width: 200px;
|
|
28
36
|
cursor: pointer;
|
|
29
|
-
padding: 0.
|
|
37
|
+
padding: 0.4rem 0.75rem;
|
|
30
38
|
font-size: 1em;
|
|
31
39
|
}
|
|
32
40
|
|
|
@@ -53,7 +61,6 @@
|
|
|
53
61
|
border-radius: 0.25rem;
|
|
54
62
|
position: relative;
|
|
55
63
|
& > span.list-arrow {
|
|
56
|
-
color: var(--mediumGray);
|
|
57
64
|
position: absolute;
|
|
58
65
|
top: 9px;
|
|
59
66
|
right: 1px;
|
|
@@ -63,7 +70,6 @@
|
|
|
63
70
|
&.disabled {
|
|
64
71
|
background-color: var(--lightestGray);
|
|
65
72
|
& > :is(input) {
|
|
66
|
-
color: var(--darkGray);
|
|
67
73
|
background-color: var(--lightestGray);
|
|
68
74
|
}
|
|
69
75
|
}
|
|
@@ -22,7 +22,6 @@ type TableProps = {
|
|
|
22
22
|
}
|
|
23
23
|
wrapColumns?: boolean
|
|
24
24
|
hasRowType?: boolean // if it has row type then the first column is the row type which will explain how to render the row
|
|
25
|
-
fontSize: 'small' | 'medium' | 'large'
|
|
26
25
|
viewport: 'lg' | 'md' | 'sm' | 'xs' | 'xxs'
|
|
27
26
|
preliminaryData?: PreliminaryDataItem[]
|
|
28
27
|
}
|
|
@@ -39,7 +38,6 @@ const Table = ({
|
|
|
39
38
|
tableOptions,
|
|
40
39
|
wrapColumns,
|
|
41
40
|
hasRowType,
|
|
42
|
-
fontSize,
|
|
43
41
|
viewport,
|
|
44
42
|
preliminaryData
|
|
45
43
|
}: TableProps) => {
|
|
@@ -71,7 +69,6 @@ const Table = ({
|
|
|
71
69
|
childRow={row}
|
|
72
70
|
wrapColumns={wrapColumns}
|
|
73
71
|
cellMinWidth={tableOptions.cellMinWidth}
|
|
74
|
-
fontSize={fontSize}
|
|
75
72
|
viewport={viewport}
|
|
76
73
|
/>
|
|
77
74
|
)
|
|
@@ -92,7 +89,6 @@ const Table = ({
|
|
|
92
89
|
childRow={childRow}
|
|
93
90
|
wrapColumns={wrapColumns}
|
|
94
91
|
cellMinWidth={tableOptions.cellMinWidth}
|
|
95
|
-
fontSize={fontSize}
|
|
96
92
|
viewport={viewport}
|
|
97
93
|
/>
|
|
98
94
|
)
|
|
@@ -110,7 +106,6 @@ const Table = ({
|
|
|
110
106
|
isTotal={true}
|
|
111
107
|
wrapColumns={wrapColumns}
|
|
112
108
|
cellMinWidth={tableOptions.cellMinWidth}
|
|
113
|
-
fontSize={fontSize}
|
|
114
109
|
viewport={viewport}
|
|
115
110
|
/>
|
|
116
111
|
)
|
|
@@ -125,7 +120,6 @@ const Table = ({
|
|
|
125
120
|
childRow={childRowCopy}
|
|
126
121
|
wrapColumns={wrapColumns}
|
|
127
122
|
cellMinWidth={tableOptions.cellMinWidth}
|
|
128
|
-
fontSize={fontSize}
|
|
129
123
|
viewport={viewport}
|
|
130
124
|
/>
|
|
131
125
|
)
|
|
@@ -8,18 +8,15 @@ type RowProps = {
|
|
|
8
8
|
wrapColumns: boolean
|
|
9
9
|
isTotal?: boolean
|
|
10
10
|
cellMinWidth?: number
|
|
11
|
-
fontSize: 'small' | 'medium' | 'large'
|
|
12
11
|
viewport: 'lg' | 'md' | 'sm' | 'xs' | 'xxs'
|
|
13
12
|
style?: object
|
|
14
13
|
preliminaryData?: PreliminaryDataItem[]
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
const Row: FC<RowProps> = props => {
|
|
18
|
-
const { childRow, rowKey, wrapColumns, cellMinWidth = 0, isTotal,
|
|
17
|
+
const { childRow, rowKey, wrapColumns, cellMinWidth = 0, isTotal, viewport, preliminaryData } = props
|
|
19
18
|
const whiteSpace = wrapColumns ? 'unset' : 'nowrap'
|
|
20
19
|
const minWidth = cellMinWidth + 'px'
|
|
21
|
-
const fontSizes = { small: 16, medium: 18, large: 20 }
|
|
22
|
-
const cellFontSize = ['xs', 'xxs'].includes(viewport) ? '12px' : `${fontSizes[fontSize]}px`
|
|
23
20
|
|
|
24
21
|
return (
|
|
25
22
|
<tr>
|
|
@@ -34,7 +31,7 @@ const Row: FC<RowProps> = props => {
|
|
|
34
31
|
<Cell
|
|
35
32
|
ariaLabel={style?.color ? 'suppressed data' : ''}
|
|
36
33
|
key={rowKey + '__' + i}
|
|
37
|
-
style={{ whiteSpace, minWidth,
|
|
34
|
+
style={{ whiteSpace, minWidth, ...style }}
|
|
38
35
|
isBold={isTotal}
|
|
39
36
|
>
|
|
40
37
|
{child}
|
|
@@ -5,25 +5,41 @@ import LoadSpin from '../ui/LoadSpin'
|
|
|
5
5
|
|
|
6
6
|
import '../../styles/v2/components/button.scss'
|
|
7
7
|
|
|
8
|
-
const Button = ({
|
|
8
|
+
const Button = ({
|
|
9
|
+
style,
|
|
10
|
+
role,
|
|
11
|
+
hoverStyle = {},
|
|
12
|
+
fluid = false,
|
|
13
|
+
loading = false,
|
|
14
|
+
loadingText = 'Loading...',
|
|
15
|
+
flexCenter,
|
|
16
|
+
active = false,
|
|
17
|
+
onClick,
|
|
18
|
+
children,
|
|
19
|
+
...attributes
|
|
20
|
+
}) => {
|
|
9
21
|
const buttonRef = useRef(null)
|
|
10
22
|
|
|
11
|
-
const [
|
|
12
|
-
const [
|
|
13
|
-
const [
|
|
14
|
-
const [
|
|
23
|
+
const [buttonState, setButtonState] = useState('out')
|
|
24
|
+
const [customStyles, setCustomStyles] = useState({ ...style })
|
|
25
|
+
const [childrenWidth, setChildrenWidth] = useState()
|
|
26
|
+
const [loadtextWidth, setLoadtextWidth] = useState()
|
|
15
27
|
|
|
16
28
|
const attributesObj = {
|
|
17
29
|
...attributes,
|
|
18
30
|
style: customStyles,
|
|
19
|
-
className:
|
|
31
|
+
className:
|
|
32
|
+
'cove-button' +
|
|
33
|
+
(flexCenter || 'loader' === role ? ' cove-button--flex-center' : '') +
|
|
34
|
+
(fluid ? ' fluid' : '') +
|
|
35
|
+
(loading ? ' loading' : '') +
|
|
36
|
+
(attributes.className ? ' ' + attributes.className : ''),
|
|
20
37
|
onMouseOver: () => setButtonState('in'),
|
|
21
38
|
onMouseOut: () => setButtonState('out'),
|
|
22
39
|
onFocus: () => setButtonState('in'),
|
|
23
40
|
onBlur: () => setButtonState('out')
|
|
24
41
|
}
|
|
25
42
|
|
|
26
|
-
|
|
27
43
|
useEffect(() => {
|
|
28
44
|
if ('loader' === role && buttonRef.current) {
|
|
29
45
|
//Create ghost object and text nodes for children
|
|
@@ -54,9 +70,8 @@ const Button = ({ style, role, hoverStyle = {}, fluid = false, loading = false,
|
|
|
54
70
|
buttonRef.current.parentNode.removeChild(ghostSpan)
|
|
55
71
|
buttonRef.current.parentNode.removeChild(ghostLoaderSpan)
|
|
56
72
|
}
|
|
57
|
-
return () => {
|
|
58
|
-
|
|
59
|
-
}, [ buttonRef, children, loadingText, role ])
|
|
73
|
+
return () => {}
|
|
74
|
+
}, [buttonRef, children, loadingText, role])
|
|
60
75
|
|
|
61
76
|
useEffect(() => {
|
|
62
77
|
//Adjust button styles depending on cursor, focus, and active, states
|
|
@@ -64,9 +79,10 @@ const Button = ({ style, role, hoverStyle = {}, fluid = false, loading = false,
|
|
|
64
79
|
|
|
65
80
|
// If button state is out, check if its 'active'; we want to keep hover styles applied to 'active' buttons
|
|
66
81
|
if (buttonState === 'out')
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
82
|
+
if (!active)
|
|
83
|
+
// If button state is out, and not 'active', reset display styles back to default
|
|
84
|
+
setCustomStyles({ ...style })
|
|
85
|
+
}, [buttonState, active, style])
|
|
70
86
|
|
|
71
87
|
return (
|
|
72
88
|
<button
|
|
@@ -82,16 +98,19 @@ const Button = ({ style, role, hoverStyle = {}, fluid = false, loading = false,
|
|
|
82
98
|
<>
|
|
83
99
|
{'loader' === role && (
|
|
84
100
|
<>
|
|
85
|
-
<span
|
|
86
|
-
|
|
101
|
+
<span
|
|
102
|
+
className='cove-button__text'
|
|
103
|
+
style={loading ? { width: loadtextWidth + 'px' } : { width: childrenWidth + 'px' }}
|
|
104
|
+
>
|
|
105
|
+
<div className='cove-button__text--loading' style={loading ? { opacity: 1 } : null}>
|
|
87
106
|
{loadingText}
|
|
88
107
|
</div>
|
|
89
|
-
<div className=
|
|
108
|
+
<div className='cove-button__text--children' style={loading ? { opacity: 0 } : null}>
|
|
90
109
|
{children}
|
|
91
110
|
</div>
|
|
92
111
|
</span>
|
|
93
|
-
<div className=
|
|
94
|
-
<LoadSpin className=
|
|
112
|
+
<div className='cove-button__load-spin' style={loading ? { width: '28px', opacity: 1 } : null}>
|
|
113
|
+
<LoadSpin className='ms-1' size={20} />
|
|
95
114
|
</div>
|
|
96
115
|
</>
|
|
97
116
|
)}
|
|
@@ -104,7 +123,7 @@ const Button = ({ style, role, hoverStyle = {}, fluid = false, loading = false,
|
|
|
104
123
|
|
|
105
124
|
Button.propTypes = {
|
|
106
125
|
/** Specify special role type for button */
|
|
107
|
-
role: PropTypes.oneOf([
|
|
126
|
+
role: PropTypes.oneOf(['loader']),
|
|
108
127
|
/** Provide object with styles that overwrite base styles when hovered */
|
|
109
128
|
hoverStyle: PropTypes.object,
|
|
110
129
|
/** Enables button to stretch to the full width of the content */
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Button from './Button.jsx'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { missingRequiredSections } from '../../helpers/missingRequiredSections.js'
|
|
4
|
+
const Confirm = props => {
|
|
5
|
+
const { updateConfig, config } = props
|
|
6
|
+
const confirmDone = e => {
|
|
7
|
+
if (e) {
|
|
8
|
+
e.preventDefault()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let newConfig = { ...config }
|
|
12
|
+
delete newConfig.newViz
|
|
13
|
+
|
|
14
|
+
updateConfig(newConfig)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const styles: React.CSSProperties = {
|
|
18
|
+
position: 'relative',
|
|
19
|
+
height: '100vh',
|
|
20
|
+
width: '100%',
|
|
21
|
+
display: 'flex',
|
|
22
|
+
justifyContent: 'center',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
gridArea: 'content'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<section className='waiting' style={styles}>
|
|
29
|
+
<section className='waiting-container'>
|
|
30
|
+
<h3>Finish Configuring</h3>
|
|
31
|
+
<p>Set all required options to the left and confirm below to display a preview of the chart.</p>
|
|
32
|
+
<Button
|
|
33
|
+
className='btn btn-primary'
|
|
34
|
+
style={{ margin: '1em auto' }}
|
|
35
|
+
disabled={missingRequiredSections(config)}
|
|
36
|
+
onClick={e => confirmDone(e)}
|
|
37
|
+
>
|
|
38
|
+
I'm Done
|
|
39
|
+
</Button>
|
|
40
|
+
</section>
|
|
41
|
+
</section>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default Confirm
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
const Error = ({ errorMessage }) => {
|
|
3
|
+
const styles: React.CSSProperties = {
|
|
4
|
+
position: 'absolute',
|
|
5
|
+
background: 'white',
|
|
6
|
+
zIndex: '999',
|
|
7
|
+
height: '100vh',
|
|
8
|
+
width: '100%',
|
|
9
|
+
display: 'flex',
|
|
10
|
+
justifyContent: 'center',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
gridArea: 'content'
|
|
13
|
+
}
|
|
14
|
+
return (
|
|
15
|
+
<section className='waiting' style={styles}>
|
|
16
|
+
<section className='waiting-container'>
|
|
17
|
+
<h3>Error With Configuration</h3>
|
|
18
|
+
<p>{errorMessage}</p>
|
|
19
|
+
</section>
|
|
20
|
+
</section>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default Error
|