@cdc/core 4.24.10 → 4.24.12-2

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 (70) hide show
  1. package/components/AdvancedEditor/AdvancedEditor.tsx +17 -13
  2. package/components/Alert/components/Alert.tsx +39 -8
  3. package/components/DataTable/DataTable.tsx +31 -10
  4. package/components/DataTable/DataTableStandAlone.tsx +3 -3
  5. package/components/DataTable/components/ExpandCollapse.tsx +1 -1
  6. package/components/DataTable/components/SortIcon/sort-icon.css +15 -0
  7. package/components/DataTable/data-table.css +4 -22
  8. package/components/DataTable/helpers/boxplotCellMatrix.tsx +19 -14
  9. package/components/DataTable/helpers/getChartCellValue.ts +25 -7
  10. package/components/EditorPanel/ColumnsEditor.tsx +81 -36
  11. package/components/EditorPanel/DataTableEditor.tsx +62 -56
  12. package/components/EditorPanel/FieldSetWrapper.tsx +2 -2
  13. package/components/EditorPanel/Inputs.tsx +26 -16
  14. package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +55 -56
  15. package/components/Filters/Filters.tsx +42 -38
  16. package/components/Filters/helpers/handleSorting.ts +5 -0
  17. package/components/Footnotes/FootnotesStandAlone.tsx +17 -4
  18. package/components/Layout/components/Sidebar/components/sidebar.styles.scss +0 -4
  19. package/components/Layout/components/Visualization/visualizations.scss +1 -1
  20. package/components/Legend/Legend.Gradient.tsx +50 -35
  21. package/components/Loader/Loader.tsx +10 -5
  22. package/components/MultiSelect/MultiSelect.tsx +56 -33
  23. package/components/MultiSelect/multiselect.styles.css +20 -7
  24. package/components/NestedDropdown/NestedDropdown.tsx +55 -32
  25. package/components/NestedDropdown/nesteddropdown.styles.css +26 -13
  26. package/components/Table/Table.tsx +102 -34
  27. package/components/Table/components/Row.tsx +1 -1
  28. package/components/_stories/DataTable.stories.tsx +14 -0
  29. package/components/_stories/Filters.stories.tsx +57 -0
  30. package/components/_stories/_mocks/DataTable/no-data.json +108 -0
  31. package/components/inputs/{InputToggle.jsx → InputToggle.tsx} +35 -29
  32. package/components/ui/Icon.tsx +19 -6
  33. package/dist/cove-main.css +26 -57
  34. package/dist/cove-main.css.map +1 -1
  35. package/helpers/DataTransform.ts +2 -1
  36. package/helpers/addValuesToFilters.ts +22 -8
  37. package/helpers/cove/{number.js → number.ts} +25 -11
  38. package/helpers/coveUpdateWorker.ts +1 -1
  39. package/helpers/fetchRemoteData.js +32 -37
  40. package/helpers/filterVizData.ts +2 -2
  41. package/helpers/formatConfigBeforeSave.ts +16 -0
  42. package/helpers/gatherQueryParams.ts +2 -3
  43. package/helpers/queryStringUtils.ts +16 -1
  44. package/helpers/tests/addValuesToFilters.test.ts +6 -1
  45. package/helpers/useDataVizClasses.ts +44 -21
  46. package/helpers/ver/4.24.10.ts +12 -0
  47. package/helpers/ver/versionNeedsUpdate.ts +2 -0
  48. package/helpers/viewports.ts +8 -7
  49. package/package.json +2 -2
  50. package/styles/_button-section.scss +1 -1
  51. package/styles/_global-variables.scss +9 -4
  52. package/styles/_global.scss +21 -22
  53. package/styles/_reset.scss +0 -12
  54. package/styles/filters.scss +0 -22
  55. package/styles/v2/base/_reset.scss +0 -7
  56. package/styles/v2/components/editor.scss +0 -4
  57. package/styles/v2/components/icon.scss +1 -1
  58. package/types/Axis.ts +2 -0
  59. package/types/BoxPlot.ts +5 -3
  60. package/types/Color.ts +1 -1
  61. package/types/Legend.ts +1 -2
  62. package/types/MarkupInclude.ts +1 -0
  63. package/types/Runtime.ts +3 -1
  64. package/types/Series.ts +8 -1
  65. package/types/Table.ts +1 -1
  66. package/types/Version.ts +1 -0
  67. package/types/Visualization.ts +7 -8
  68. package/types/VizFilter.ts +2 -1
  69. package/components/ui/Select.jsx +0 -30
  70. 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
