@cdc/markup-include 4.25.8 → 4.25.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/markup-include",
3
- "version": "4.25.8",
3
+ "version": "4.25.10",
4
4
  "description": "React component for displaying HTML content from an outside link",
5
5
  "moduleName": "CdcMarkupInclude",
6
6
  "main": "dist/cdcmarkupinclude",
@@ -27,15 +27,23 @@
27
27
  "license": "Apache-2.0",
28
28
  "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
29
29
  "dependencies": {
30
- "@cdc/core": "^4.25.8",
30
+ "@cdc/core": "^4.25.10",
31
31
  "axios": "^1.9.0",
32
32
  "chroma": "0.0.1",
33
33
  "interweave": "^13.1.1",
34
+ "lodash": "^4.17.21",
34
35
  "react-accessible-accordion": "^5.0.1"
35
36
  },
36
37
  "peerDependencies": {
37
38
  "react": "^18.2.0",
38
39
  "react-dom": "^18.2.0"
39
40
  },
40
- "gitHead": "e369994230b5e3facff224e1d89d5937528ac5a0"
41
+ "devDependencies": {
42
+ "@rollup/plugin-dsv": "^3.0.2",
43
+ "@vitejs/plugin-react": "^4.3.4",
44
+ "vite": "^4.4.11",
45
+ "vite-plugin-css-injected-by-js": "^2.4.0",
46
+ "vite-plugin-svgr": "^2.4.0"
47
+ },
48
+ "gitHead": "c2db758e74ab9b9ca1667a6f9cb41dd0dccf985d"
41
49
  }
@@ -7,6 +7,8 @@ import axios from 'axios'
7
7
  // cdc
8
8
  import { MarkupIncludeConfig } from '@cdc/core/types/MarkupInclude'
9
9
  import { publish } from '@cdc/core/helpers/events'
10
+ import { processMarkupVariables } from '@cdc/core/helpers/markupProcessor'
11
+ import { addValuesToFilters } from '@cdc/core/helpers/addValuesToFilters'
10
12
  import ConfigContext from './ConfigContext'
11
13
  import coveUpdateWorker from '@cdc/core/helpers/coveUpdateWorker'
12
14
  import EditorPanel from '../src/components/EditorPanel'
@@ -14,6 +16,7 @@ import defaults from './data/initial-state'
14
16
 
15
17
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
16
18
  import Loading from '@cdc/core/components/Loading'
19
+ import Filters from '@cdc/core/components/Filters'
17
20
  import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
18
21
  import markupIncludeReducer from './store/markupInclude.reducer'
19
22
  import Layout from '@cdc/core/components/Layout'
@@ -28,12 +31,13 @@ type CdcMarkupIncludeProps = {
28
31
  isDashboard: boolean
29
32
  isEditor: boolean
30
33
  setConfig: any
34
+ interactionLabel?: string
31
35
  }
32
36
 
33
37
  import Title from '@cdc/core/components/ui/Title'
34
38
  import FootnotesStandAlone from '@cdc/core/components/Footnotes/FootnotesStandAlone'
35
39
  import { Datasets } from '@cdc/core/types/DataSet'
36
- import { publishAnalyticsEvent } from '@cdc/core/helpers/metrics/helpers'
40
+ import { VizFilter } from '@cdc/core/types/VizFilter'
37
41
 
38
42
  const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
39
43
  configUrl,
@@ -41,7 +45,8 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
41
45
  datasets,
42
46
  isDashboard = true,
43
47
  isEditor = false,
