@cdc/core 4.24.10 → 4.24.12
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/AdvancedEditor/AdvancedEditor.tsx +17 -13
- package/components/Alert/components/Alert.tsx +39 -8
- package/components/DataTable/DataTable.tsx +31 -10
- package/components/DataTable/components/ExpandCollapse.tsx +1 -1
- package/components/DataTable/components/SortIcon/sort-icon.css +15 -0
- package/components/DataTable/data-table.css +4 -22
- package/components/DataTable/helpers/boxplotCellMatrix.tsx +19 -14
- package/components/DataTable/helpers/getChartCellValue.ts +25 -7
- package/components/EditorPanel/ColumnsEditor.tsx +81 -36
- package/components/EditorPanel/DataTableEditor.tsx +62 -56
- package/components/EditorPanel/FieldSetWrapper.tsx +2 -2
- package/components/EditorPanel/Inputs.tsx +26 -16
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +43 -56
- package/components/Filters/Filters.tsx +16 -11
- package/components/Footnotes/FootnotesStandAlone.tsx +17 -4
- package/components/Layout/components/Sidebar/components/sidebar.styles.scss +0 -4
- package/components/Layout/components/Visualization/visualizations.scss +1 -1
- package/components/Legend/Legend.Gradient.tsx +50 -35
- package/components/Loader/Loader.tsx +10 -5
- package/components/MultiSelect/MultiSelect.tsx +56 -33
- package/components/MultiSelect/multiselect.styles.css +20 -7
- package/components/NestedDropdown/NestedDropdown.tsx +55 -32
- package/components/NestedDropdown/nesteddropdown.styles.css +26 -13
- package/components/Table/Table.tsx +102 -34
- package/components/Table/components/Row.tsx +1 -1
- package/components/_stories/DataTable.stories.tsx +14 -0
- package/components/_stories/Filters.stories.tsx +57 -0
- package/components/_stories/_mocks/DataTable/no-data.json +108 -0
- package/components/inputs/{InputToggle.jsx → InputToggle.tsx} +35 -29
- package/components/ui/Icon.tsx +19 -6
- package/dist/cove-main.css +26 -57
- package/dist/cove-main.css.map +1 -1
- package/helpers/DataTransform.ts +2 -1
- package/helpers/cove/{number.js → number.ts} +25 -11
- package/helpers/fetchRemoteData.js +32 -37
- package/helpers/formatConfigBeforeSave.ts +1 -0
- package/helpers/gatherQueryParams.ts +2 -3
- package/helpers/queryStringUtils.ts +16 -1
- package/helpers/useDataVizClasses.ts +44 -21
- package/helpers/ver/versionNeedsUpdate.ts +2 -0
- package/helpers/viewports.ts +8 -7
- package/package.json +2 -2
- package/styles/_button-section.scss +1 -1
- package/styles/_global-variables.scss +9 -4
- package/styles/_global.scss +21 -22
- package/styles/_reset.scss +0 -12
- package/styles/filters.scss +0 -22
- package/styles/v2/base/_reset.scss +0 -7
- package/styles/v2/components/editor.scss +0 -4
- package/styles/v2/components/icon.scss +1 -1
- package/types/Axis.ts +2 -0
- package/types/BoxPlot.ts +5 -3
- package/types/Color.ts +1 -1
- package/types/Legend.ts +1 -2
- package/types/MarkupInclude.ts +1 -0
- package/types/Runtime.ts +3 -1
- package/types/Series.ts +8 -1
- package/types/Table.ts +1 -1
- package/types/Version.ts +1 -0
- package/types/Visualization.ts +7 -8
- package/components/ui/Select.jsx +0 -30
- package/helpers/getGradientLegendWidth.ts +0 -15
|
@@ -83,7 +83,7 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
83
83
|
</Tooltip>
|
|
84
84
|
}
|
|
85
85
|
/>
|
|
86
|
-
{config.type !== 'table'
|
|
86
|
+
{config.type !== 'table' ? (
|
|
87
87
|
<CheckBox
|
|
88
88
|
value={config.table.show}
|
|
89
89
|
fieldName='show'
|
|
@@ -108,6 +108,15 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
108
108
|
</Tooltip>
|
|
109
109
|
}
|
|
110
110
|
/>
|
|
111
|
+
) : (
|
|
112
|
+
<CheckBox
|
|
113
|
+
value={config.general?.showDownloadButton}
|
|
114
|
+
fieldName='showDownloadButton'
|
|
115
|
+
label='Show Download CSV link'
|
|
116
|
+
section='general'
|
|
117
|
+
updateField={updateField}
|
|
118
|
+
className='column-heading'
|
|
119
|
+
/>
|
|
111
120
|
)}
|
|
112
121
|
|
|
113
122
|
{config.visualizationType !== 'Box Plot' && config.type !== 'table' && (
|
|
@@ -196,15 +205,18 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
196
205
|
/>
|
|
197
206
|
)}
|
|
198
207
|
{config?.visualizationType !== 'Sankey' && (
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
<label>
|
|
209
|
+
<span className='edit-label column-heading mt-1'>Exclude Columns </span>
|
|
210
|
+
<MultiSelect
|
|
211
|
+
key={excludedColumns.join('') + 'excluded'}
|
|
212
|
+
options={dataColumns.map(c => ({ label: c, value: c }))}
|
|
213
|
+
selected={excludedColumns}
|
|
214
|
+
label={'Exclude Columns'}
|
|
215
|
+
fieldName='dataTable'
|
|
216
|
+
section='columns'
|
|
217
|
+
updateField={excludeColumns}
|
|
218
|
+
/>
|
|
219
|
+
</label>
|
|
208
220
|
)}
|
|
209
221
|
<CheckBox
|
|
210
222
|
value={config.table.collapsible}
|
|
@@ -249,15 +261,14 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
249
261
|
updateField={updateField}
|
|
250
262
|
/>
|
|
251
263
|
)}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
)}
|
|
264
|
+
|
|
265
|
+
<CheckBox
|
|
266
|
+
value={config.table.showDownloadLinkBelow}
|
|
267
|
+
fieldName='showDownloadLinkBelow'
|
|
268
|
+
label='Show Download Link Below Table'
|
|
269
|
+
section='table'
|
|
270
|
+
updateField={updateField}
|
|
271
|
+
/>
|
|
261
272
|
<label>
|
|
262
273
|
<span className='edit-label column-heading'>Table Cell Min Width</span>
|
|
263
274
|
<input
|
|
@@ -267,9 +278,17 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
267
278
|
/>
|
|
268
279
|
</label>
|
|
269
280
|
{config?.visualizationType !== 'Sankey' && (
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
|
|
281
|
+
<Select
|
|
282
|
+
value={config.table.groupBy}
|
|
283
|
+
fieldName={'groupBy'}
|
|
284
|
+
section='table'
|
|
285
|
+
label='Group By'
|
|
286
|
+
updateField={(_section, _subSection, _fieldName, value) => changeGroupBy(value)}
|
|
287
|
+
initial={PLACEHOLDER}
|
|
288
|
+
options={groupPivotColumns.filter(
|
|
289
|
+
col => col !== config.table.pivot?.columnName && !(config.table.pivot?.valueColumns || []).includes(col)
|
|
290
|
+
)}
|
|
291
|
+
tooltip={
|
|
273
292
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
274
293
|
<Tooltip.Target>
|
|
275
294
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
@@ -281,27 +300,11 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
281
300
|
</p>
|
|
282
301
|
</Tooltip.Content>
|
|
283
302
|
</Tooltip>
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
<select
|
|
287
|
-
value={config.table.groupBy}
|
|
288
|
-
onChange={event => {
|
|
289
|
-
changeGroupBy(event.target.value)
|
|
290
|
-
}}
|
|
291
|
-
>
|
|
292
|
-
{[
|
|
293
|
-
PLACEHOLDER,
|
|
294
|
-
...groupPivotColumns.filter(
|
|
295
|
-
col => col !== config.table.pivot?.columnName && col !== config.table.pivot?.valueColumn
|
|
296
|
-
)
|
|
297
|
-
].map(option => (
|
|
298
|
-
<option key={option}>{option}</option>
|
|
299
|
-
))}
|
|
300
|
-
</select>
|
|
301
|
-
</label>
|
|
303
|
+
}
|
|
304
|
+
/>
|
|
302
305
|
)}
|
|
303
306
|
<Select
|
|
304
|
-
label='Pivot Column
|
|
307
|
+
label='Pivot Column'
|
|
305
308
|
tooltip={
|
|
306
309
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
307
310
|
<Tooltip.Target>
|
|
@@ -314,7 +317,7 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
314
317
|
}
|
|
315
318
|
value={config.table.pivot?.columnName}
|
|
316
319
|
options={groupPivotColumns.filter(
|
|
317
|
-
col => col !== config.table.groupBy &&
|
|
320
|
+
col => col !== config.table.groupBy && !(config.table.pivot?.valueColumns || []).includes(col)
|
|
318
321
|
)}
|
|
319
322
|
initial='-Select-'
|
|
320
323
|
section='table'
|
|
@@ -323,18 +326,9 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
323
326
|
updateField={updateField}
|
|
324
327
|
/>
|
|
325
328
|
{config.table.pivot?.columnName && (
|
|
326
|
-
<
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
.filter(col => col !== config.table.pivot?.columnName && col !== config.table.groupBy)
|
|
330
|
-
.map(c => ({ label: c, value: c }))}
|
|
331
|
-
selected={config.table.pivot?.valueColumns}
|
|
332
|
-
label='Pivot Value Column(s) '
|
|
333
|
-
section='table'
|
|
334
|
-
subsection='pivot'
|
|
335
|
-
fieldName='valueColumns'
|
|
336
|
-
updateField={updateField}
|
|
337
|
-
tooltip={
|
|
329
|
+
<label>
|
|
330
|
+
<span className='edit-label column-heading mt-1'>
|
|
331
|
+
Pivot Value Column(s)
|
|
338
332
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
339
333
|
<Tooltip.Target>
|
|
340
334
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
@@ -343,8 +337,20 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
343
337
|
<p>The column(s) whos values will be pivoted under the column selected as the Filter.</p>
|
|
344
338
|
</Tooltip.Content>
|
|
345
339
|
</Tooltip>
|
|
346
|
-
|
|
347
|
-
|
|
340
|
+
</span>
|
|
341
|
+
<MultiSelect
|
|
342
|
+
key={config.table.pivot?.columnName}
|
|
343
|
+
options={groupPivotColumns
|
|
344
|
+
.filter(col => col !== config.table.pivot?.columnName && col !== config.table.groupBy)
|
|
345
|
+
.map(c => ({ label: c, value: c }))}
|
|
346
|
+
selected={config.table.pivot?.valueColumns}
|
|
347
|
+
label='Pivot Value Column(s) '
|
|
348
|
+
section='table'
|
|
349
|
+
subsection='pivot'
|
|
350
|
+
fieldName='valueColumns'
|
|
351
|
+
updateField={updateField}
|
|
352
|
+
/>
|
|
353
|
+
</label>
|
|
348
354
|
)}
|
|
349
355
|
</>
|
|
350
356
|
)
|
|
@@ -21,7 +21,7 @@ const FieldSet: React.FC<FieldSetProps> = ({ fieldName, fieldKey, fieldType, con
|
|
|
21
21
|
if (!show)
|
|
22
22
|
return (
|
|
23
23
|
<div className='mb-1'>
|
|
24
|
-
<button onClick={() => setShow(fieldKey, true)}>
|
|
24
|
+
<button className='btn btn-light' onClick={() => setShow(fieldKey, true)}>
|
|
25
25
|
<Icon display='caretDown' />
|
|
26
26
|
</button>
|
|
27
27
|
<span> {fieldName ? `${fieldName}` : 'New ' + fieldType}</span>
|
|
@@ -30,7 +30,7 @@ const FieldSet: React.FC<FieldSetProps> = ({ fieldName, fieldKey, fieldType, con
|
|
|
30
30
|
return (
|
|
31
31
|
<fieldset className='edit-block mb-1' key={fieldKey}>
|
|
32
32
|
<div className='d-flex justify-content-between'>
|
|
33
|
-
<button onClick={() => setShow(fieldKey, false)}>
|
|
33
|
+
<button className='btn btn-light' onClick={() => setShow(fieldKey, false)}>
|
|
34
34
|
<Icon display='caretUp' />
|
|
35
35
|
</button>
|
|
36
36
|
<button
|
|
@@ -31,16 +31,6 @@ export type CheckboxProps = {
|
|
|
31
31
|
} & Input &
|
|
32
32
|
Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value'>
|
|
33
33
|
|
|
34
|
-
export type SelectProps = {
|
|
35
|
-
value?: string
|
|
36
|
-
options?: string[]
|
|
37
|
-
required?: boolean
|
|
38
|
-
initial?: string
|
|
39
|
-
|
|
40
|
-
// all other props
|
|
41
|
-
[x: string]: any
|
|
42
|
-
} & Input
|
|
43
|
-
|
|
44
34
|
const TextField = memo((props: TextFieldProps) => {
|
|
45
35
|
const {
|
|
46
36
|
display = true,
|
|
@@ -141,6 +131,16 @@ const CheckBox = memo((props: CheckboxProps) => {
|
|
|
141
131
|
)
|
|
142
132
|
})
|
|
143
133
|
|
|
134
|
+
export type SelectProps = {
|
|
135
|
+
value?: string
|
|
136
|
+
options?: string[] | { label: string; value: string }[]
|
|
137
|
+
required?: boolean
|
|
138
|
+
initial?: string
|
|
139
|
+
|
|
140
|
+
// all other props
|
|
141
|
+
[x: string]: any
|
|
142
|
+
} & Input
|
|
143
|
+
|
|
144
144
|
const Select = memo((props: SelectProps) => {
|
|
145
145
|
const {
|
|
146
146
|
display = true,
|
|
@@ -156,11 +156,21 @@ const Select = memo((props: SelectProps) => {
|
|
|
156
156
|
initial: initialValue,
|
|
157
157
|
...attributes
|
|
158
158
|
} = props
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
159
|
+
const optionsJsx = options.map((option, index) => {
|
|
160
|
+
if (typeof option === 'string') {
|
|
161
|
+
return (
|
|
162
|
+
<option value={option} key={index}>
|
|
163
|
+
{option}
|
|
164
|
+
</option>
|
|
165
|
+
)
|
|
166
|
+
} else {
|
|
167
|
+
return (
|
|
168
|
+
<option value={option.value} key={index}>
|
|
169
|
+
{option.label}
|
|
170
|
+
</option>
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
})
|
|
164
174
|
|
|
165
175
|
if (initialValue) {
|
|
166
176
|
optionsJsx.unshift(
|
|
@@ -180,7 +190,7 @@ const Select = memo((props: SelectProps) => {
|
|
|
180
190
|
{tooltip}
|
|
181
191
|
</span>
|
|
182
192
|
<select
|
|
183
|
-
className={required && !value ? 'warning' : ''}
|
|
193
|
+
className={`cove-form-select ${required && !value ? 'warning' : ''}`}
|
|
184
194
|
name={fieldName}
|
|
185
195
|
value={value}
|
|
186
196
|
onChange={event => {
|
|
@@ -67,7 +67,12 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
67
67
|
|
|
68
68
|
const addNewFilter = () => {
|
|
69
69
|
const filters = config.filters ? [...config.filters] : []
|
|
70
|
-
const newVizFilter: VizFilter = {
|
|
70
|
+
const newVizFilter: VizFilter = {
|
|
71
|
+
values: [],
|
|
72
|
+
filterStyle: 'dropdown',
|
|
73
|
+
id: Date.now(),
|
|
74
|
+
showDropdown: true
|
|
75
|
+
} as VizFilter
|
|
71
76
|
filters.push(newVizFilter)
|
|
72
77
|
updateField(null, null, 'filters', filters)
|
|
73
78
|
}
|
|
@@ -125,6 +130,13 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
125
130
|
</Tooltip>
|
|
126
131
|
}
|
|
127
132
|
/>
|
|
133
|
+
<TextField
|
|
134
|
+
type='textarea'
|
|
135
|
+
label='Filter intro text'
|
|
136
|
+
value={config.filterIntro}
|
|
137
|
+
updateField={updateField}
|
|
138
|
+
fieldName='filterIntro'
|
|
139
|
+
/>
|
|
128
140
|
<br />
|
|
129
141
|
<ul className='filters-list'>
|
|
130
142
|
{/* Whether filters should apply onChange or Apply Button */}
|
|
@@ -140,43 +152,24 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
140
152
|
controls={openControls}
|
|
141
153
|
deleteField={() => removeFilter(filterIndex)}
|
|
142
154
|
>
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}}
|
|
151
|
-
>
|
|
152
|
-
{filterStyleOptions.map((item, index) => {
|
|
153
|
-
return (
|
|
154
|
-
<option key={`filter-style-${index}`} value={item}>
|
|
155
|
-
{item}
|
|
156
|
-
</option>
|
|
157
|
-
)
|
|
158
|
-
})}
|
|
159
|
-
</select>
|
|
160
|
-
</label>
|
|
155
|
+
<Select
|
|
156
|
+
value={filter.filterStyle}
|
|
157
|
+
fieldName='filterStyle'
|
|
158
|
+
label='Filter Style'
|
|
159
|
+
updateField={(_section, _subsection, _field, value) => updateFilterStyle(filterIndex, value)}
|
|
160
|
+
options={filterStyleOptions}
|
|
161
|
+
/>
|
|
161
162
|
|
|
162
163
|
{filter.filterStyle !== 'nested-dropdown' ? (
|
|
163
164
|
<>
|
|
164
|
-
<
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
<option value=''>- Select Option -</option>
|
|
173
|
-
{dataColumns.map((dataKey, filterIndex) => (
|
|
174
|
-
<option value={dataKey} key={filterIndex}>
|
|
175
|
-
{dataKey}
|
|
176
|
-
</option>
|
|
177
|
-
))}
|
|
178
|
-
</select>
|
|
179
|
-
</label>
|
|
165
|
+
<Select
|
|
166
|
+
value={filter.columnName}
|
|
167
|
+
fieldName='columnName'
|
|
168
|
+
label='Filter'
|
|
169
|
+
updateField={(_section, _subsection, _field, value) => handleNameChange(filterIndex, value)}
|
|
170
|
+
options={dataColumns}
|
|
171
|
+
initial='- Select Option -'
|
|
172
|
+
/>
|
|
180
173
|
|
|
181
174
|
<label>
|
|
182
175
|
<span className='edit-showDropdown column-heading'>Show Filter Input</span>
|
|
@@ -233,27 +226,21 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
|
|
|
233
226
|
/>
|
|
234
227
|
</label>
|
|
235
228
|
|
|
236
|
-
<
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
<FilterOrder
|
|
252
|
-
orderedValues={filter.orderedValues || filter.values}
|
|
253
|
-
handleFilterOrder={(index1, index2) => handleFilterOrder(index1, index2, filterIndex)}
|
|
254
|
-
/>
|
|
255
|
-
)}
|
|
256
|
-
</label>
|
|
229
|
+
<Select
|
|
230
|
+
value={filter.order || 'asc'}
|
|
231
|
+
fieldName='order'
|
|
232
|
+
label='Filter Order'
|
|
233
|
+
updateField={(_section, _subSection, _field, value) =>
|
|
234
|
+
updateFilterProp('order', filterIndex, value)
|
|
235
|
+
}
|
|
236
|
+
options={filterOrderOptions}
|
|
237
|
+
/>
|
|
238
|
+
{filter.order === 'cust' && (
|
|
239
|
+
<FilterOrder
|
|
240
|
+
orderedValues={filter.orderedValues || filter.values}
|
|
241
|
+
handleFilterOrder={(index1, index2) => handleFilterOrder(index1, index2, filterIndex)}
|
|
242
|
+
/>
|
|
243
|
+
)}
|
|
257
244
|
</>
|
|
258
245
|
) : (
|
|
259
246
|
<NestedDropdownEditor
|
|
@@ -249,9 +249,7 @@ export const useFilters = props => {
|
|
|
249
249
|
|
|
250
250
|
const filterConstants = {
|
|
251
251
|
buttonText: 'Apply Filters',
|
|
252
|
-
resetText: 'Reset All'
|
|
253
|
-
introText: `Make a selection from the filters to change the visualization information.`,
|
|
254
|
-
applyText: 'Select the apply button to update the visualization information.'
|
|
252
|
+
resetText: 'Reset All'
|
|
255
253
|
}
|
|
256
254
|
|
|
257
255
|
// prettier-ignore
|
|
@@ -351,7 +349,7 @@ const Filters = (props: FilterProps) => {
|
|
|
351
349
|
id={`filter-${outerIndex}`}
|
|
352
350
|
name={label}
|
|
353
351
|
aria-label={`Filter by ${label}`}
|
|
354
|
-
className='
|
|
352
|
+
className='cove-form-select'
|
|
355
353
|
data-index='0'
|
|
356
354
|
value={active}
|
|
357
355
|
onChange={e => {
|
|
@@ -439,6 +437,7 @@ const Filters = (props: FilterProps) => {
|
|
|
439
437
|
|
|
440
438
|
const classList = [
|
|
441
439
|
'single-filters',
|
|
440
|
+
'form-group mr-3',
|
|
442
441
|
mobileFilterStyle ? 'single-filters--dropdown' : `single-filters--${filterStyle}`
|
|
443
442
|
]
|
|
444
443
|
const mobileExempt = ['nested-dropdown', 'multi-select'].includes(filterStyle)
|
|
@@ -446,7 +445,11 @@ const Filters = (props: FilterProps) => {
|
|
|
446
445
|
return (
|
|
447
446
|
<div className={classList.join(' ')} key={outerIndex}>
|
|
448
447
|
<>
|
|
449
|
-
{label &&
|
|
448
|
+
{label && (
|
|
449
|
+
<label className='font-weight-bold mt-1 mb-0' htmlFor={`filter-${outerIndex}`}>
|
|
450
|
+
{label}
|
|
451
|
+
</label>
|
|
452
|
+
)}
|
|
450
453
|
{filterStyle === 'tab' && !mobileFilterStyle && Tabs}
|
|
451
454
|
{filterStyle === 'pill' && !mobileFilterStyle && Pills}
|
|
452
455
|
{filterStyle === 'tab bar' && !mobileFilterStyle && <TabBar filter={singleFilter} index={outerIndex} />}
|
|
@@ -463,6 +466,7 @@ const Filters = (props: FilterProps) => {
|
|
|
463
466
|
<NestedDropdown
|
|
464
467
|
activeGroup={(singleFilter.active as string) || (singleFilter.queuedActive || [])[0]}
|
|
465
468
|
activeSubGroup={(singleFilter.subGrouping?.active as string) || (singleFilter.queuedActive || [])[1]}
|
|
469
|
+
filterIndex={outerIndex}
|
|
466
470
|
options={getNestedOptions(singleFilter)}
|
|
467
471
|
listLabel={label}
|
|
468
472
|
handleSelectedItems={value => changeFilterActive(outerIndex, value)}
|
|
@@ -496,18 +500,19 @@ const Filters = (props: FilterProps) => {
|
|
|
496
500
|
|
|
497
501
|
return (
|
|
498
502
|
<section className={getClasses().join(' ')}>
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
<div className='filters-section__wrapper'>
|
|
503
|
+
{visualizationConfig.filterIntro && (
|
|
504
|
+
<p className='filters-section__intro-text'>{visualizationConfig.filterIntro}</p>
|
|
505
|
+
)}
|
|
506
|
+
<div className='d-flex flex-wrap w-100 filters-section__wrapper'>
|
|
504
507
|
{' '}
|
|
505
508
|
<>
|
|
506
509
|
<Style />
|
|
507
510
|
{filterBehavior === 'Apply Button' ? (
|
|
508
511
|
<div className='filters-section__buttons'>
|
|
509
512
|
<Button
|
|
510
|
-
onClick={
|
|
513
|
+
onClick={e => {
|
|
514
|
+
handleApplyButton(filters)
|
|
515
|
+
}}
|
|
511
516
|
disabled={!showApplyButton}
|
|
512
517
|
className={[general?.headerColor ? general.headerColor : theme, 'apply'].join(' ')}
|
|
513
518
|
>
|
|
@@ -15,20 +15,33 @@ type StandAloneProps = {
|
|
|
15
15
|
viewport?: ViewPort
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const FootnotesStandAlone: React.FC<StandAloneProps> = ({
|
|
18
|
+
const FootnotesStandAlone: React.FC<StandAloneProps> = ({
|
|
19
|
+
visualizationKey,
|
|
20
|
+
config,
|
|
21
|
+
viewport,
|
|
22
|
+
isEditor,
|
|
23
|
+
updateConfig
|
|
24
|
+
}) => {
|
|
19
25
|
const updateField = updateFieldFactory<Footnote[]>(config, updateConfig)
|
|
20
26
|
if (isEditor)
|
|
21
27
|
return (
|
|
22
|
-
<EditorWrapper
|
|
28
|
+
<EditorWrapper
|
|
29
|
+
component={FootnotesStandAlone}
|
|
30
|
+
visualizationKey={visualizationKey}
|
|
31
|
+
visualizationConfig={config}
|
|
32
|
+
updateConfig={updateConfig}
|
|
33
|
+
type={'Footnotes'}
|
|
34
|
+
viewport={viewport}
|
|
35
|
+
>
|
|
23
36
|
<FootnotesEditor key={visualizationKey} config={config} updateField={updateField} />
|
|
24
37
|
</EditorWrapper>
|
|
25
38
|
)
|
|
26
39
|
|
|
27
40
|
// get the api footnotes from the config
|
|
28
41
|
const apiFootnotes = useMemo(() => {
|
|
29
|
-
|
|
42
|
+
const configData = config.formattedData || config.data
|
|
43
|
+
if (configData && config.dataKey && config.dynamicFootnotes) {
|
|
30
44
|
const { symbolColumn, textColumn, orderColumn } = config.dynamicFootnotes
|
|
31
|
-
const configData = config.formattedData || config.data
|
|
32
45
|
const _data = configData.map(row => _.pick(row, [symbolColumn, textColumn, orderColumn]))
|
|
33
46
|
_data.sort((a, b) => a[orderColumn] - b[orderColumn])
|
|
34
47
|
return _data.map(row => ({ symbol: row[symbolColumn], text: row[textColumn] }))
|