@cdc/markup-include 4.25.8 → 4.25.11

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/index.html CHANGED
@@ -1,30 +1,41 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
6
- <style>
7
- body {
8
- margin: 0 auto !important;
9
- display: flex;
10
- flex-direction: column;
11
- justify-content: center;
12
- border-top: none !important;
13
- }
14
3
 
15
- .react-container + .react-container {
16
- margin-top: 3rem;
17
- }
18
- </style>
19
- <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/5.0/css/app.min.css?_=71669" />
20
- </head>
21
- <body>
22
- <!-- Original -->
4
+ <head>
5
+ <meta charset="utf-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
7
+ <style type="text/css">
8
+ body {
9
+ margin: 0;
10
+ border-top: none !important;
11
+ }
23
12
 
24
- <!-- DATA PRESENTATION GALLERY: https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/Markup-Include.html#examples -->
25
- <!-- <div class="react-container" data-config="/src/_stories/_mock/icon-no-text.json"></div> -->
26
- <!-- <div class="react-container" data-config="/src/_stories/_mock/image-with-text.json"></div> -->
27
- <div class="react-container" data-config="/src/_stories/_mock/button-and-text.json"></div>
28
- <script type="module" src="./src/index.jsx"></script>
29
- </body>
30
- </html>
13
+ .cdc-map-outer-container {
14
+ min-height: 100vh;
15
+ }
16
+ </style>
17
+ <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/5.0/css/app.min.css?_=71669" />
18
+
19
+ <!-- This is temporary and for testing until Nunito/900 is added to TP -->
20
+ <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap" rel="stylesheet" />
21
+ <style type="text/css">
22
+ @font-face {
23
+ font-family: 'Nunito';
24
+ font-weight: 900;
25
+ font-display: swap;
26
+ src: url('https://app.unpkg.com/@fontsource/nunito@5.0.18/files/files/nunito-latin-900-normal.woff2') format('woff2');
27
+ }
28
+ </style>
29
+ </head>
30
+
31
+ <body>
32
+ <!-- Original -->
33
+
34
+ <!-- DATA PRESENTATION GALLERY: https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/Markup-Include.html#examples -->
35
+ <!-- <div class="react-container" data-config="/src/_stories/_mock/icon-no-text.json"></div> -->
36
+ <!-- <div class="react-container" data-config="/src/_stories/_mock/image-with-text.json"></div> -->
37
+ <div class="react-container" data-config="/src/_stories/_mock/button-and-text.json"></div>
38
+ <script type="module" src="./src/index.tsx"></script>
39
+ </body>
40
+
41
+ </html>
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.11",
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,22 @@
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.11",
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
+ "@vitejs/plugin-react": "^4.3.4",
43
+ "vite": "^4.4.11",
44
+ "vite-plugin-css-injected-by-js": "^2.4.0",
45
+ "vite-plugin-svgr": "^2.4.0"
46
+ },
47
+ "gitHead": "5f09a137c22f454111ab5f4cd7fdf1d2d58e31bd"
41
48
  }
@@ -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 || {}
65
- const data = configObj?.data
69
+ const {
70
+ showNoDataMessage,
71
+ allowHideSection,
72
+ noDataMessageText,
73
+ markupVariables: contentEditorMarkupVariables
74
+ } = contentEditor || {}
75
+ const data = configObj?.data || config?.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,21 @@ 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
+ datasets,
228
+ configDataKey: config?.dataKey
229
+ })
230
+ : { processedContent: parseBodyMarkup(urlMarkup), shouldHideSection: false, shouldShowNoDataMessage: false }
231
+
232
+ const markup = processedMarkup.processedContent
261
233
 
262
- const hideMarkupInclude = contentEditor?.allowHideSection && emptyVariableChecker.length > 0 && !isEditor
263
- const _showNoDataMessage = showNoDataMessage && noDataMessageChecker.length > 0 && !isEditor
234
+ const hideMarkupInclude = processedMarkup.shouldHideSection
235
+ const _showNoDataMessage = processedMarkup.shouldShowNoDataMessage
264
236
 
265
237
  if (loading === false) {
266
238
  content = (
@@ -273,6 +245,16 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
273
245
  <div className={`markup-include-component ${contentClasses.join(' ')}`}>
274
246
  <Title title={title} isDashboard={isDashboard} classes={[`${theme}`, 'mb-0']} />
275
247
  <div className={`${innerContainerClasses.join(' ')}`}>
248
+ {/* Filters */}
249
+ {config.filters && config.filters.length > 0 && (
250
+ <Filters
251
+ config={config}
252
+ setFilters={setFilters}
253
+ excludedData={data || []}
254
+ dimensions={[0, 0]}
255
+ interactionLabel={interactionLabel || 'markup-include'}
256
+ />
257
+ )}
276
258
  <div className='cove-component__content-wrap'>
277
259
  {_showNoDataMessage && (
278
260
  <div className='no-data-message'>
@@ -284,7 +266,13 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
284
266
  </div>
285
267
  </div>
286
268
  </div>
287
- <FootnotesStandAlone config={configObj?.footnotes} filters={[]} />
269
+ <FootnotesStandAlone
270
+ config={configObj?.footnotes}
271
+ filters={config?.filters || []}
272
+ markupVariables={markupVariables}
273
+ enableMarkupVariables={config?.enableMarkupVariables}
274
+ data={data}
275
+ />
288
276
  </div>
289
277
  </Layout.Responsive>
290
278
  )}