@cdc/core 4.24.5 → 4.24.7

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 (66) hide show
  1. package/components/AdvancedEditor/AdvancedEditor.tsx +93 -0
  2. package/components/AdvancedEditor/advanced-editor-styles.css +3 -0
  3. package/components/AdvancedEditor/index.ts +1 -0
  4. package/components/DataTable/DataTable.tsx +21 -2
  5. package/components/DataTable/DataTableStandAlone.tsx +4 -25
  6. package/components/DataTable/components/DataTableEditorPanel.tsx +4 -4
  7. package/components/DataTable/components/ExpandCollapse.tsx +1 -1
  8. package/components/DataTable/helpers/chartCellMatrix.tsx +3 -9
  9. package/components/DataTable/helpers/getChartCellValue.ts +8 -4
  10. package/components/DataTable/helpers/getDataSeriesColumns.ts +8 -5
  11. package/components/DataTable/helpers/getRowType.ts +6 -0
  12. package/components/DataTable/types/TableConfig.ts +1 -0
  13. package/components/EditorPanel/ColumnsEditor.tsx +3 -30
  14. package/components/EditorPanel/DataTableEditor.tsx +66 -22
  15. package/components/EditorPanel/FieldSetWrapper.tsx +51 -0
  16. package/components/EditorPanel/FootnotesEditor.tsx +77 -0
  17. package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +227 -0
  18. package/components/EditorPanel/VizFilterEditor/components/FilterOrder.tsx +54 -0
  19. package/components/EditorPanel/VizFilterEditor/index.ts +1 -0
  20. package/components/EditorWrapper/EditorWrapper.tsx +3 -4
  21. package/components/EditorWrapper/index.ts +1 -0
  22. package/components/{Filters.jsx → Filters.tsx} +40 -24
  23. package/components/Footnotes/Footnotes.tsx +25 -0
  24. package/components/Footnotes/FootnotesStandAlone.tsx +45 -0
  25. package/components/Footnotes/footnotes.css +5 -0
  26. package/components/Footnotes/index.ts +1 -0
  27. package/components/Layout/components/Sidebar/components/sidebar.styles.scss +8 -4
  28. package/components/Layout/components/Visualization/index.tsx +12 -5
  29. package/components/MultiSelect/MultiSelect.tsx +36 -9
  30. package/components/MultiSelect/multiselect.styles.css +0 -3
  31. package/components/_stories/Footnotes.stories.tsx +17 -0
  32. package/components/_stories/styles.scss +1 -0
  33. package/components/inputs/InputSelect.tsx +17 -6
  34. package/components/ui/Icon.tsx +1 -2
  35. package/helpers/addValuesToFilters.ts +56 -0
  36. package/helpers/cove/accessibility.ts +1 -0
  37. package/helpers/cove/fontSettings.ts +2 -0
  38. package/helpers/coveUpdateWorker.ts +7 -0
  39. package/helpers/filterVizData.ts +30 -0
  40. package/helpers/formatConfigBeforeSave.ts +90 -0
  41. package/helpers/gatherQueryParams.ts +14 -7
  42. package/helpers/lineChartHelpers.js +2 -1
  43. package/helpers/pivotData.ts +18 -0
  44. package/helpers/queryStringUtils.ts +29 -0
  45. package/helpers/tests/updateFieldFactory.test.ts +1 -0
  46. package/helpers/updateFieldFactory.ts +1 -1
  47. package/helpers/ver/4.24.7.ts +92 -0
  48. package/package.json +6 -4
  49. package/styles/_button-section.scss +6 -1
  50. package/styles/_data-table.scss +0 -1
  51. package/styles/base.scss +4 -0
  52. package/styles/v2/themes/_color-definitions.scss +1 -0
  53. package/types/Annotation.ts +46 -0
  54. package/types/Axis.ts +0 -2
  55. package/types/ConfigureData.ts +1 -1
  56. package/types/Footnotes.ts +17 -0
  57. package/types/General.ts +5 -0
  58. package/types/Runtime.ts +2 -7
  59. package/types/Table.ts +6 -0
  60. package/types/Visualization.ts +31 -9
  61. package/types/VizFilter.ts +16 -5
  62. package/LICENSE +0 -201
  63. package/components/AdvancedEditor.jsx +0 -74
  64. package/components/EditorPanel/VizFilterEditor.tsx +0 -234
  65. package/helpers/queryStringUtils.js +0 -26
  66. package/types/BaseVisualizationType.ts +0 -1
