@cdc/markup-include 4.25.7 → 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.7",
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.7",
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": "9062881d50c824ee6cdd71868bafd016a5e5694d"
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,11 +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'
40
+ import { VizFilter } from '@cdc/core/types/VizFilter'
36
41
 
37
42
  const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
38
43
  configUrl,
@@ -40,7 +45,8 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
40
45
  datasets,
41
46
  isDashboard = true,
42
47
  isEditor = false,
43
- setConfig: setParentConfig
48
+ setConfig: setParentConfig,
49
+ interactionLabel = 'no link provided'
44
50
  }) => {
45
51
  const initialState = {
46
52
  config: configObj,
@@ -60,9 +66,18 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
60
66
 
61
67
  const { innerContainerClasses, contentClasses } = useDataVizClasses(config || {})
62
68
  const { contentEditor, theme } = config || {}
69
+ const {
70
+ showNoDataMessage,
71
+ allowHideSection,
72
+ noDataMessageText,
73
+ markupVariables: contentEditorMarkupVariables
74
+ } = contentEditor || {}
63
75
  const data = configObj?.data
64
76
 
65
- 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 || {}
66
81
 
67
82
  // Default Functions
68
83
  const updateConfig = newConfig => {
@@ -79,6 +94,15 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
79
94
  dispatch({ type: 'SET_CONFIG', payload: newConfig })
80
95
  }
81
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
+
82
106
  const loadConfig = async () => {
83
107
  let response = configObj || (await (await fetch(configUrl)).json())
84
108
  let responseData = response.data ?? {}
@@ -91,6 +115,11 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
91
115
  response.data = responseData
92
116
  const processedConfig = { ...coveUpdateWorker(response) }
93
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
+
94
123
  updateConfig({ ...configObj, ...processedConfig })
95
124
  dispatch({ type: 'SET_LOADING', payload: false })
96
125
  }
@@ -153,65 +182,6 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
153
182
  }
154
183
  }
155
184
 
156
- const filterOutConditions = (workingData, conditionList) => {
157
- const { columnName, isOrIsNotEqualTo, value } = conditionList[0]
158
-
159
- const newWorkingData =
160
- isOrIsNotEqualTo === 'is'
161
- ? workingData?.filter(dataObject => dataObject[columnName] === value)
162
- : workingData?.filter(dataObject => dataObject[columnName] !== value)
163
-
164
- conditionList.shift()
165
- return conditionList.length === 0 ? newWorkingData : filterOutConditions(newWorkingData, conditionList)
166
- }
167
-
168
- const emptyVariableChecker = []
169
-
170
- const convertVariablesInMarkup = inlineMarkup => {
171
- if (_.isEmpty(markupVariables)) return inlineMarkup
172
- const variableRegexPattern = /{{(.*?)}}/g
173
- const convertedInlineMarkup = inlineMarkup.replace(variableRegexPattern, variableTag => {
174
- if (emptyVariableChecker.length > 0) return
175
- const workingVariable = markupVariables.filter(variable => variable.tag === variableTag)[0]
176
- if (workingVariable === undefined) return [variableTag]
177
- const workingData =
178
- workingVariable && workingVariable.conditions.length === 0
179
- ? data
180
- : filterOutConditions(data, [...workingVariable.conditions])
181
-
182
- const variableValues: string[] = _.uniq(
183
- (workingData || []).map(dataObject => {
184
- const dataObjectValue = dataObject[workingVariable.columnName]
185
- return workingVariable.addCommas && !isNaN(parseFloat(dataObjectValue))
186
- ? parseFloat(dataObjectValue).toLocaleString('en-US', { useGrouping: true })
187
- : dataObjectValue
188
- })
189
- )
190
-
191
- const variableDisplay = []
192
-
193
- const listConjunction = !isEditor ? 'and' : 'or'
194
-
195
- const length = variableValues.length
196
- if (length === 2) {
197
- const newVariableValues = variableValues.join(` ${listConjunction} `)
198
- variableValues.splice(0, 2, newVariableValues)
199
- }
200
- if (length > 2) {
201
- variableValues[length - 1] = `${listConjunction} ${variableValues[length - 1]}`
202
- }
203
- variableDisplay.push(variableValues.join(', '))
204
-
205
- const finalDisplay = variableDisplay[0]
206
-
207
- if (finalDisplay === '' && contentEditor.allowHideSection) {
208
- emptyVariableChecker.push(true)
209
- }
210
- return finalDisplay
211
- })
212
- return convertedInlineMarkup
213
- }
214
-
215
185
  const parseBodyMarkup = markup => {
216
186
  let parse
217
187
  let hasBody = false
@@ -248,27 +218,53 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
248
218
 
249
219
  let content = <Loading />
250
220
 
251
- 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 }
252
229
 
253
- const hideMarkupInclude = contentEditor?.allowHideSection && emptyVariableChecker.length > 0 && !isEditor
230
+ const markup = processedMarkup.processedContent
231
+
232
+ const hideMarkupInclude = processedMarkup.shouldHideSection
233
+ const _showNoDataMessage = processedMarkup.shouldShowNoDataMessage
254
234
 
255
235
  if (loading === false) {
256
236
  content = (
257
237
  <>
258
238
  {isEditor && <EditorPanel datasets={datasets} />}
239
+
259
240
  {!hideMarkupInclude && (
260
241
  <Layout.Responsive isEditor={isEditor}>
261
242
  <div className='markup-include-content-container cove-component__content no-borders'>
262
243
  <div className={`markup-include-component ${contentClasses.join(' ')}`}>
263
244
  <Title title={title} isDashboard={isDashboard} classes={[`${theme}`, 'mb-0']} />
264
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
+ )}
265
256
  <div className='cove-component__content-wrap'>
266
- {!markupError && <Markup allowElements={!!urlMarkup} content={markup} />}
267
- {markupError && srcUrl && <div className='warning'>{errorMessage}</div>}
257
+ {_showNoDataMessage && (
258
+ <div className='no-data-message'>
259
+ <p>{`${noDataMessageText}`}</p>
260
+ </div>
261
+ )}
262
+ {!markupError && !_showNoDataMessage && <Markup allowElements={!!urlMarkup} content={markup} />}
263
+ {markupError && srcUrl && !_showNoDataMessage && <div className='warning'>{errorMessage}</div>}
268
264
  </div>
269
265
  </div>
270
266
  </div>
271
- <FootnotesStandAlone config={configObj?.footnotes} filters={[]} />
267
+ <FootnotesStandAlone config={configObj?.footnotes} filters={config?.filters || []} />
272
268
  </div>
273
269
  </Layout.Responsive>
274
270
  )}