@cdc/markup-include 4.24.10 → 4.24.12-2
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 +3731 -3517
- package/package.json +3 -3
- package/src/CdcMarkupInclude.tsx +32 -20
- package/src/components/Conditions.tsx +24 -5
- package/src/components/EditorPanel.tsx +132 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/markup-include",
|
|
3
|
-
"version": "4.24.
|
|
3
|
+
"version": "4.24.12-2",
|
|
4
4
|
"description": "React component for displaying HTML content from an outside link",
|
|
5
5
|
"moduleName": "CdcMarkupInclude",
|
|
6
6
|
"main": "dist/cdcmarkupinclude",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "Apache-2.0",
|
|
28
28
|
"homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@cdc/core": "^4.24.
|
|
30
|
+
"@cdc/core": "^4.24.12-2",
|
|
31
31
|
"axios": "^1.6.0",
|
|
32
32
|
"chroma": "0.0.1",
|
|
33
33
|
"chroma-js": "^2.1.0",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"react": "^18.2.0",
|
|
40
40
|
"react-dom": "^18.2.0"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "a60edf1148396309eb473ac9f65426ee40797ddf"
|
|
43
43
|
}
|
package/src/CdcMarkupInclude.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useCallback, useRef, useReducer,
|
|
1
|
+
import { useEffect, useCallback, useRef, useReducer, useMemo } from 'react'
|
|
2
2
|
import _ from 'lodash'
|
|
3
3
|
// external
|
|
4
4
|
import { Markup } from 'interweave'
|
|
@@ -154,17 +154,20 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
|
|
|
154
154
|
|
|
155
155
|
const newWorkingData =
|
|
156
156
|
isOrIsNotEqualTo === 'is'
|
|
157
|
-
? workingData
|
|
158
|
-
: workingData
|
|
157
|
+
? workingData?.filter(dataObject => dataObject[columnName] === value)
|
|
158
|
+
: workingData?.filter(dataObject => dataObject[columnName] !== value)
|
|
159
159
|
|
|
160
160
|
conditionList.shift()
|
|
161
161
|
return conditionList.length === 0 ? newWorkingData : filterOutConditions(newWorkingData, conditionList)
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
const emptyVariableChecker = []
|
|
165
|
+
|
|
164
166
|
const convertVariablesInMarkup = inlineMarkup => {
|
|
165
167
|
if (_.isEmpty(markupVariables)) return inlineMarkup
|
|
166
168
|
const variableRegexPattern = /{{(.*?)}}/g
|
|
167
169
|
const convertedInlineMarkup = inlineMarkup.replace(variableRegexPattern, variableTag => {
|
|
170
|
+
if (emptyVariableChecker.length > 0) return
|
|
168
171
|
const workingVariable = markupVariables.filter(variable => variable.tag === variableTag)[0]
|
|
169
172
|
if (workingVariable === undefined) return [variableTag]
|
|
170
173
|
const workingData =
|
|
@@ -173,28 +176,33 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
|
|
|
173
176
|
: filterOutConditions(data, [...workingVariable.conditions])
|
|
174
177
|
|
|
175
178
|
const variableValues: string[] = _.uniq(
|
|
176
|
-
(workingData || []).map(dataObject =>
|
|
179
|
+
(workingData || []).map(dataObject => {
|
|
180
|
+
const dataObjectValue = dataObject[workingVariable.columnName]
|
|
181
|
+
return workingVariable.addCommas && !isNaN(parseFloat(dataObjectValue))
|
|
182
|
+
? parseFloat(dataObjectValue).toLocaleString('en-US', { useGrouping: true })
|
|
183
|
+
: dataObjectValue
|
|
184
|
+
})
|
|
177
185
|
)
|
|
186
|
+
|
|
178
187
|
const variableDisplay = []
|
|
179
188
|
|
|
180
189
|
const listConjunction = !isEditor ? 'and' : 'or'
|
|
181
190
|
|
|
182
191
|
const length = variableValues.length
|
|
183
192
|
if (length === 2) {
|
|
184
|
-
variableValues.
|
|
193
|
+
const newVariableValues = variableValues.join(` ${listConjunction} `)
|
|
194
|
+
variableValues.splice(0, 2, newVariableValues)
|
|
185
195
|
}
|
|
186
196
|
if (length > 2) {
|
|
187
197
|
variableValues[length - 1] = `${listConjunction} ${variableValues[length - 1]}`
|
|
188
198
|
}
|
|
189
199
|
variableDisplay.push(variableValues.join(', '))
|
|
190
200
|
|
|
191
|
-
|
|
201
|
+
const finalDisplay = variableDisplay[0]
|
|
192
202
|
|
|
193
|
-
if (
|
|
194
|
-
|
|
195
|
-
finalDisplay = finalDisplay.toLocaleString('en-US', { useGrouping: true })
|
|
203
|
+
if (finalDisplay === '' && contentEditor.allowHideSection) {
|
|
204
|
+
emptyVariableChecker.push(true)
|
|
196
205
|
}
|
|
197
|
-
|
|
198
206
|
return finalDisplay
|
|
199
207
|
})
|
|
200
208
|
return convertedInlineMarkup
|
|
@@ -237,23 +245,27 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
|
|
|
237
245
|
|
|
238
246
|
const markup = useInlineHTML ? convertVariablesInMarkup(inlineHTML) : parseBodyMarkup(urlMarkup)
|
|
239
247
|
|
|
248
|
+
const hideMarkupInclude = contentEditor?.allowHideSection && emptyVariableChecker.length > 0 && !isEditor
|
|
249
|
+
|
|
240
250
|
if (loading === false) {
|
|
241
251
|
content = (
|
|
242
252
|
<>
|
|
243
253
|
{isEditor && <EditorPanel />}
|
|
244
|
-
|
|
245
|
-
<
|
|
246
|
-
<div className=
|
|
247
|
-
<
|
|
248
|
-
|
|
249
|
-
<div className='
|
|
250
|
-
|
|
251
|
-
|
|
254
|
+
{!hideMarkupInclude && (
|
|
255
|
+
<Layout.Responsive isEditor={isEditor}>
|
|
256
|
+
<div className='markup-include-content-container cove-component__content no-borders'>
|
|
257
|
+
<div className={`markup-include-component ${contentClasses.join(' ')}`}>
|
|
258
|
+
<Title title={title} isDashboard={isDashboard} classes={[`${theme}`, 'mb-0']} />
|
|
259
|
+
<div className={`${innerContainerClasses.join(' ')}`}>
|
|
260
|
+
<div className='cove-component__content-wrap'>
|
|
261
|
+
{!markupError && <Markup allowElements={!!urlMarkup} content={markup} />}
|
|
262
|
+
{markupError && srcUrl && <div className='warning'>{errorMessage}</div>}
|
|
263
|
+
</div>
|
|
252
264
|
</div>
|
|
253
265
|
</div>
|
|
254
266
|
</div>
|
|
255
|
-
</
|
|
256
|
-
|
|
267
|
+
</Layout.Responsive>
|
|
268
|
+
)}
|
|
257
269
|
</>
|
|
258
270
|
)
|
|
259
271
|
}
|
|
@@ -14,7 +14,15 @@ type CondtionsProps = {
|
|
|
14
14
|
updateConditionsList: Function
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const Conditions: React.FC<CondtionsProps> = ({
|
|
17
|
+
const Conditions: React.FC<CondtionsProps> = ({
|
|
18
|
+
conditionControls,
|
|
19
|
+
conditionLookup,
|
|
20
|
+
conditionSettings,
|
|
21
|
+
conditionIndex,
|
|
22
|
+
removeCondition,
|
|
23
|
+
selectedColumn,
|
|
24
|
+
updateConditionsList
|
|
25
|
+
}) => {
|
|
18
26
|
const [openConditionControls, setOpenConditionControls] = conditionControls
|
|
19
27
|
const showCondition = openConditionControls[conditionIndex]
|
|
20
28
|
const setShowCondition = (index, value) => {
|
|
@@ -43,7 +51,10 @@ const Conditions: React.FC<CondtionsProps> = ({ conditionControls, conditionLook
|
|
|
43
51
|
<button onClick={() => setShowCondition(conditionIndex, true)}>
|
|
44
52
|
<Icon display='caretDown' />
|
|
45
53
|
</button>
|
|
46
|
-
<span>
|
|
54
|
+
<span>
|
|
55
|
+
{' '}
|
|
56
|
+
{value ? `${columnName} ${isOrIsNotEqualTo === 'is' ? 'is' : 'is not'} ${value}` : 'New Condition'}
|
|
57
|
+
</span>
|
|
47
58
|
</div>
|
|
48
59
|
</>
|
|
49
60
|
) : (
|
|
@@ -58,7 +69,7 @@ const Conditions: React.FC<CondtionsProps> = ({ conditionControls, conditionLook
|
|
|
58
69
|
>
|
|
59
70
|
<Icon display='caretDown' />
|
|
60
71
|
</button>
|
|
61
|
-
<button className='btn btn-
|
|
72
|
+
<button className='btn btn-warn btn-sm mt-0 ml-2' onClick={() => removeCondition(conditionIndex)}>
|
|
62
73
|
Remove
|
|
63
74
|
</button>
|
|
64
75
|
</div>
|
|
@@ -66,7 +77,11 @@ const Conditions: React.FC<CondtionsProps> = ({ conditionControls, conditionLook
|
|
|
66
77
|
<label className='d-block'>
|
|
67
78
|
<span>Condition : </span>
|
|
68
79
|
<div className='pt-1'>
|
|
69
|
-
<select
|
|
80
|
+
<select
|
|
81
|
+
className='ml-1'
|
|
82
|
+
value={columnName}
|
|
83
|
+
onChange={e => handleConditionChange(e.target.value, 'columnName')}
|
|
84
|
+
>
|
|
70
85
|
<option value=''>Select</option>
|
|
71
86
|
{columnNameConditionOptions?.map(columnName => (
|
|
72
87
|
<option key={columnName} value={columnName}>
|
|
@@ -74,7 +89,11 @@ const Conditions: React.FC<CondtionsProps> = ({ conditionControls, conditionLook
|
|
|
74
89
|
</option>
|
|
75
90
|
))}
|
|
76
91
|
</select>
|
|
77
|
-
<select
|
|
92
|
+
<select
|
|
93
|
+
className='ml-1'
|
|
94
|
+
value={isOrIsNotEqualTo}
|
|
95
|
+
onChange={e => handleConditionChange(e.target.value, 'isOrIsNotEqualTo')}
|
|
96
|
+
>
|
|
78
97
|
<option value='is'>is</option>
|
|
79
98
|
<option value='isNot'>is not</option>
|
|
80
99
|
</select>
|
|
@@ -23,13 +23,26 @@ import Accordion from '@cdc/core/components/ui/Accordion'
|
|
|
23
23
|
import '@cdc/core/styles/v2/components/editor.scss'
|
|
24
24
|
import './editorPanel.style.css'
|
|
25
25
|
import VariableSection from './Variables'
|
|
26
|
+
import { CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
26
27
|
|
|
27
|
-
const headerColors = [
|
|
28
|
+
const headerColors = [
|
|
29
|
+
'theme-blue',
|
|
30
|
+
'theme-purple',
|
|
31
|
+
'theme-brown',
|
|
32
|
+
'theme-teal',
|
|
33
|
+
'theme-pink',
|
|
34
|
+
'theme-orange',
|
|
35
|
+
'theme-slate',
|
|
36
|
+
'theme-indigo',
|
|
37
|
+
'theme-cyan',
|
|
38
|
+
'theme-green',
|
|
39
|
+
'theme-amber'
|
|
40
|
+
]
|
|
28
41
|
|
|
29
42
|
const EditorPanel: React.FC = () => {
|
|
30
43
|
const { config, data, isDashboard, loading, setParentConfig, updateConfig } = useContext(ConfigContext)
|
|
31
44
|
const { contentEditor, theme, visual } = config
|
|
32
|
-
const { inlineHTML, markupVariables, srcUrl, title, useInlineHTML } = contentEditor
|
|
45
|
+
const { inlineHTML, markupVariables, srcUrl, title, useInlineHTML, allowHideSection } = contentEditor
|
|
33
46
|
const [displayPanel, setDisplayPanel] = useState(true)
|
|
34
47
|
const updateField = updateFieldFactory(config, updateConfig, true)
|
|
35
48
|
const hasData = data?.[0] !== undefined ?? false
|
|
@@ -111,17 +124,40 @@ const EditorPanel: React.FC = () => {
|
|
|
111
124
|
const editorContent = (
|
|
112
125
|
<Accordion>
|
|
113
126
|
<Accordion.Section title='General'>
|
|
114
|
-
<InputText
|
|
127
|
+
<InputText
|
|
128
|
+
value={title || ''}
|
|
129
|
+
section='contentEditor'
|
|
130
|
+
fieldName='title'
|
|
131
|
+
label='Title'
|
|
132
|
+
placeholder='Markup Include Title'
|
|
133
|
+
updateField={updateField}
|
|
134
|
+
/>
|
|
115
135
|
</Accordion.Section>
|
|
116
136
|
<Accordion.Section title='Content Editor'>
|
|
117
137
|
<span className='divider-heading'>Enter Markup</span>
|
|
118
|
-
<InputCheckbox
|
|
138
|
+
<InputCheckbox
|
|
139
|
+
inline
|
|
140
|
+
value={useInlineHTML}
|
|
141
|
+
section='contentEditor'
|
|
142
|
+
fieldName='useInlineHTML'
|
|
143
|
+
label='Use Inline HTML '
|
|
144
|
+
updateField={updateField}
|
|
145
|
+
/>
|
|
119
146
|
<div className='column-edit'>
|
|
120
147
|
{useInlineHTML ? (
|
|
121
148
|
<>
|
|
122
149
|
{/* HTML Textbox */}
|
|
123
150
|
<div ref={textAreaInEditorContainer}>
|
|
124
|
-
<InputText
|
|
151
|
+
<InputText
|
|
152
|
+
value={inlineHTML}
|
|
153
|
+
section='contentEditor'
|
|
154
|
+
fieldName='inlineHTML'
|
|
155
|
+
label='HTML'
|
|
156
|
+
placeholder='Add HTML here'
|
|
157
|
+
type='textarea'
|
|
158
|
+
rows={10}
|
|
159
|
+
updateField={updateField}
|
|
160
|
+
/>
|
|
125
161
|
|
|
126
162
|
<hr className='accordion__divider' />
|
|
127
163
|
</div>
|
|
@@ -140,23 +176,69 @@ const EditorPanel: React.FC = () => {
|
|
|
140
176
|
</Tooltip>
|
|
141
177
|
</span>
|
|
142
178
|
</label>
|
|
143
|
-
{hasData === false &&
|
|
179
|
+
{hasData === false && (
|
|
180
|
+
<span className='need-data-source-prompt'>To use variables, add data source.</span>
|
|
181
|
+
)}
|
|
144
182
|
{variableArray && variableArray.length > 0 && (
|
|
145
183
|
<div className='section-border'>
|
|
146
184
|
{variableArray?.map((variableObject, index) => {
|
|
147
|
-
return
|
|
185
|
+
return (
|
|
186
|
+
<VariableSection
|
|
187
|
+
key={`${variableObject.name}-${index}`}
|
|
188
|
+
controls={openVariableControls}
|
|
189
|
+
data={data}
|
|
190
|
+
deleteVariable={deleteVariable}
|
|
191
|
+
updateVariableArray={updateVariableArray}
|
|
192
|
+
variableConfig={variableObject}
|
|
193
|
+
variableIndex={index}
|
|
194
|
+
/>
|
|
195
|
+
)
|
|
148
196
|
})}
|
|
149
197
|
</div>
|
|
150
198
|
)}
|
|
199
|
+
<div className='pt-2'>
|
|
200
|
+
<CheckBox
|
|
201
|
+
value={allowHideSection}
|
|
202
|
+
section='contentEditor'
|
|
203
|
+
fieldName='allowHideSection'
|
|
204
|
+
label='Hide Section on Null'
|
|
205
|
+
updateField={updateField}
|
|
206
|
+
tooltip={
|
|
207
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
208
|
+
<Tooltip.Target>
|
|
209
|
+
<Icon
|
|
210
|
+
display='question'
|
|
211
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
212
|
+
/>
|
|
213
|
+
</Tooltip.Target>
|
|
214
|
+
<Tooltip.Content>
|
|
215
|
+
<p>{`Hide this entire Markup Include section if any variable is null or blank.`}</p>
|
|
216
|
+
</Tooltip.Content>
|
|
217
|
+
</Tooltip>
|
|
218
|
+
}
|
|
219
|
+
/>
|
|
220
|
+
</div>
|
|
221
|
+
|
|
151
222
|
<div className='mb-1 d-flex'>
|
|
152
|
-
<button
|
|
223
|
+
<button
|
|
224
|
+
className={'btn btn-primary'}
|
|
225
|
+
onClick={handleCreateNewVariableButtonClick}
|
|
226
|
+
disabled={!hasData}
|
|
227
|
+
>
|
|
153
228
|
Create New Variable
|
|
154
229
|
</button>
|
|
155
230
|
</div>
|
|
156
231
|
</fieldset>
|
|
157
232
|
</>
|
|
158
233
|
) : (
|
|
159
|
-
<InputText
|
|
234
|
+
<InputText
|
|
235
|
+
value={srcUrl || ''}
|
|
236
|
+
section='contentEditor'
|
|
237
|
+
fieldName='srcUrl'
|
|
238
|
+
label='Source URL;'
|
|
239
|
+
placeholder='https://www.example.com/file.html'
|
|
240
|
+
updateField={updateField}
|
|
241
|
+
/>
|
|
160
242
|
)}
|
|
161
243
|
</div>
|
|
162
244
|
</Accordion.Section>
|
|
@@ -177,11 +259,41 @@ const EditorPanel: React.FC = () => {
|
|
|
177
259
|
</ul>
|
|
178
260
|
</div>
|
|
179
261
|
<div className='cove-accordion__panel-section checkbox-group'>
|
|
180
|
-
<InputCheckbox
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
262
|
+
<InputCheckbox
|
|
263
|
+
value={visual.border}
|
|
264
|
+
section='visual'
|
|
265
|
+
fieldName='border'
|
|
266
|
+
label='Display Border '
|
|
267
|
+
updateField={updateField}
|
|
268
|
+
/>
|
|
269
|
+
<InputCheckbox
|
|
270
|
+
value={visual.borderColorTheme}
|
|
271
|
+
section='visual'
|
|
272
|
+
fieldName='borderColorTheme'
|
|
273
|
+
label='Use Border Color Theme '
|
|
274
|
+
updateField={updateField}
|
|
275
|
+
/>
|
|
276
|
+
<InputCheckbox
|
|
277
|
+
value={visual.accent}
|
|
278
|
+
section='visual'
|
|
279
|
+
fieldName='accent'
|
|
280
|
+
label='Use Accent Style '
|
|
281
|
+
updateField={updateField}
|
|
282
|
+
/>
|
|
283
|
+
<InputCheckbox
|
|
284
|
+
value={visual.background}
|
|
285
|
+
section='visual'
|
|
286
|
+
fieldName='background'
|
|
287
|
+
label='Use Theme Background Color '
|
|
288
|
+
updateField={updateField}
|
|
289
|
+
/>
|
|
290
|
+
<InputCheckbox
|
|
291
|
+
value={visual.hideBackgroundColor}
|
|
292
|
+
section='visual'
|
|
293
|
+
fieldName='hideBackgroundColor'
|
|
294
|
+
label='Hide Background Color '
|
|
295
|
+
updateField={updateField}
|
|
296
|
+
/>
|
|
185
297
|
</div>
|
|
186
298
|
</Accordion.Section>
|
|
187
299
|
</Accordion>
|
|
@@ -191,7 +303,12 @@ const EditorPanel: React.FC = () => {
|
|
|
191
303
|
|
|
192
304
|
return (
|
|
193
305
|
<ErrorBoundary component='EditorPanel'>
|
|
194
|
-
<Layout.Sidebar
|
|
306
|
+
<Layout.Sidebar
|
|
307
|
+
displayPanel={displayPanel}
|
|
308
|
+
isDashboard={isDashboard}
|
|
309
|
+
title={'Configure Markup Include'}
|
|
310
|
+
onBackClick={onBackClick}
|
|
311
|
+
>
|
|
195
312
|
{editorContent}
|
|
196
313
|
</Layout.Sidebar>
|
|
197
314
|
</ErrorBoundary>
|