@@ -1,234 +0,0 @@
1
- import { AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
2
- import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'
3
- import { Select } from './Inputs'
4
- import Tooltip from '../ui/Tooltip'
5
- import Icon from '../ui/Icon'
6
- import { Visualization } from '../../types/Visualization'
7
- import { UpdateFieldFunc } from '../../types/UpdateFieldFunc'
8
- import _ from 'lodash'
9
- import { VizFilter } from '../../types/VizFilter'
10
- import { filterStyleOptions, filterOrderOptions, handleSorting } from '../Filters'
11
-
12
- type VizFilterProps = {
13
- config: Visualization
14
- updateField: UpdateFieldFunc<string | VizFilter[] | VizFilter>
15
- rawData: Object[]
16
- }
17
-
18
- const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawData }) => {
19
- const getFilters = () => {
20
- return _.uniq(_.flatten(rawData.map(row => Object.keys(row))))
21
- }
22
- const removeFilter = index => {
23
- let filters = _.cloneDeep(config.filters)
24
-
25
- filters.splice(index, 1)
26
-
27
- updateField(null, null, 'filters', filters)
28
- }
29
-
30
- const updateFilterProp = (prop, index, value) => {
31
- updateField('filters', index, prop, value)
32
- }
33
-
34
- const handleNameChange = (filterIndex, columnName) => {
35
- const values = _.uniq(rawData.map(row => row[columnName]))
36
- const copiedFilter = { ..._.cloneDeep(config.filters[filterIndex]), columnName, values }
37
- handleSorting(copiedFilter) // sorts dropdown values in place
38
- copiedFilter.active = copiedFilter.values[0]
39
- const newFilters = config.filters.map((filter, index) => {
40
- if (index === filterIndex) return copiedFilter
41
- return filter
42
- })
43
- updateField(null, null, 'filters', newFilters)
44
- }
45
-
46
- const addNewFilter = () => {
47
- const filters = config.filters ? [...config.filters] : []
48
- const newVizFilter: VizFilter = { values: [], filterStyle: 'dropdown' } as VizFilter
49
- filters.push(newVizFilter)
50
- updateField(null, null, 'filters', filters)
51
- }
52
-
53
- const handleFilterOrder = (idx1, idx2, filterIndex, filter) => {
54
- // Create a shallow copy of the filter values array & update position of the values
55
- const updatedValues = [...filter.values]
56
- const [movedItem] = updatedValues.splice(idx1, 1)
57
- updatedValues.splice(idx2, 0, movedItem)
58
-
59
- const filtersCopy = _.cloneDeep(config.filters)
60
- const filterItem = { ...filtersCopy[filterIndex] }
61
-
62
- // Overwrite filterItem.values since thats what we map through in the editor panel
63
- filterItem.values = updatedValues
64
- filterItem.orderedValues = updatedValues
65
- filterItem.active = updatedValues[0]
66
- filterItem.order = 'cust'
67
-
68
- // Update the filters
69
- filtersCopy[filterIndex] = filterItem
70
-
71
- updateField(null, null, 'filters', filtersCopy)
72
- }
73
-
74
- return (
75
- <>
76
- {config.filters && (
77
- <>
78
- <Select
79
- value={config.filterBehavior}
80
- fieldName='filterBehavior'
81
- label='Filter Behavior'
82
- updateField={updateField}
83
- options={['Apply Button', 'Filter Change']}
84
- tooltip={
85
- <Tooltip style={{ textTransform: 'none' }}>
86
- <Tooltip.Target>
87
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
88
- </Tooltip.Target>
89
- <Tooltip.Content>
90
- <p>The Apply Button option changes the visualization when the user clicks "apply". The Filter Change option immediately changes the visualization when the selection is changed.</p>
91
- </Tooltip.Content>
92
- </Tooltip>
93
- }
94
- />
95
- <br />
96
- </>
97
- )}
98
- {config.filters && (
99
- <ul className='filters-list'>
100
- {/* Whether filters should apply onChange or Apply Button */}
101
-
102
- {config.filters.map((filter, index) => {
103
- if (filter.type === 'url') return <></>
104
-
105
- return (
106
- <fieldset className='edit-block' key={index}>
107
- <button
108
- type='button'
109
- className='remove-column'
110
- onClick={() => {
111
- removeFilter(index)
112
- }}
113
- >
114
- Remove
115
- </button>
116
- <label>
117
- <span className='edit-label column-heading'>Filter</span>
118
- <select
119
- value={filter.columnName}
120
- onChange={e => {
121
- handleNameChange(index, e.target.value)
122
- }}
123
- >
124
- <option value=''>- Select Option -</option>
125
- {getFilters().map((dataKey, index) => (
126
- <option value={dataKey} key={index}>
127
- {dataKey}
128
- </option>
129
- ))}
130
- </select>
131
- </label>
132
-
133
- <label>
134
- <span className='edit-showDropdown column-heading'>Show Filter Input</span>
135
- <input
136
- type='checkbox'
137
- checked={filter.showDropdown === undefined ? true : filter.showDropdown}
138
- onChange={e => {
139
- updateFilterProp('showDropdown', index, e.target.checked)
140
- }}
141
- />
142
- </label>
143
-
144
- <label>
145
- <span className='edit-label column-heading'>Filter Style</span>
146
-
147
- <select
148
- value={filter.filterStyle}
149
- onChange={e => {
150
- updateFilterProp('filterStyle', index, e.target.value)
151
- }}
152
- >
153
- {filterStyleOptions.map((item, index) => {
154
- return (
155
- <option key={`filter-style-${index}`} value={item}>
156
- {item}
157
- </option>
158
- )
159
- })}
160
- </select>
161
- </label>
162
- <label>
163
- <span className='edit-label column-heading'>Label</span>
164
- <input
165
- type='text'
166
- value={filter.label}
167
- onChange={e => {
168
- updateFilterProp('label', index, e.target.value)
169
- }}
170
- />
171
- </label>
172
-
173
- <label>
174
- <span className='edit-label column-heading'>Default Value Set By Query String Parameter</span>
175
- <input
176
- type='text'
177
- value={filter.setByQueryParameter}
178
- onChange={e => {
179
- updateFilterProp('setByQueryParameter', index, e.target.value)
180
- }}
181
- />
182
- </label>
183
-
184
- <label>
185
- <span className='edit-filterOrder column-heading'>Filter Order</span>
186
- <select value={filter.order ? filter.order : 'asc'} onChange={e => updateFilterProp('order', index, e.target.value)}>
187
- {filterOrderOptions.map((option, index) => {
188
- return (
189
- <option value={option.value} key={`filter-${index}`}>
190
- {option.label}
191
- </option>
192
- )
193
- })}
194
- </select>
195
-
196
- {filter.order === 'cust' && (
197
- <DragDropContext onDragEnd={({ source, destination }) => handleFilterOrder(source.index, destination.index, index, config.filters[index])}>
198
- <Droppable droppableId='filter_order'>
199
- {provided => (
200
- <ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
201
- {config.filters[index]?.values.map((value, index) => {
202
- return (
203
- <Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
204
- {(provided, snapshot) => (
205
- <li>
206
- <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={provided.draggableProps.style} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
207
- {value}
208
- </div>
209
- </li>
210
- )}
211
- </Draggable>
212
- )
213
- })}
214
- {provided.placeholder}
215
- </ul>
216
- )}
217
- </Droppable>
218
- </DragDropContext>
219
- )}
220
- </label>
221
- </fieldset>
222
- )
223
- })}
224
- </ul>
225
- )}
226
- {!config.filters && <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
227
- <button type='button' onClick={addNewFilter} className='btn btn-primary full-width'>
228
- Add Filter
229
- </button>
230
- </>
231
- )
232
- }
233
-
234
- export default VizFilterEditor
@@ -1,26 +0,0 @@
1
- export function getQueryStringFilterValue(filter) {
2
- const urlParams = new URLSearchParams(window.location.search)
3
- if(filter.setByQueryParameter){ // Only check the query string if the filter is supposed to be set by QS param
4
- const filterValue = urlParams.get(filter.setByQueryParameter)
5
- if(filterValue && filter.values){
6
- for(let i = 0; i < filter.values.length; i++){
7
- if(filter.values[i] && filter.values[i].toLowerCase() === filterValue.toLowerCase()){
8
- return filter.values[i]
9
- }
10
- }
11
- }
12
- }
13
- }
14
-
15
- export function getQueryParams(filter) {
16
- const queryParams = {};
17
- for (const [key, value] of (new URLSearchParams(window.location.search)).entries()) {
18
- queryParams[key] = value
19
- }
20
- return queryParams;
21
- }
22
-
23
- export function updateQueryString(queryParams) {
24
- const updateUrl = `${window.location.origin}${window.location.pathname}?${Object.keys(queryParams).map(queryParam => `${queryParam}=${encodeURIComponent(queryParams[queryParam])}`).join('&')}`;
25
- window.history.pushState({path: updateUrl}, '', updateUrl);
26
- }
@@ -1 +0,0 @@
1
- export type BaseVisualizationType = 'dashboard' | 'chart' | 'map' | 'data-bite' | 'waffle-chart' | 'markup-include' | 'filtered-text' | 'filter-dropdowns' | 'table' | 'navigation'