@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/dist/cdcmarkupinclude.js +17294 -11077
- package/package.json +11 -3
- package/src/CdcMarkupInclude.tsx +54 -74
- package/src/_stories/MarkupInclude.Editor.stories.tsx +465 -0
- package/src/_stories/MarkupInclude.stories.tsx +58 -58
- package/src/components/EditorPanel.tsx +27 -130
- package/src/data/initial-state.js +3 -2
- package/src/index.jsx +0 -1
- package/src/test/CdcMarkupInclude.test.jsx +8 -3
- package/src/types/Condition.ts +1 -1
- package/src/types/Config.ts +2 -1
- package/vite.config.js +1 -1
- package/src/coreStyles_markupinclude.scss +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/markup-include",
|
|
3
|
-
"version": "4.25.
|
|
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.
|
|
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
|
-
"
|
|
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
|
}
|
package/src/CdcMarkupInclude.tsx
CHANGED
|
@@ -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 {
|
|
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 {
|
|
69
|
+
const {
|
|
70
|
+
showNoDataMessage,
|
|
71
|
+
allowHideSection,
|
|
72
|
+
noDataMessageText,
|
|
73
|
+
markupVariables: contentEditorMarkupVariables
|
|
74
|
+
} = contentEditor || {}
|
|
65
75
|
const data = configObj?.data
|
|
66
76
|
|
|
67
|
-
|
|
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
|
|
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 =
|
|
263
|
-
const _showNoDataMessage =
|
|
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
|
)}
|