- <MultiSelect
200
- key={excludedColumns.join('') + 'excluded'}
201
- options={dataColumns.map(c => ({ label: c, value: c }))}
202
- selected={excludedColumns}
203
- fieldName='dataTable'
204
- label='Exclude Columns'
205
- section='columns'
206
- updateField={excludeColumns}
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
- {config.type !== 'table' && (
253
- <CheckBox
254
- value={config.table.showDownloadLinkBelow}
255
- fieldName='showDownloadLinkBelow'
256
- label='Show Download Link Below Table'
257
- section='table'
258
- updateField={updateField}
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
- <label>
271
- <span className='edit-label column-heading'>
272
- Group By{' '}
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
- </span>
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 && col !== config.table.pivot?.valueColumn
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
- <MultiSelect
327
- key={config.table.pivot?.columnName}
328
- options={groupPivotColumns
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
- let optionsJsx = options.map((optionName, index) => (
160
- <option value={optionName} key={index}>
161
- {optionName}
162
- </option>
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 = { values: [], filterStyle: 'dropdown', id: Date.now() } as 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
- <label>
144
- <span className='edit-label column-heading'>Filter Style</span>
145
-
146
- <select
147
- value={filter.filterStyle || 'dropdown'}
148
- onChange={e => {
149
- updateFilterStyle(filterIndex, e.target.value)
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
- <label>
165
- <span className='edit-label column-heading'>Filter</span>
166
- <select
167
- value={filter.columnName}
168
- onChange={e => {
169
- handleNameChange(filterIndex, e.target.value)
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,32 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
233
226
  />
234
227
  </label>
235
228
 
236
- <label>
237
- <span className='edit-filterOrder column-heading'>Filter Order</span>
238
- <select
239
- value={filter.order ? filter.order : 'asc'}
240
- onChange={e => updateFilterProp('order', filterIndex, e.target.value)}
241
- >
242
- {filterOrderOptions.map((option, index) => {
243
- return (
244
- <option value={option.value} key={`filter-${index}`}>
245
- {option.label}
246
- </option>
247
- )
248
- })}
249
- </select>
250
- {filter.order === 'cust' && (
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
+ )}
244
+ {filter.order === 'column' && (
245
+ <Select
246
+ value={filter.orderColumn}
247
+ fieldName='orderColumn'
248
+ label='Order Column'
249
+ updateField={(_section, _subSection, _field, value) =>
250
+ updateFilterProp('orderColumn', filterIndex, value)
251
+ }
252
+ options={dataColumns}
253
+ />
254
+ )}
257
255
  </>
258
256
  ) : (
259
257
  <NestedDropdownEditor
@@ -287,6 +285,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
287
285
  updateFilterProp('parents', filterIndex, value)
288
286
  }}
289
287
  options={getParentFilterOptions(filterIndex)}
288
+ selected={config.filters[filterIndex].parents}
290
289
  />
291
290
  </label>
292
291
  </FieldSetWrapper>
@@ -41,18 +41,25 @@ export const filterOrderOptions: { label: string; value: OrderBy }[] = [
41
41
  {
42
42
  label: 'Custom',
43
43
  value: 'cust'
44
- }
44
+ },
45
+ { label: 'Order By Data Column', value: 'column' }
45
46
  ]
46
47
 
47
- const hasStandardFilterBehavior = ['chart', 'table']
48
-
49
48
  export const useFilters = props => {
50
49
  const [showApplyButton, setShowApplyButton] = useState(false)
51
50
 
52
51
  // Desconstructing: notice, adding more descriptive visualizationConfig name over config
53
52
  // visualizationConfig feels more robust for all vis types so that its not confused with config/state/etc.
54
- const { config: visualizationConfig, setConfig, filteredData, setFilteredData, excludedData, getUniqueValues } = props
55
- const { type, data } = visualizationConfig
53
+ const {
54
+ config: visualizationConfig,
55
+ setConfig,
56
+ filteredData,
57
+ setFilteredData,
58
+ excludedData,
59
+ getUniqueValues,
60
+ standaloneMap
61
+ } = props
62
+ const { data } = visualizationConfig
56
63
 
57
64
  /**
58
65
  * Re-orders a filter based on two indices and updates the runtime filters array and filters state
@@ -72,9 +79,7 @@ export const useFilters = props => {
72
79
  const [movedItem] = updatedValues.splice(idx1, 1)
73
80
  updatedValues.splice(idx2, 0, movedItem)
74
81
 
75
- const filtersCopy = hasStandardFilterBehavior.includes(visualizationConfig.type)
76
- ? [...visualizationConfig.filters]
77
- : [...filteredData]
82
+ const filtersCopy = !standaloneMap ? [...visualizationConfig.filters] : [...filteredData]
78
83
  const filterItem = { ...filtersCopy[filterIndex] }
79
84
 
80
85
  // Overwrite filterItem.values since thats what we map through in the editor panel
@@ -86,7 +91,7 @@ export const useFilters = props => {
86
91
  // Update the filters
87
92
  filtersCopy[filterIndex] = filterItem
88
93
 
89
- if (visualizationConfig.type === 'map') {
94
+ if (standaloneMap) {
90
95
  setFilteredData(filtersCopy)
91
96
  }
92
97
 
@@ -94,7 +99,7 @@ export const useFilters = props => {
94
99
  }
95
100
 
96
101
  const changeFilterActive = (index, value) => {
97
- let newFilters = visualizationConfig.type === 'map' ? [...filteredData] : [...visualizationConfig.filters]
102
+ let newFilters = standaloneMap ? [...filteredData] : [...visualizationConfig.filters]
98
103
 
99
104
  if (visualizationConfig.filterBehavior === 'Apply Button') {
100
105
  newFilters[index].queuedActive = value
@@ -120,7 +125,7 @@ export const useFilters = props => {
120
125
  queryParams[newFilter?.subGrouping?.setByQueryParameter] = newFilter.subGrouping.active
121
126
  updateQueryString(queryParams)
122
127
  }
123
- setFilteredData(newFilters[index])
128
+ setFilteredData(newFilters)
124
129
  }
125
130
 
126
131
  if (!visualizationConfig.dynamicSeries) {
@@ -132,15 +137,12 @@ export const useFilters = props => {
132
137
  }
133
138
 
134
139
  // Used for setting active filter, fromHash breaks the filteredData functionality.
135
- if (visualizationConfig.type === 'map' && visualizationConfig.filterBehavior === 'Filter Change') {
140
+ if (standaloneMap && visualizationConfig.filterBehavior === 'Filter Change') {
136
141
  setFilteredData(newFilters)
137
142
  }
138
143
 
139
144
  // If we're on a chart and not using the apply button
140
- if (
141
- hasStandardFilterBehavior.includes(visualizationConfig.type) &&
142
- visualizationConfig.filterBehavior === 'Filter Change'
143
- ) {
145
+ if (!standaloneMap && visualizationConfig.filterBehavior === 'Filter Change') {
144
146
  const newFilteredData = filterVizData(newFilters, excludedData)
145
147
  setFilteredData(newFilteredData)
146
148
 
@@ -204,11 +206,9 @@ export const useFilters = props => {
204
206
 
205
207
  setConfig({ ...visualizationConfig, filters: newFilters })
206
208
 
207
- if (type === 'map') {
209
+ if (standaloneMap) {
208
210
  setFilteredData(newFilters, excludedData)
209
- }
210
-
211
- if (hasStandardFilterBehavior.includes(visualizationConfig.type)) {
211
+ } else {
212
212
  setFilteredData(filterVizData(newFilters, excludedData))
213
213
  }
214
214
 
@@ -240,7 +240,7 @@ export const useFilters = props => {
240
240
 
241
241
  setConfig({ ...visualizationConfig, filters: newFilters })
242
242
 
243
- if (type === 'map') {
243
+ if (standaloneMap) {
244
244
  setFilteredData(newFilters, excludedData)
245
245
  } else {
246
246
  setFilteredData(filterVizData(newFilters, excludedData))
@@ -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
@@ -276,13 +274,12 @@ type FilterProps = {
276
274
  setFilteredData: Function
277
275
  // updating function for setting fitlerBehavior
278
276
  setConfig: Function
279
- // exclusions
280
- exclusions: any[]
277
+ standaloneMap?: boolean
281
278
  }
282
279
 
283
280
  const Filters = (props: FilterProps) => {
284
- const { config: visualizationConfig, filteredData, dimensions } = props
285
- const { filters, type, general, theme, filterBehavior } = visualizationConfig
281
+ const { config: visualizationConfig, filteredData, dimensions, standaloneMap } = props
282
+ const { filters, general, theme, filterBehavior } = visualizationConfig
286
283
  const [mobileFilterStyle, setMobileFilterStyle] = useState(false)
287
284
  const [selectedFilter, setSelectedFilter] = useState<EventTarget>(null)
288
285
  const id = useId()
@@ -351,7 +348,7 @@ const Filters = (props: FilterProps) => {
351
348
  id={`filter-${outerIndex}`}
352
349
  name={label}
353
350
  aria-label={`Filter by ${label}`}
354
- className='filter-select'
351
+ className='cove-form-select'
355
352
  data-index='0'
356
353
  value={active}
357
354
  onChange={e => {
@@ -365,7 +362,7 @@ const Filters = (props: FilterProps) => {
365
362
 
366
363
  const vizFiltersWithValues = useMemo(() => {
367
364
  // Here charts is using config.filters where maps is using a runtime value
368
- let vizfilters = type === 'map' ? filteredData : filters
365
+ let vizfilters = standaloneMap ? filteredData : filters
369
366
  if (!vizfilters) return []
370
367
  if (vizfilters.fromHash) delete vizfilters.fromHash // support for Maps config
371
368
  return addValuesToFilters(vizfilters as VizFilter[], visualizationConfig.data)
@@ -439,6 +436,7 @@ const Filters = (props: FilterProps) => {
439
436
 
440
437
  const classList = [
441
438
  'single-filters',
439
+ 'form-group mr-3',
442
440
  mobileFilterStyle ? 'single-filters--dropdown' : `single-filters--${filterStyle}`
443
441
  ]
444
442
  const mobileExempt = ['nested-dropdown', 'multi-select'].includes(filterStyle)
@@ -446,7 +444,11 @@ const Filters = (props: FilterProps) => {
446
444
  return (
447
445
  <div className={classList.join(' ')} key={outerIndex}>
448
446
  <>
449
- {label && <label htmlFor={`filter-${outerIndex}`}>{label}</label>}
447
+ {label && (
448
+ <label className='font-weight-bold mt-1 mb-0' htmlFor={`filter-${outerIndex}`}>
449
+ {label}
450
+ </label>
451
+ )}
450
452
  {filterStyle === 'tab' && !mobileFilterStyle && Tabs}
451
453
  {filterStyle === 'pill' && !mobileFilterStyle && Pills}
452
454
  {filterStyle === 'tab bar' && !mobileFilterStyle && <TabBar filter={singleFilter} index={outerIndex} />}
@@ -463,6 +465,7 @@ const Filters = (props: FilterProps) => {
463
465
  <NestedDropdown
464
466
  activeGroup={(singleFilter.active as string) || (singleFilter.queuedActive || [])[0]}
465
467
  activeSubGroup={(singleFilter.subGrouping?.active as string) || (singleFilter.queuedActive || [])[1]}
468
+ filterIndex={outerIndex}
466
469
  options={getNestedOptions(singleFilter)}
467
470
  listLabel={label}
468
471
  handleSelectedItems={value => changeFilterActive(outerIndex, value)}
@@ -488,7 +491,7 @@ const Filters = (props: FilterProps) => {
488
491
  const getClasses = () => {
489
492
  const { visualizationType, legend } = visualizationConfig || {}
490
493
  const baseClass = 'filters-section'
491
- const conditionalClass = type === 'map' ? general.headerColor : visualizationType === 'Spark Line' ? null : theme
494
+ const conditionalClass = standaloneMap ? general.headerColor : visualizationType === 'Spark Line' ? null : theme
492
495
  const legendClass = legend && !legend.hide && legend.position === 'top' ? 'mb-0' : null
493
496
 
494
497
  return [baseClass, conditionalClass, legendClass].filter(Boolean)
@@ -496,18 +499,19 @@ const Filters = (props: FilterProps) => {
496
499
 
497
500
  return (
498
501
  <section className={getClasses().join(' ')}>
499
- <p className='filters-section__intro-text'>
500
- {filters?.some(filter => filter.active && filter.columnName) ? filterConstants.introText : ''}{' '}
501
- {visualizationConfig.filterBehavior === 'Apply Button' && filterConstants.applyText}
502
- </p>
503
- <div className='filters-section__wrapper'>
502
+ {visualizationConfig.filterIntro && (
503
+ <p className='filters-section__intro-text'>{visualizationConfig.filterIntro}</p>
504
+ )}
505
+ <div className='d-flex flex-wrap w-100 filters-section__wrapper'>
504
506
  {' '}
505
507
  <>
506
508
  <Style />
507
509
  {filterBehavior === 'Apply Button' ? (
508
510
  <div className='filters-section__buttons'>
509
511
  <Button
510
- onClick={() => handleApplyButton(filters)}
512
+ onClick={e => {
513
+ handleApplyButton(filters)
514
+ }}
511
515
  disabled={!showApplyButton}
512
516
  className={[general?.headerColor ? general.headerColor : theme, 'apply'].join(' ')}
513
517
  >
@@ -7,6 +7,11 @@ export const handleSorting = singleFilter => {
7
7
  return singleFilter
8
8
  }
9
9
 
10
+ if (singleFilter.order === 'column') {
11
+ // sorting is done in the generateValuesForFilter function
12
+ return singleFilter
13
+ }
14
+
10
15
  const sort = (a, b) => {
11
16
  const asc = singleFilter.order !== 'desc'
12
17
  return String(asc ? a : b).localeCompare(String(asc ? b : a), 'en', { numeric: true })