44
- setConfig: setParentConfig
48
+ setConfig: setParentConfig,
49
+ interactionLabel = 'no link provided'
45
50
  }) => {
46
51
  const initialState = {
47
52
  config: configObj,
@@ -61,10 +66,18 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
61
66
 
62
67
  const { innerContainerClasses, contentClasses } = useDataVizClasses(config || {})
63
68
  const { contentEditor, theme } = config || {}
64
- const { showNoDataMessage, allowHideSection, noDataMessageText } = contentEditor || {}
69
+ const {
70
+ showNoDataMessage,
71
+ allowHideSection,
72
+ noDataMessageText,
73
+ markupVariables: contentEditorMarkupVariables
74
+ } = contentEditor || {}
65
75
  const data = configObj?.data
66
76
 
67
- const { inlineHTML, markupVariables, srcUrl, title, useInlineHTML } = contentEditor || {}
77
+ // Support markupVariables at root level or inside contentEditor
78
+ const markupVariables = config?.markupVariables || contentEditorMarkupVariables || []
79
+
80
+ const { inlineHTML, srcUrl, title, useInlineHTML } = contentEditor || {}
68
81
 
69
82
  // Default Functions
70
83
  const updateConfig = newConfig => {
@@ -81,6 +94,15 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
81
94
  dispatch({ type: 'SET_CONFIG', payload: newConfig })
82
95
  }
83
96
 
97
+ const setFilters = (newFilters: VizFilter[]) => {
98
+ const _newFilters = addValuesToFilters(newFilters, data || [])
99
+ const updatedConfig = {
100
+ ...config,
101
+ filters: _newFilters
102
+ }
103
+ dispatch({ type: 'SET_CONFIG', payload: updatedConfig })
104
+ }
105
+
84
106
  const loadConfig = async () => {
85
107
  let response = configObj || (await (await fetch(configUrl)).json())
86
108
  let responseData = response.data ?? {}
@@ -93,6 +115,11 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
93
115
  response.data = responseData
94
116
  const processedConfig = { ...coveUpdateWorker(response) }
95
117
 
118
+ // Add filter values if filters are present
119
+ if (processedConfig.filters && processedConfig.filters.length > 0) {
120
+ processedConfig.filters = addValuesToFilters(processedConfig.filters, responseData)
121
+ }
122
+
96
123
  updateConfig({ ...configObj, ...processedConfig })
97
124
  dispatch({ type: 'SET_LOADING', payload: false })
98
125
  }
@@ -155,71 +182,6 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
155
182
  }
156
183
  }
157
184
 
158
- const filterOutConditions = (workingData, conditionList) => {
159
- const { columnName, isOrIsNotEqualTo, value } = conditionList[0]
160
-
161
- const newWorkingData =
162
- isOrIsNotEqualTo === 'is'
163
- ? workingData?.filter(dataObject => dataObject[columnName] === value)
164
- : workingData?.filter(dataObject => dataObject[columnName] !== value)
165
-
166
- conditionList.shift()
167
- return conditionList.length === 0 ? newWorkingData : filterOutConditions(newWorkingData, conditionList)
168
- }
169
-
170
- const emptyVariableChecker = []
171
- const noDataMessageChecker = []
172
-
173
- const convertVariablesInMarkup = inlineMarkup => {
174
- if (_.isEmpty(markupVariables)) return inlineMarkup
175
- const variableRegexPattern = /{{(.*?)}}/g
176
- const convertedInlineMarkup = inlineMarkup.replace(variableRegexPattern, variableTag => {
177
- if (emptyVariableChecker.length > 0) return
178
- const workingVariable = markupVariables.filter(variable => variable.tag === variableTag)[0]
179
- if (workingVariable === undefined) return [variableTag]
180
- const workingData =
181
- workingVariable && workingVariable.conditions.length === 0
182
- ? data
183
- : filterOutConditions(data, [...workingVariable.conditions])
184
-
185
- const variableValues: string[] = _.uniq(
186
- (workingData || []).map(dataObject => {
187
- const dataObjectValue = dataObject[workingVariable.columnName]
188
- return workingVariable.addCommas && !isNaN(parseFloat(dataObjectValue))
189
- ? parseFloat(dataObjectValue).toLocaleString('en-US', { useGrouping: true })
190
- : dataObjectValue
191
- })
192
- )
193
-
194
- const variableDisplay = []
195
-
196
- const listConjunction = !isEditor ? 'and' : 'or'
197
-
198
- const length = variableValues.length
199
- if (length === 2) {
200
- const newVariableValues = variableValues.join(` ${listConjunction} `)
201
- variableValues.splice(0, 2, newVariableValues)
202
- }
203
- if (length > 2) {
204
- variableValues[length - 1] = `${listConjunction} ${variableValues[length - 1]}`
205
- }
206
-
207
- variableDisplay.push(variableValues.join(', '))
208
-
209
- const finalDisplay = variableDisplay[0]
210
-
211
- if (showNoDataMessage && finalDisplay === '') {
212
- noDataMessageChecker.push(true)
213
- }
214
-
215
- if (finalDisplay === '' && contentEditor.allowHideSection) {
216
- emptyVariableChecker.push(true)
217
- }
218
- return finalDisplay
219
- })
220
- return convertedInlineMarkup
221
- }
222
-
223
185
  const parseBodyMarkup = markup => {
224
186
  let parse
225
187
  let hasBody = false
@@ -246,7 +208,6 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
246
208
  if (config && !coveLoadedHasRan && container) {
247
209
  publish('cove_loaded', { config: config })
248
210
  dispatch({ type: 'SET_COVE_LOADED_HAS_RAN', payload: true })
249
- publishAnalyticsEvent('markup-include_loaded', 'load', configUrl, 'markup-include')
250
211
  }
251
212
  }, [config, container])
