@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/dist/cdcmarkupinclude.js +17202 -10890
- package/package.json +11 -3
- package/src/CdcMarkupInclude.tsx +62 -66
- package/src/_stories/MarkupInclude.Editor.stories.tsx +465 -0
- package/src/_stories/MarkupInclude.stories.tsx +58 -58
- package/src/components/EditorPanel.tsx +27 -121
- package/src/data/initial-state.js +6 -3
- package/src/index.jsx +5 -2
- package/src/test/CdcMarkupInclude.test.jsx +8 -3
- package/src/types/Condition.ts +1 -1
- package/src/types/Config.ts +4 -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,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
|
-
|
|
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
|
|
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
|
|
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
|
-
{
|
|
267
|
-
|
|
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
|
)}
|