@cdc/markup-include 4.25.10 → 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/dist/cdcmarkupinclude.js +7128 -7333
- package/index.html +37 -26
- package/package.json +3 -4
- package/src/CdcMarkupInclude.tsx +11 -3
- package/src/_stories/MarkupInclude.Editor.stories.tsx +1 -1
- package/src/components/EditorPanel.tsx +26 -50
- package/src/scss/main.scss +0 -8
- package/src/store/markupInclude.reducer.ts +1 -1
- package/src/components/Conditions.tsx +0 -118
- package/src/components/Variables.tsx +0 -218
- package/src/types/Config.ts +0 -33
- /package/src/{index.jsx → index.tsx} +0 -0
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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.
|
|
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,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.25.
|
|
30
|
+
"@cdc/core": "^4.25.11",
|
|
31
31
|
"axios": "^1.9.0",
|
|
32
32
|
"chroma": "0.0.1",
|
|
33
33
|
"interweave": "^13.1.1",
|
|
@@ -39,11 +39,10 @@
|
|
|
39
39
|
"react-dom": "^18.2.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@rollup/plugin-dsv": "^3.0.2",
|
|
43
42
|
"@vitejs/plugin-react": "^4.3.4",
|
|
44
43
|
"vite": "^4.4.11",
|
|
45
44
|
"vite-plugin-css-injected-by-js": "^2.4.0",
|
|
46
45
|
"vite-plugin-svgr": "^2.4.0"
|
|
47
46
|
},
|
|
48
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "5f09a137c22f454111ab5f4cd7fdf1d2d58e31bd"
|
|
49
48
|
}
|
package/src/CdcMarkupInclude.tsx
CHANGED
|
@@ -72,7 +72,7 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
|
|
|
72
72
|
noDataMessageText,
|
|
73
73
|
markupVariables: contentEditorMarkupVariables
|
|
74
74
|
} = contentEditor || {}
|
|
75
|
-
const data = configObj?.data
|
|
75
|
+
const data = configObj?.data || config?.data
|
|
76
76
|
|
|
77
77
|
// Support markupVariables at root level or inside contentEditor
|
|
78
78
|
const markupVariables = config?.markupVariables || contentEditorMarkupVariables || []
|
|
@@ -223,7 +223,9 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
|
|
|
223
223
|
isEditor,
|
|
224
224
|
showNoDataMessage,
|
|
225
225
|
allowHideSection,
|
|
226
|
-
filters: config?.filters || []
|
|
226
|
+
filters: config?.filters || [],
|
|
227
|
+
datasets,
|
|
228
|
+
configDataKey: config?.dataKey
|
|
227
229
|
})
|
|
228
230
|
: { processedContent: parseBodyMarkup(urlMarkup), shouldHideSection: false, shouldShowNoDataMessage: false }
|
|
229
231
|
|
|
@@ -264,7 +266,13 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
|
|
|
264
266
|
</div>
|
|
265
267
|
</div>
|
|
266
268
|
</div>
|
|
267
|
-
<FootnotesStandAlone
|
|
269
|
+
<FootnotesStandAlone
|
|
270
|
+
config={configObj?.footnotes}
|
|
271
|
+
filters={config?.filters || []}
|
|
272
|
+
markupVariables={markupVariables}
|
|
273
|
+
enableMarkupVariables={config?.enableMarkupVariables}
|
|
274
|
+
data={data}
|
|
275
|
+
/>
|
|
268
276
|
</div>
|
|
269
277
|
</Layout.Responsive>
|
|
270
278
|
)}
|
|
@@ -323,7 +323,7 @@ export const VisualSectionTests: Story = {
|
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
const themeButtons = Array.from(canvasElement.querySelectorAll('.color-palette
|
|
326
|
+
const themeButtons = Array.from(canvasElement.querySelectorAll('.color-palette button')) as HTMLElement[]
|
|
327
327
|
expect(themeButtons.length).toBeGreaterThan(1)
|
|
328
328
|
|
|
329
329
|
await performAndAssert(
|
|
@@ -9,33 +9,19 @@ import ConfigContext from '../ConfigContext'
|
|
|
9
9
|
import { updateFieldFactory } from '@cdc/core/helpers/updateFieldFactory'
|
|
10
10
|
|
|
11
11
|
// Components
|
|
12
|
-
import
|
|
12
|
+
import { TextField, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
13
13
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
14
|
-
import InputText from '@cdc/core/components/inputs/InputText'
|
|
15
14
|
import Layout from '@cdc/core/components/Layout'
|
|
16
15
|
import Accordion from '@cdc/core/components/ui/Accordion'
|
|
17
16
|
import MarkupVariablesEditor from '@cdc/core/components/EditorPanel/components/MarkupVariablesEditor'
|
|
18
17
|
import FootnotesEditor from '@cdc/core/components/EditorPanel/FootnotesEditor'
|
|
18
|
+
import { HeaderThemeSelector } from '@cdc/core/components/HeaderThemeSelector'
|
|
19
19
|
import { Datasets } from '@cdc/core/types/DataSet'
|
|
20
20
|
|
|
21
21
|
// styles
|
|
22
22
|
import '@cdc/core/styles/v2/components/editor.scss'
|
|
23
23
|
import './editorPanel.style.css'
|
|
24
24
|
|
|
25
|
-
const headerColors = [
|
|
26
|
-
'theme-blue',
|
|
27
|
-
'theme-purple',
|
|
28
|
-
'theme-brown',
|
|
29
|
-
'theme-teal',
|
|
30
|
-
'theme-pink',
|
|
31
|
-
'theme-orange',
|
|
32
|
-
'theme-slate',
|
|
33
|
-
'theme-indigo',
|
|
34
|
-
'theme-cyan',
|
|
35
|
-
'theme-green',
|
|
36
|
-
'theme-amber'
|
|
37
|
-
]
|
|
38
|
-
|
|
39
25
|
type MarkupIncludeEditorPanelProps = {
|
|
40
26
|
datasets?: Datasets
|
|
41
27
|
}
|
|
@@ -97,7 +83,7 @@ const EditorPanel: React.FC<MarkupIncludeEditorPanelProps> = ({ datasets }) => {
|
|
|
97
83
|
const editorContent = (
|
|
98
84
|
<Accordion>
|
|
99
85
|
<Accordion.Section title='General'>
|
|
100
|
-
<
|
|
86
|
+
<TextField
|
|
101
87
|
value={title || ''}
|
|
102
88
|
section='contentEditor'
|
|
103
89
|
fieldName='title'
|
|
@@ -108,12 +94,11 @@ const EditorPanel: React.FC<MarkupIncludeEditorPanelProps> = ({ datasets }) => {
|
|
|
108
94
|
</Accordion.Section>
|
|
109
95
|
<Accordion.Section title='Content Editor'>
|
|
110
96
|
<span className='divider-heading'>Enter Markup</span>
|
|
111
|
-
<
|
|
112
|
-
inline
|
|
97
|
+
<CheckBox
|
|
113
98
|
value={useInlineHTML}
|
|
114
99
|
section='contentEditor'
|
|
115
100
|
fieldName='useInlineHTML'
|
|
116
|
-
label='Use Inline HTML
|
|
101
|
+
label='Use Inline HTML'
|
|
117
102
|
updateField={updateField}
|
|
118
103
|
/>
|
|
119
104
|
<div className='column-edit'>
|
|
@@ -121,20 +106,19 @@ const EditorPanel: React.FC<MarkupIncludeEditorPanelProps> = ({ datasets }) => {
|
|
|
121
106
|
<>
|
|
122
107
|
{/* HTML Textbox */}
|
|
123
108
|
<div ref={textAreaInEditorContainer}>
|
|
124
|
-
<
|
|
109
|
+
<TextField
|
|
125
110
|
value={inlineHTML}
|
|
126
111
|
section='contentEditor'
|
|
127
112
|
fieldName='inlineHTML'
|
|
128
113
|
label='HTML'
|
|
129
114
|
placeholder='Add HTML here'
|
|
130
115
|
type='textarea'
|
|
131
|
-
rows={10}
|
|
132
116
|
updateField={updateField}
|
|
133
117
|
/>
|
|
134
118
|
</div>
|
|
135
119
|
</>
|
|
136
120
|
) : (
|
|
137
|
-
<
|
|
121
|
+
<TextField
|
|
138
122
|
value={srcUrl || ''}
|
|
139
123
|
section='contentEditor'
|
|
140
124
|
fieldName='srcUrl'
|
|
@@ -145,56 +129,46 @@ const EditorPanel: React.FC<MarkupIncludeEditorPanelProps> = ({ datasets }) => {
|
|
|
145
129
|
)}
|
|
146
130
|
</div>
|
|
147
131
|
</Accordion.Section>
|
|
148
|
-
<Accordion.Section title='Visual'>
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
onClick={() => {
|
|
157
|
-
updateConfig({ ...config, theme: palette })
|
|
158
|
-
}}
|
|
159
|
-
className={theme === palette ? 'selected ' + palette : palette}
|
|
160
|
-
></li>
|
|
161
|
-
))}
|
|
162
|
-
</ul>
|
|
163
|
-
</div>
|
|
164
|
-
<div className='cove-accordion__panel-section checkbox-group'>
|
|
165
|
-
<InputCheckbox
|
|
132
|
+
<Accordion.Section title='Visual' className='panel-visual'>
|
|
133
|
+
<HeaderThemeSelector
|
|
134
|
+
selectedTheme={theme}
|
|
135
|
+
onThemeSelect={theme => updateConfig({ ...config, theme })}
|
|
136
|
+
label='Theme'
|
|
137
|
+
/>
|
|
138
|
+
<div className='checkbox-group'>
|
|
139
|
+
<CheckBox
|
|
166
140
|
value={visual.border}
|
|
167
141
|
section='visual'
|
|
168
142
|
fieldName='border'
|
|
169
|
-
label='Display Border
|
|
143
|
+
label='Display Border'
|
|
170
144
|
updateField={updateField}
|
|
171
145
|
/>
|
|
172
|
-
<
|
|
146
|
+
<CheckBox
|
|
173
147
|
value={visual.borderColorTheme}
|
|
174
148
|
section='visual'
|
|
175
149
|
fieldName='borderColorTheme'
|
|
176
|
-
label='Use Border Color Theme
|
|
150
|
+
label='Use Border Color Theme'
|
|
177
151
|
updateField={updateField}
|
|
178
152
|
/>
|
|
179
|
-
<
|
|
153
|
+
<CheckBox
|
|
180
154
|
value={visual.accent}
|
|
181
155
|
section='visual'
|
|
182
156
|
fieldName='accent'
|
|
183
|
-
label='Use Accent Style
|
|
157
|
+
label='Use Accent Style'
|
|
184
158
|
updateField={updateField}
|
|
185
159
|
/>
|
|
186
|
-
<
|
|
160
|
+
<CheckBox
|
|
187
161
|
value={visual.background}
|
|
188
162
|
section='visual'
|
|
189
163
|
fieldName='background'
|
|
190
|
-
label='Use Theme Background Color
|
|
164
|
+
label='Use Theme Background Color'
|
|
191
165
|
updateField={updateField}
|
|
192
166
|
/>
|
|
193
|
-
<
|
|
167
|
+
<CheckBox
|
|
194
168
|
value={visual.hideBackgroundColor}
|
|
195
169
|
section='visual'
|
|
196
170
|
fieldName='hideBackgroundColor'
|
|
197
|
-
label='Hide Background Color
|
|
171
|
+
label='Hide Background Color'
|
|
198
172
|
updateField={updateField}
|
|
199
173
|
/>
|
|
200
174
|
</div>
|
|
@@ -208,6 +182,8 @@ const EditorPanel: React.FC<MarkupIncludeEditorPanelProps> = ({ datasets }) => {
|
|
|
208
182
|
<MarkupVariablesEditor
|
|
209
183
|
markupVariables={config.markupVariables || []}
|
|
210
184
|
data={data || []}
|
|
185
|
+
datasets={datasets}
|
|
186
|
+
config={config}
|
|
211
187
|
onChange={handleMarkupVariablesChange}
|
|
212
188
|
enableMarkupVariables={config.enableMarkupVariables || false}
|
|
213
189
|
onToggleEnable={handleToggleEnable}
|
package/src/scss/main.scss
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MarkupIncludeConfig } from '@cdc/core/types/MarkupInclude'
|
|
2
2
|
import MarkupIncludeActions from './markupInclude.actions'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
type MarkupIncludeState = {
|
|
5
5
|
config?: MarkupIncludeConfig
|
|
6
6
|
loading: boolean
|
|
7
7
|
urlMarkup: string
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash'
|
|
2
|
-
import { Condition } from '../types/Condition'
|
|
3
|
-
import Icon from '@cdc/core/components/ui/Icon'
|
|
4
|
-
|
|
5
|
-
type OpenControls = [boolean[], Function] // useState type
|
|
6
|
-
|
|
7
|
-
type CondtionsProps = {
|
|
8
|
-
conditionControls: OpenControls
|
|
9
|
-
conditionLookup: Record<string, string[] | number[]>
|
|
10
|
-
conditionSettings: Condition
|
|
11
|
-
conditionIndex: number
|
|
12
|
-
removeCondition: Function
|
|
13
|
-
selectedColumn: string
|
|
14
|
-
updateConditionsList: Function
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const Conditions: React.FC<CondtionsProps> = ({
|
|
18
|
-
conditionControls,
|
|
19
|
-
conditionLookup,
|
|
20
|
-
conditionSettings,
|
|
21
|
-
conditionIndex,
|
|
22
|
-
removeCondition,
|
|
23
|
-
selectedColumn,
|
|
24
|
-
updateConditionsList
|
|
25
|
-
}) => {
|
|
26
|
-
const [openConditionControls, setOpenConditionControls] = conditionControls
|
|
27
|
-
const showCondition = openConditionControls[conditionIndex]
|
|
28
|
-
const setShowCondition = (index, value) => {
|
|
29
|
-
const newOpenConditionsControls = [...openConditionControls]
|
|
30
|
-
newOpenConditionsControls[index] = value
|
|
31
|
-
setOpenConditionControls(newOpenConditionsControls)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const columnNames = Object.keys(conditionLookup)
|
|
35
|
-
const columnNameConditionOptions = columnNames.filter(optionName => optionName !== selectedColumn)
|
|
36
|
-
|
|
37
|
-
const { columnName, isOrIsNotEqualTo, value } = conditionSettings
|
|
38
|
-
|
|
39
|
-
const handleConditionChange = (selectionValue: string | number, conditionSetting: string) => {
|
|
40
|
-
const conditionSettingUpdate = _.cloneDeep(conditionSettings)
|
|
41
|
-
if (conditionSetting === 'columnName') {
|
|
42
|
-
conditionSettingUpdate['value'] = ''
|
|
43
|
-
}
|
|
44
|
-
conditionSettingUpdate[conditionSetting] = selectionValue
|
|
45
|
-
updateConditionsList(conditionSettingUpdate, conditionIndex)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return !showCondition ? (
|
|
49
|
-
<>
|
|
50
|
-
<div className='mb-1'>
|
|
51
|
-
<button onClick={() => setShowCondition(conditionIndex, true)}>
|
|
52
|
-
<Icon display='caretDown' />
|
|
53
|
-
</button>
|
|
54
|
-
<span>
|
|
55
|
-
{' '}
|
|
56
|
-
{value ? `${columnName} ${isOrIsNotEqualTo === 'is' ? 'is' : 'is not'} ${value}` : 'New Condition'}
|
|
57
|
-
</span>
|
|
58
|
-
</div>
|
|
59
|
-
</>
|
|
60
|
-
) : (
|
|
61
|
-
<>
|
|
62
|
-
<div className='d-flex justify-content-between'>
|
|
63
|
-
<button
|
|
64
|
-
onClick={() => {
|
|
65
|
-
const newOpenConditionsControls = [...openConditionControls]
|
|
66
|
-
newOpenConditionsControls[conditionIndex] = false
|
|
67
|
-
setOpenConditionControls(newOpenConditionsControls)
|
|
68
|
-
}}
|
|
69
|
-
>
|
|
70
|
-
<Icon display='caretDown' />
|
|
71
|
-
</button>
|
|
72
|
-
<button className='btn btn-warn btn-sm mt-0 ms-2' onClick={() => removeCondition(conditionIndex)}>
|
|
73
|
-
Remove
|
|
74
|
-
</button>
|
|
75
|
-
</div>
|
|
76
|
-
<div id={`condition_${conditionIndex}`}>
|
|
77
|
-
<label className='d-block'>
|
|
78
|
-
<span>Condition : </span>
|
|
79
|
-
<div className='pt-1'>
|
|
80
|
-
<select
|
|
81
|
-
className='ms-1'
|
|
82
|
-
value={columnName}
|
|
83
|
-
onChange={e => handleConditionChange(e.target.value, 'columnName')}
|
|
84
|
-
>
|
|
85
|
-
<option value=''>Select</option>
|
|
86
|
-
{columnNameConditionOptions?.map(columnName => (
|
|
87
|
-
<option key={columnName} value={columnName}>
|
|
88
|
-
{columnName}
|
|
89
|
-
</option>
|
|
90
|
-
))}
|
|
91
|
-
</select>
|
|
92
|
-
<select
|
|
93
|
-
className='ms-1'
|
|
94
|
-
value={isOrIsNotEqualTo}
|
|
95
|
-
onChange={e => handleConditionChange(e.target.value, 'isOrIsNotEqualTo')}
|
|
96
|
-
>
|
|
97
|
-
<option value='is'>is</option>
|
|
98
|
-
<option value='isNot'>is not</option>
|
|
99
|
-
</select>
|
|
100
|
-
<select className='ms-1' value={value} onChange={e => handleConditionChange(e.target.value, 'value')}>
|
|
101
|
-
<option value=''>Select</option>
|
|
102
|
-
|
|
103
|
-
{conditionLookup[columnName]?.map(valueItem => {
|
|
104
|
-
return (
|
|
105
|
-
<option key={valueItem} value={valueItem}>
|
|
106
|
-
{valueItem}
|
|
107
|
-
</option>
|
|
108
|
-
)
|
|
109
|
-
})}
|
|
110
|
-
</select>
|
|
111
|
-
</div>
|
|
112
|
-
</label>
|
|
113
|
-
</div>
|
|
114
|
-
</>
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export default Conditions
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import { useMemo, useState } from 'react'
|
|
2
|
-
import Conditions from './Conditions'
|
|
3
|
-
import { Variable } from '../types/Variable'
|
|
4
|
-
import { Condition } from '../types/Condition'
|
|
5
|
-
import _ from 'lodash'
|
|
6
|
-
import Icon from '@cdc/core/components/ui/Icon'
|
|
7
|
-
import { CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
8
|
-
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
9
|
-
|
|
10
|
-
type OpenControls = [boolean[], Function] // useState type
|
|
11
|
-
|
|
12
|
-
type VariableSectionProps = {
|
|
13
|
-
controls: OpenControls
|
|
14
|
-
data: Object[]
|
|
15
|
-
deleteVariable: Function
|
|
16
|
-
updateVariableArray: Function
|
|
17
|
-
variableConfig: Variable
|
|
18
|
-
variableIndex: number
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const VariableSection: React.FC<VariableSectionProps> = ({
|
|
22
|
-
controls,
|
|
23
|
-
data,
|
|
24
|
-
deleteVariable,
|
|
25
|
-
updateVariableArray,
|
|
26
|
-
variableConfig,
|
|
27
|
-
variableIndex
|
|
28
|
-
}) => {
|
|
29
|
-
const [openVariableControls, setOpenVariableControls] = controls
|
|
30
|
-
const show = openVariableControls[variableIndex]
|
|
31
|
-
const setShow = (key, value) => {
|
|
32
|
-
setOpenVariableControls({ openVariableControls, [key]: value })
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const openConditionControls = useState([])
|
|
36
|
-
|
|
37
|
-
const columnNames = Object.keys(data?.[0] || {})
|
|
38
|
-
const [selectedColumn, setNewVariableColumnName] = useState(variableConfig.columnName)
|
|
39
|
-
const [conditionsList, setConditionsList] = useState(variableConfig.conditions)
|
|
40
|
-
const [variableName, setVariableName] = useState(variableConfig.name)
|
|
41
|
-
const [addCommas, setAddCommas] = useState(variableConfig.addCommas)
|
|
42
|
-
|
|
43
|
-
const conditionLookup: Record<string, string[] | number[]> = useMemo(() => {
|
|
44
|
-
return columnNames.reduce((acc, column) => {
|
|
45
|
-
acc[column] = _.uniq(data.map(row => row[column]))
|
|
46
|
-
return acc
|
|
47
|
-
}, {})
|
|
48
|
-
}, [columnNames])
|
|
49
|
-
|
|
50
|
-
const handleUpdateAddCommas = () => {
|
|
51
|
-
setAddCommas(!addCommas)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const handleVariableColumnChange = (columnName: string) => {
|
|
55
|
-
setNewVariableColumnName(columnName)
|
|
56
|
-
setConditionsList([])
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const updateConditionsList = (conditionSettings: Condition, conditionIndex: number) => {
|
|
60
|
-
const { columnName, isOrIsNotEqualTo, value } = conditionSettings
|
|
61
|
-
const newConditionsList = _.cloneDeep(conditionsList)
|
|
62
|
-
newConditionsList[conditionIndex] = {
|
|
63
|
-
columnName: columnName,
|
|
64
|
-
isOrIsNotEqualTo: isOrIsNotEqualTo,
|
|
65
|
-
value: value
|
|
66
|
-
}
|
|
67
|
-
setConditionsList(newConditionsList)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const removeCondition = (conditionIndex: number) => {
|
|
71
|
-
const updatedConditionsList = _.cloneDeep(conditionsList)
|
|
72
|
-
updatedConditionsList.splice(conditionIndex, 1)
|
|
73
|
-
setConditionsList(updatedConditionsList)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const handleAddConditionClick = () => {
|
|
77
|
-
setConditionsList([
|
|
78
|
-
...conditionsList,
|
|
79
|
-
{
|
|
80
|
-
columnName: '',
|
|
81
|
-
isOrIsNotEqualTo: 'is',
|
|
82
|
-
value: ''
|
|
83
|
-
}
|
|
84
|
-
])
|
|
85
|
-
|
|
86
|
-
const [conditionControls, setConditionControls] = openConditionControls
|
|
87
|
-
|
|
88
|
-
const newConditionsControls = [...conditionControls]
|
|
89
|
-
newConditionsControls[conditionsList.length + 1] = true
|
|
90
|
-
setConditionControls(newConditionsControls)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const handleVariableDoneClick = () => {
|
|
94
|
-
const filteredConditionsList = conditionsList.filter(
|
|
95
|
-
condition => condition.columnName !== '' && condition.value !== ''
|
|
96
|
-
)
|
|
97
|
-
const newVariable = {
|
|
98
|
-
columnName: selectedColumn,
|
|
99
|
-
conditions: filteredConditionsList,
|
|
100
|
-
name: variableName,
|
|
101
|
-
tag: `{{${variableName}}}`,
|
|
102
|
-
addCommas
|
|
103
|
-
}
|
|
104
|
-
updateVariableArray(newVariable, variableIndex)
|
|
105
|
-
setShow(variableIndex, false)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const columnSelectDisabled = variableName === ''
|
|
109
|
-
const addConditionDisabled = columnSelectDisabled || selectedColumn === ''
|
|
110
|
-
|
|
111
|
-
return (
|
|
112
|
-
<>
|
|
113
|
-
{!show ? (
|
|
114
|
-
<>
|
|
115
|
-
<div className='mb-2'>
|
|
116
|
-
<button onClick={() => setShow(variableIndex, true)}>
|
|
117
|
-
<Icon display='caretDown' />
|
|
118
|
-
</button>
|
|
119
|
-
<span> {variableName ? `${variableName}` : 'New Variable'}</span>
|
|
120
|
-
</div>
|
|
121
|
-
</>
|
|
122
|
-
) : (
|
|
123
|
-
<fieldset className='edit-block mb-1' key={variableIndex}>
|
|
124
|
-
<div className='d-flex justify-content-between'>
|
|
125
|
-
<button onClick={handleVariableDoneClick} disabled={addConditionDisabled}>
|
|
126
|
-
<Icon display='caretUp' />
|
|
127
|
-
</button>
|
|
128
|
-
<button
|
|
129
|
-
className='btn btn-danger btn-sm mt-0 ms-2'
|
|
130
|
-
onClick={event => {
|
|
131
|
-
event.preventDefault()
|
|
132
|
-
deleteVariable(variableIndex)
|
|
133
|
-
}}
|
|
134
|
-
>
|
|
135
|
-
Delete
|
|
136
|
-
</button>
|
|
137
|
-
</div>
|
|
138
|
-
<label className='d-block'>
|
|
139
|
-
<span className='edit-label column-heading'>Variable Name:</span>
|
|
140
|
-
<input
|
|
141
|
-
className={`variable-${variableIndex} ms-1`}
|
|
142
|
-
type='text'
|
|
143
|
-
value={variableName}
|
|
144
|
-
onChange={e => setVariableName(e.target.value)}
|
|
145
|
-
/>
|
|
146
|
-
</label>
|
|
147
|
-
<div className='pt-2'>
|
|
148
|
-
<label className='d-block'>
|
|
149
|
-
<span className='edit-label column-heading'>Column:</span>
|
|
150
|
-
<select
|
|
151
|
-
className={`variable-${variableIndex} ms-1`}
|
|
152
|
-
onChange={e => handleVariableColumnChange(e.target.value)}
|
|
153
|
-
value={selectedColumn}
|
|
154
|
-
disabled={columnSelectDisabled}
|
|
155
|
-
>
|
|
156
|
-
<option value=''>Select</option>
|
|
157
|
-
{columnNames.map(columnName => (
|
|
158
|
-
<option key={columnName} value={columnName}>
|
|
159
|
-
{columnName}
|
|
160
|
-
</option>
|
|
161
|
-
))}
|
|
162
|
-
</select>
|
|
163
|
-
</label>
|
|
164
|
-
</div>
|
|
165
|
-
<div className='pt-2'>
|
|
166
|
-
<CheckBox
|
|
167
|
-
value={addCommas}
|
|
168
|
-
label='Add Commas to Number'
|
|
169
|
-
updateField={handleUpdateAddCommas}
|
|
170
|
-
tooltip={
|
|
171
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
172
|
-
<Tooltip.Target>
|
|
173
|
-
<Icon
|
|
174
|
-
display='question'
|
|
175
|
-
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
176
|
-
/>
|
|
177
|
-
</Tooltip.Target>
|
|
178
|
-
<Tooltip.Content>
|
|
179
|
-
<p>{`Selecting this option will add commas to the numeric value.`}</p>
|
|
180
|
-
</Tooltip.Content>
|
|
181
|
-
</Tooltip>
|
|
182
|
-
}
|
|
183
|
-
/>
|
|
184
|
-
</div>
|
|
185
|
-
<label className='d-block py-2'>
|
|
186
|
-
<span className='edit-label column-heading'>Conditions:</span>
|
|
187
|
-
{conditionsList.map((condition, index) => {
|
|
188
|
-
return (
|
|
189
|
-
<div className='condition-section mt-2'>
|
|
190
|
-
<Conditions
|
|
191
|
-
key={variableName + '-condition-' + index}
|
|
192
|
-
conditionControls={openConditionControls}
|
|
193
|
-
conditionLookup={conditionLookup}
|
|
194
|
-
conditionSettings={condition}
|
|
195
|
-
conditionIndex={index}
|
|
196
|
-
removeCondition={removeCondition}
|
|
197
|
-
selectedColumn={selectedColumn}
|
|
198
|
-
updateConditionsList={updateConditionsList}
|
|
199
|
-
/>
|
|
200
|
-
</div>
|
|
201
|
-
)
|
|
202
|
-
})}
|
|
203
|
-
</label>
|
|
204
|
-
<div className='mt-1'>
|
|
205
|
-
<button onClick={handleAddConditionClick} disabled={addConditionDisabled}>
|
|
206
|
-
Add Condition
|
|
207
|
-
</button>
|
|
208
|
-
<button className='ms-2' onClick={handleVariableDoneClick} disabled={addConditionDisabled}>
|
|
209
|
-
Done
|
|
210
|
-
</button>
|
|
211
|
-
</div>
|
|
212
|
-
</fieldset>
|
|
213
|
-
)}
|
|
214
|
-
</>
|
|
215
|
-
)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export default VariableSection
|