252
213
 
@@ -257,10 +218,19 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
257
218
 
258
219
  let content = <Loading />
259
220
 
260
- const markup = useInlineHTML ? convertVariablesInMarkup(inlineHTML) : parseBodyMarkup(urlMarkup)
221
+ const processedMarkup = useInlineHTML
222
+ ? processMarkupVariables(inlineHTML, data || [], markupVariables || [], {
223
+ isEditor,
224
+ showNoDataMessage,
225
+ allowHideSection,
226
+ filters: config?.filters || []
227
+ })
228
+ : { processedContent: parseBodyMarkup(urlMarkup), shouldHideSection: false, shouldShowNoDataMessage: false }
229
+
230
+ const markup = processedMarkup.processedContent
261
231
 
262
- const hideMarkupInclude = contentEditor?.allowHideSection && emptyVariableChecker.length > 0 && !isEditor
263
- const _showNoDataMessage = showNoDataMessage && noDataMessageChecker.length > 0 && !isEditor
232
+ const hideMarkupInclude = processedMarkup.shouldHideSection
233
+ const _showNoDataMessage = processedMarkup.shouldShowNoDataMessage
264
234
 
265
235
  if (loading === false) {
266
236
  content = (
@@ -273,6 +243,16 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
273
243
  <div className={`markup-include-component ${contentClasses.join(' ')}`}>
274
244
  <Title title={title} isDashboard={isDashboard} classes={[`${theme}`, 'mb-0']} />
275
245
  <div className={`${innerContainerClasses.join(' ')}`}>
246
+ {/* Filters */}
247
+ {config.filters && config.filters.length > 0 && (
248
+ <Filters
249
+ config={config}
250
+ setFilters={setFilters}
251
+ excludedData={data || []}
252
+ dimensions={[0, 0]}
253
+ interactionLabel={interactionLabel || 'markup-include'}
254
+ />
255
+ )}
276
256
  <div className='cove-component__content-wrap'>
277
257
  {_showNoDataMessage && (
278
258
  <div className='no-data-message'>
@@ -284,7 +264,7 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
284
264
  </div>
285
265
  </div>
286
266
  </div>
287
- <FootnotesStandAlone config={configObj?.footnotes} filters={[]} />
267
+ <FootnotesStandAlone config={configObj?.footnotes} filters={config?.filters || []} />
288
268
  </div>
289
269
  </Layout.Responsive>
290
270
  )}