@visns-studio/visns-components 5.0.4 → 5.0.6
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/package.json +1 -1
- package/src/components/crm/AsyncSelect.jsx +121 -15
- package/src/components/crm/DataGrid.jsx +25 -5
- package/src/components/crm/Field.jsx +163 -147
- package/src/components/crm/Form.jsx +4 -3
- package/src/components/crm/MultiSelect.jsx +82 -26
- package/src/components/crm/auth/styles/Login.module.scss +4 -3
- package/src/components/crm/auth/styles/Profile.module.scss +4 -4
- package/src/components/crm/generic/GenericDetail.jsx +95 -14
- package/src/components/crm/generic/styles/GenericDetail.module.scss +132 -118
- package/src/components/crm/generic/styles/GenericIndex.module.scss +1 -1
- package/src/components/crm/styles/DataGrid.module.scss +2 -3
- package/src/components/crm/styles/Field.module.scss +13 -11
- package/src/components/crm/styles/Form.module.scss +1 -1
- package/src/components/crm/styles/Navigation.module.scss +12 -10
- package/src/components/styles/global.css +40 -6
package/package.json
CHANGED
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
76
76
|
},
|
|
77
77
|
"name": "@visns-studio/visns-components",
|
|
78
|
-
"version": "5.0.
|
|
78
|
+
"version": "5.0.6",
|
|
79
79
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
80
80
|
"main": "src/index.js",
|
|
81
81
|
"files": [
|
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
2
|
import CustomFetch from './Fetch';
|
|
3
3
|
import SelectList from './SelectList';
|
|
4
4
|
import AsyncSelect from 'react-select/async';
|
|
5
|
+
import AsyncCreatableSelect from 'react-select/async-creatable';
|
|
5
6
|
import { debounce } from 'lodash';
|
|
6
7
|
import styles from './styles/AsyncSelect.module.scss';
|
|
8
|
+
import { components } from 'react-select';
|
|
9
|
+
|
|
10
|
+
// Custom Option component to add a second line of text
|
|
11
|
+
const CustomOption = (props) => (
|
|
12
|
+
<components.Option {...props}>
|
|
13
|
+
<div>
|
|
14
|
+
{props.data.label}
|
|
15
|
+
{props.data.description && props.data.description !== '' && (
|
|
16
|
+
<div style={{ fontSize: '0.85em', color: '#888' }}>
|
|
17
|
+
{props.data.description}
|
|
18
|
+
</div>
|
|
19
|
+
)}
|
|
20
|
+
</div>
|
|
21
|
+
</components.Option>
|
|
22
|
+
);
|
|
7
23
|
|
|
8
24
|
function VisnsAsyncSelect({
|
|
25
|
+
className,
|
|
9
26
|
fields = [],
|
|
10
27
|
inputValue,
|
|
11
28
|
onChange,
|
|
@@ -14,6 +31,7 @@ function VisnsAsyncSelect({
|
|
|
14
31
|
placeholder,
|
|
15
32
|
settings,
|
|
16
33
|
style,
|
|
34
|
+
isCreatable = false, // New prop to toggle creatable functionality
|
|
17
35
|
}) {
|
|
18
36
|
const loadSuggestedOptions = useCallback(
|
|
19
37
|
debounce((inputValue, callback) => {
|
|
@@ -31,7 +49,6 @@ function VisnsAsyncSelect({
|
|
|
31
49
|
return new Promise((resolve, reject) => {
|
|
32
50
|
let data = [];
|
|
33
51
|
|
|
34
|
-
// Prepare payload
|
|
35
52
|
let payload = {
|
|
36
53
|
where: [
|
|
37
54
|
{
|
|
@@ -41,38 +58,50 @@ function VisnsAsyncSelect({
|
|
|
41
58
|
],
|
|
42
59
|
};
|
|
43
60
|
|
|
44
|
-
// Check and set fields from settings if fields prop is null or empty
|
|
45
61
|
if (fields && fields.length > 0) {
|
|
46
62
|
payload.fields = fields;
|
|
47
63
|
} else if (settings.fields && settings.fields.length > 0) {
|
|
48
64
|
payload.fields = settings.fields;
|
|
49
65
|
}
|
|
50
66
|
|
|
51
|
-
// Check and set orderBy from settings if orderBy prop is null or empty
|
|
52
67
|
if (orderBy) {
|
|
53
68
|
payload.orderBy = orderBy;
|
|
54
69
|
} else if (settings.orderBy) {
|
|
55
70
|
payload.orderBy = settings.orderBy;
|
|
56
71
|
}
|
|
57
72
|
|
|
58
|
-
// Fetch data
|
|
59
73
|
CustomFetch(
|
|
60
74
|
settings.url,
|
|
61
75
|
'POST',
|
|
62
76
|
payload,
|
|
63
77
|
function (result) {
|
|
64
78
|
result.data.forEach((a) => {
|
|
79
|
+
let mainLabel = a.label || a[Object.keys(a)[0]];
|
|
80
|
+
|
|
81
|
+
if (settings.fields && settings.fields.length > 2) {
|
|
82
|
+
const additionalFields =
|
|
83
|
+
settings.fields.slice(2);
|
|
84
|
+
const additionalLabels = additionalFields
|
|
85
|
+
.filter(
|
|
86
|
+
(field) =>
|
|
87
|
+
field !== settings.descriptionKey
|
|
88
|
+
)
|
|
89
|
+
.map((field) => a[field] || '')
|
|
90
|
+
.join(' ');
|
|
91
|
+
mainLabel += ` ${additionalLabels}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
65
94
|
let _optionItem = {
|
|
66
95
|
value: a.id,
|
|
67
|
-
label:
|
|
96
|
+
label: mainLabel,
|
|
97
|
+
description: settings.descriptionKey
|
|
98
|
+
? a[settings.descriptionKey]
|
|
99
|
+
: '',
|
|
68
100
|
};
|
|
69
101
|
|
|
70
102
|
Object.keys(a).forEach((b) => {
|
|
71
|
-
if (b !== 'id') {
|
|
72
|
-
_optionItem =
|
|
73
|
-
..._optionItem,
|
|
74
|
-
[b]: a[b],
|
|
75
|
-
};
|
|
103
|
+
if (b !== 'id' && b !== 'label') {
|
|
104
|
+
_optionItem[b] = a[b];
|
|
76
105
|
}
|
|
77
106
|
});
|
|
78
107
|
|
|
@@ -87,17 +116,92 @@ function VisnsAsyncSelect({
|
|
|
87
116
|
);
|
|
88
117
|
});
|
|
89
118
|
} else {
|
|
90
|
-
return Promise.resolve([]);
|
|
119
|
+
return Promise.resolve([]);
|
|
91
120
|
}
|
|
92
121
|
};
|
|
93
122
|
|
|
123
|
+
const handleCreateOption = async (inputValue) => {
|
|
124
|
+
if (
|
|
125
|
+
settings.creatableConfig &&
|
|
126
|
+
settings.creatableConfig.url &&
|
|
127
|
+
settings.creatableConfig.method
|
|
128
|
+
) {
|
|
129
|
+
let payload;
|
|
130
|
+
let firstNameField, lastNameField;
|
|
131
|
+
|
|
132
|
+
if (
|
|
133
|
+
settings.creatableConfig.type === 'name' &&
|
|
134
|
+
Array.isArray(settings.creatableConfig.fields)
|
|
135
|
+
) {
|
|
136
|
+
[firstNameField, lastNameField] =
|
|
137
|
+
settings.creatableConfig.fields;
|
|
138
|
+
|
|
139
|
+
const nameParts = inputValue.trim().split(' ');
|
|
140
|
+
let firstname = '';
|
|
141
|
+
let lastname = '';
|
|
142
|
+
|
|
143
|
+
if (nameParts.length === 1) {
|
|
144
|
+
firstname = nameParts[0];
|
|
145
|
+
} else if (nameParts.length === 2) {
|
|
146
|
+
firstname = nameParts[0];
|
|
147
|
+
lastname = nameParts[1];
|
|
148
|
+
} else {
|
|
149
|
+
firstname = nameParts[0];
|
|
150
|
+
lastname = nameParts.slice(1).join(' ');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
payload = {
|
|
154
|
+
[firstNameField || 'firstname']: firstname,
|
|
155
|
+
[lastNameField || 'lastname']: lastname,
|
|
156
|
+
};
|
|
157
|
+
} else {
|
|
158
|
+
payload = { label: inputValue };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const newOption = await CustomFetch(
|
|
162
|
+
settings.creatableConfig.url,
|
|
163
|
+
settings.creatableConfig.method,
|
|
164
|
+
payload
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (newOption && newOption.data && newOption.data.data) {
|
|
168
|
+
const newOptionData = newOption.data.data;
|
|
169
|
+
const option = {
|
|
170
|
+
value: newOptionData.id,
|
|
171
|
+
label:
|
|
172
|
+
settings.creatableConfig.type === 'name'
|
|
173
|
+
? `${
|
|
174
|
+
newOptionData[firstNameField] ||
|
|
175
|
+
newOptionData.firstname
|
|
176
|
+
} ${
|
|
177
|
+
newOptionData[lastNameField] ||
|
|
178
|
+
newOptionData.lastname
|
|
179
|
+
}`
|
|
180
|
+
: newOptionData.label || inputValue,
|
|
181
|
+
description: settings.descriptionKey
|
|
182
|
+
? newOptionData[settings.descriptionKey]
|
|
183
|
+
: 'Placeholder text for description',
|
|
184
|
+
...newOptionData,
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
onChange(option, { action: 'create-option' }, settings.id); // Directly call onChange with new option
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const SelectComponent = isCreatable ? AsyncCreatableSelect : AsyncSelect;
|
|
193
|
+
|
|
94
194
|
return (
|
|
95
|
-
<
|
|
195
|
+
<SelectComponent
|
|
96
196
|
isClearable
|
|
97
197
|
cacheOptions
|
|
98
198
|
loadOptions={loadSuggestedOptions}
|
|
99
199
|
defaultOptions
|
|
100
|
-
className={
|
|
200
|
+
className={
|
|
201
|
+
className
|
|
202
|
+
? `${styles.visns__ms} ${className}`
|
|
203
|
+
: styles.visns__ms
|
|
204
|
+
}
|
|
101
205
|
onChange={(inputValue, action) => {
|
|
102
206
|
onChange(inputValue, action, settings.id);
|
|
103
207
|
}}
|
|
@@ -106,7 +210,9 @@ function VisnsAsyncSelect({
|
|
|
106
210
|
onKeyDown(e);
|
|
107
211
|
}
|
|
108
212
|
}}
|
|
109
|
-
|
|
213
|
+
classNamePrefix="visns-select"
|
|
214
|
+
onCreateOption={isCreatable ? handleCreateOption : undefined}
|
|
215
|
+
components={{ Option: CustomOption }}
|
|
110
216
|
styles={{
|
|
111
217
|
menu: (styles) => ({
|
|
112
218
|
...styles,
|
|
@@ -2382,12 +2382,32 @@ const DataGrid = forwardRef(
|
|
|
2382
2382
|
data[column.id] &&
|
|
2383
2383
|
data[column.id] !== ''
|
|
2384
2384
|
) {
|
|
2385
|
+
let content = String(
|
|
2386
|
+
data[column.id]
|
|
2387
|
+
);
|
|
2388
|
+
|
|
2389
|
+
// If removeFormat is true, strip HTML tags
|
|
2390
|
+
if (column.removeFormat) {
|
|
2391
|
+
content = content.replace(
|
|
2392
|
+
/<\/?[^>]+(>|$)/g,
|
|
2393
|
+
''
|
|
2394
|
+
); // Simple regex to strip HTML tags
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
// If truncate has a value, limit content to specified number of characters
|
|
2398
|
+
if (column.truncate) {
|
|
2399
|
+
content =
|
|
2400
|
+
content.length >
|
|
2401
|
+
column.truncate
|
|
2402
|
+
? content.substring(
|
|
2403
|
+
0,
|
|
2404
|
+
column.truncate
|
|
2405
|
+
) + '...'
|
|
2406
|
+
: content;
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2385
2409
|
return (
|
|
2386
|
-
<span>
|
|
2387
|
-
{parse(
|
|
2388
|
-
String(data[column.id])
|
|
2389
|
-
)}
|
|
2390
|
-
</span>
|
|
2410
|
+
<span>{parse(content)}</span>
|
|
2391
2411
|
);
|
|
2392
2412
|
} else {
|
|
2393
2413
|
return null;
|
|
@@ -253,65 +253,70 @@ function Field({
|
|
|
253
253
|
}, [settings.options, settings, counter]);
|
|
254
254
|
|
|
255
255
|
const renderLabel = () => {
|
|
256
|
-
if (
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
return (
|
|
287
|
-
<span className={`${styles.fi__span} ${styles.prefocus}`}>
|
|
288
|
-
{settings.label} {settings.required ? '*' : ''}
|
|
289
|
-
</span>
|
|
290
|
-
);
|
|
291
|
-
} else if (['plaintext'].includes(settings.type)) {
|
|
292
|
-
if (settings.description) {
|
|
293
|
-
return (
|
|
294
|
-
<span>
|
|
295
|
-
{settings.description
|
|
296
|
-
? parse(settings.description)
|
|
297
|
-
: ''}
|
|
298
|
-
</span>
|
|
299
|
-
);
|
|
300
|
-
} else {
|
|
256
|
+
if (settings.label && settings.label !== '') {
|
|
257
|
+
if (
|
|
258
|
+
[
|
|
259
|
+
'address',
|
|
260
|
+
'async-dropdown-ajax',
|
|
261
|
+
'checkbox',
|
|
262
|
+
'colour',
|
|
263
|
+
'copytoclipboard',
|
|
264
|
+
'date',
|
|
265
|
+
'datetime',
|
|
266
|
+
'dropdown',
|
|
267
|
+
'dropdown-ajax',
|
|
268
|
+
'dynamicdata',
|
|
269
|
+
'file',
|
|
270
|
+
'gallery',
|
|
271
|
+
'image',
|
|
272
|
+
'multi-dropdown',
|
|
273
|
+
'multi-dropdown-ajax',
|
|
274
|
+
'plaindate',
|
|
275
|
+
'plaindatetime',
|
|
276
|
+
'plainrelation',
|
|
277
|
+
'plainrelationarray',
|
|
278
|
+
'radio',
|
|
279
|
+
'radio-ajax',
|
|
280
|
+
'signature',
|
|
281
|
+
'table_radio',
|
|
282
|
+
'table_text',
|
|
283
|
+
'time',
|
|
284
|
+
].includes(settings.type)
|
|
285
|
+
) {
|
|
301
286
|
return (
|
|
302
287
|
<span className={`${styles.fi__span} ${styles.prefocus}`}>
|
|
303
288
|
{settings.label} {settings.required ? '*' : ''}
|
|
304
289
|
</span>
|
|
305
290
|
);
|
|
291
|
+
} else if (['plaintext'].includes(settings.type)) {
|
|
292
|
+
if (settings.description) {
|
|
293
|
+
return (
|
|
294
|
+
<span>
|
|
295
|
+
{settings.description
|
|
296
|
+
? parse(settings.description)
|
|
297
|
+
: ''}
|
|
298
|
+
</span>
|
|
299
|
+
);
|
|
300
|
+
} else {
|
|
301
|
+
return (
|
|
302
|
+
<span
|
|
303
|
+
className={`${styles.fi__span} ${styles.prefocus}`}
|
|
304
|
+
>
|
|
305
|
+
{settings.label} {settings.required ? '*' : ''}
|
|
306
|
+
</span>
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
} else if (['plaintextheading'].includes(settings.type)) {
|
|
310
|
+
return <h2>{settings.label ? settings.label : ''}</h2>;
|
|
311
|
+
} else if (['section'].includes(settings.type)) {
|
|
312
|
+
return (
|
|
313
|
+
<div className={styles.gridtxt__header}>
|
|
314
|
+
<span>{settings.label}</span>
|
|
315
|
+
</div>
|
|
316
|
+
);
|
|
317
|
+
} else if (['richeditor'].includes(settings.type)) {
|
|
318
|
+
return settings.label;
|
|
306
319
|
}
|
|
307
|
-
} else if (['plaintextheading'].includes(settings.type)) {
|
|
308
|
-
return <h2>{settings.label ? settings.label : ''}</h2>;
|
|
309
|
-
} else if (['section'].includes(settings.type)) {
|
|
310
|
-
return (
|
|
311
|
-
<div className={styles.gridtxt__header}>
|
|
312
|
-
<span>{settings.label}</span>
|
|
313
|
-
</div>
|
|
314
|
-
);
|
|
315
320
|
}
|
|
316
321
|
};
|
|
317
322
|
|
|
@@ -368,23 +373,26 @@ function Field({
|
|
|
368
373
|
);
|
|
369
374
|
case 'async-dropdown-ajax':
|
|
370
375
|
return (
|
|
371
|
-
<
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
inputValue
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
376
|
+
<div className={styles.dropdownContainer}>
|
|
377
|
+
<VisnsAsyncSelect
|
|
378
|
+
settings={settings}
|
|
379
|
+
className={inputClass[settings.id]}
|
|
380
|
+
multi={
|
|
381
|
+
settings.hasOwnProperty('multi')
|
|
382
|
+
? settings.multi
|
|
383
|
+
: false
|
|
384
|
+
}
|
|
385
|
+
onChange={onChangeSelect}
|
|
386
|
+
inputValue={
|
|
387
|
+
inputValue === null || inputValue === undefined
|
|
388
|
+
? ''
|
|
389
|
+
: inputValue
|
|
390
|
+
}
|
|
391
|
+
options={options}
|
|
392
|
+
dataOptions={dataOptions}
|
|
393
|
+
isCreatable={settings.isCreatable || false}
|
|
394
|
+
/>
|
|
395
|
+
</div>
|
|
388
396
|
);
|
|
389
397
|
case 'checkbox':
|
|
390
398
|
return (
|
|
@@ -807,6 +815,13 @@ function Field({
|
|
|
807
815
|
|
|
808
816
|
return htmlContainer;
|
|
809
817
|
case 'html5_date':
|
|
818
|
+
// Convert inputValue to 'YYYY-MM-DD' if necessary
|
|
819
|
+
const formattedDate =
|
|
820
|
+
inputValue &&
|
|
821
|
+
moment(inputValue, moment.ISO_8601, true).isValid()
|
|
822
|
+
? moment(inputValue).format('YYYY-MM-DD')
|
|
823
|
+
: inputValue; // Use as-is if it's already in the correct format or invalid
|
|
824
|
+
|
|
810
825
|
return (
|
|
811
826
|
<input
|
|
812
827
|
type="date"
|
|
@@ -814,11 +829,7 @@ function Field({
|
|
|
814
829
|
className={inputClass[settings.id]}
|
|
815
830
|
placeholder=" "
|
|
816
831
|
onChange={onChange}
|
|
817
|
-
value={
|
|
818
|
-
inputValue && inputValue !== 'null'
|
|
819
|
-
? inputValue
|
|
820
|
-
: ''
|
|
821
|
-
}
|
|
832
|
+
value={formattedDate || ''}
|
|
822
833
|
autoComplete="off"
|
|
823
834
|
/>
|
|
824
835
|
);
|
|
@@ -970,6 +981,7 @@ function Field({
|
|
|
970
981
|
? settings.options
|
|
971
982
|
: options
|
|
972
983
|
}
|
|
984
|
+
isCreatable={settings.isCreatable || false}
|
|
973
985
|
dataOptions={dataOptions}
|
|
974
986
|
style={style}
|
|
975
987
|
/>
|
|
@@ -1172,77 +1184,6 @@ function Field({
|
|
|
1172
1184
|
))}
|
|
1173
1185
|
</div>
|
|
1174
1186
|
) : null;
|
|
1175
|
-
case 'richeditor':
|
|
1176
|
-
return (
|
|
1177
|
-
<Editor
|
|
1178
|
-
tinymceScriptSrc="https://d16lktya8ojp5z.cloudfront.net/generic/packages/tinymce_v701/tinymce.min.js"
|
|
1179
|
-
licenseKey="gpl"
|
|
1180
|
-
onEditorChange={(value, e) => {
|
|
1181
|
-
onChangeRicheditor(e, value, settings.id);
|
|
1182
|
-
}}
|
|
1183
|
-
onInit={(evt, editor) => (editorRef.current = editor)}
|
|
1184
|
-
value={inputValue || ''}
|
|
1185
|
-
init={{
|
|
1186
|
-
branding: false,
|
|
1187
|
-
height: settings.height ? settings.height : 500,
|
|
1188
|
-
menubar: false,
|
|
1189
|
-
plugins: [
|
|
1190
|
-
'advlist',
|
|
1191
|
-
'autolink',
|
|
1192
|
-
'lists',
|
|
1193
|
-
'link',
|
|
1194
|
-
'image',
|
|
1195
|
-
'charmap',
|
|
1196
|
-
'preview',
|
|
1197
|
-
'anchor',
|
|
1198
|
-
'searchreplace',
|
|
1199
|
-
'visualblocks',
|
|
1200
|
-
'code',
|
|
1201
|
-
'fullscreen',
|
|
1202
|
-
'insertdatetime',
|
|
1203
|
-
'media',
|
|
1204
|
-
'table',
|
|
1205
|
-
'code',
|
|
1206
|
-
],
|
|
1207
|
-
toolbar:
|
|
1208
|
-
'insertTextDropdown | undo redo | blocks | ' +
|
|
1209
|
-
'bold italic forecolor | alignleft aligncenter ' +
|
|
1210
|
-
'alignright alignjustify | bullist numlist outdent indent | ' +
|
|
1211
|
-
'removeformat | table',
|
|
1212
|
-
content_style:
|
|
1213
|
-
'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }',
|
|
1214
|
-
setup: (editor) => {
|
|
1215
|
-
// Check if insertText exists and is an array of objects
|
|
1216
|
-
if (
|
|
1217
|
-
settings.insertText &&
|
|
1218
|
-
Array.isArray(settings.insertText) &&
|
|
1219
|
-
settings.insertText.length > 0
|
|
1220
|
-
) {
|
|
1221
|
-
editor.ui.registry.addMenuButton(
|
|
1222
|
-
'insertTextDropdown',
|
|
1223
|
-
{
|
|
1224
|
-
text: 'Insert Text',
|
|
1225
|
-
fetch: (callback) => {
|
|
1226
|
-
const items =
|
|
1227
|
-
settings.insertText.map(
|
|
1228
|
-
(textObj) => ({
|
|
1229
|
-
type: 'menuitem',
|
|
1230
|
-
text: textObj.text,
|
|
1231
|
-
onAction: () =>
|
|
1232
|
-
editor.insertContent(
|
|
1233
|
-
textObj.content
|
|
1234
|
-
),
|
|
1235
|
-
})
|
|
1236
|
-
);
|
|
1237
|
-
callback(items);
|
|
1238
|
-
},
|
|
1239
|
-
}
|
|
1240
|
-
);
|
|
1241
|
-
}
|
|
1242
|
-
},
|
|
1243
|
-
}}
|
|
1244
|
-
/>
|
|
1245
|
-
);
|
|
1246
1187
|
case 'signature':
|
|
1247
1188
|
return (
|
|
1248
1189
|
<>
|
|
@@ -1767,6 +1708,77 @@ function Field({
|
|
|
1767
1708
|
shouldCloseOnSelect={true}
|
|
1768
1709
|
/>
|
|
1769
1710
|
);
|
|
1711
|
+
case 'richeditor':
|
|
1712
|
+
return (
|
|
1713
|
+
<Editor
|
|
1714
|
+
tinymceScriptSrc="https://d16lktya8ojp5z.cloudfront.net/generic/packages/tinymce_v701/tinymce.min.js"
|
|
1715
|
+
licenseKey="gpl"
|
|
1716
|
+
onEditorChange={(value, e) => {
|
|
1717
|
+
onChangeRicheditor(e, value, settings.id);
|
|
1718
|
+
}}
|
|
1719
|
+
onInit={(evt, editor) => (editorRef.current = editor)}
|
|
1720
|
+
value={inputValue || ''}
|
|
1721
|
+
init={{
|
|
1722
|
+
branding: false,
|
|
1723
|
+
height: settings.height ? settings.height : 500,
|
|
1724
|
+
menubar: false,
|
|
1725
|
+
plugins: [
|
|
1726
|
+
'advlist',
|
|
1727
|
+
'autolink',
|
|
1728
|
+
'lists',
|
|
1729
|
+
'link',
|
|
1730
|
+
'image',
|
|
1731
|
+
'charmap',
|
|
1732
|
+
'preview',
|
|
1733
|
+
'anchor',
|
|
1734
|
+
'searchreplace',
|
|
1735
|
+
'visualblocks',
|
|
1736
|
+
'code',
|
|
1737
|
+
'fullscreen',
|
|
1738
|
+
'insertdatetime',
|
|
1739
|
+
'media',
|
|
1740
|
+
'table',
|
|
1741
|
+
'code',
|
|
1742
|
+
],
|
|
1743
|
+
toolbar:
|
|
1744
|
+
'insertTextDropdown | undo redo | blocks | ' +
|
|
1745
|
+
'bold italic forecolor | alignleft aligncenter ' +
|
|
1746
|
+
'alignright alignjustify | bullist numlist outdent indent | ' +
|
|
1747
|
+
'removeformat | table',
|
|
1748
|
+
content_style:
|
|
1749
|
+
'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }',
|
|
1750
|
+
setup: (editor) => {
|
|
1751
|
+
// Check if insertText exists and is an array of objects
|
|
1752
|
+
if (
|
|
1753
|
+
settings.insertText &&
|
|
1754
|
+
Array.isArray(settings.insertText) &&
|
|
1755
|
+
settings.insertText.length > 0
|
|
1756
|
+
) {
|
|
1757
|
+
editor.ui.registry.addMenuButton(
|
|
1758
|
+
'insertTextDropdown',
|
|
1759
|
+
{
|
|
1760
|
+
text: 'Insert Text',
|
|
1761
|
+
fetch: (callback) => {
|
|
1762
|
+
const items =
|
|
1763
|
+
settings.insertText.map(
|
|
1764
|
+
(textObj) => ({
|
|
1765
|
+
type: 'menuitem',
|
|
1766
|
+
text: textObj.text,
|
|
1767
|
+
onAction: () =>
|
|
1768
|
+
editor.insertContent(
|
|
1769
|
+
textObj.content
|
|
1770
|
+
),
|
|
1771
|
+
})
|
|
1772
|
+
);
|
|
1773
|
+
callback(items);
|
|
1774
|
+
},
|
|
1775
|
+
}
|
|
1776
|
+
);
|
|
1777
|
+
}
|
|
1778
|
+
},
|
|
1779
|
+
}}
|
|
1780
|
+
/>
|
|
1781
|
+
);
|
|
1770
1782
|
case 'time':
|
|
1771
1783
|
return (
|
|
1772
1784
|
<DatePicker
|
|
@@ -1868,7 +1880,11 @@ function Field({
|
|
|
1868
1880
|
|
|
1869
1881
|
return (
|
|
1870
1882
|
<div className={formItemClass} style={formItemStyle}>
|
|
1871
|
-
<label
|
|
1883
|
+
<label
|
|
1884
|
+
className={
|
|
1885
|
+
settings.type === 'richeditor' ? '' : styles.fi__label
|
|
1886
|
+
}
|
|
1887
|
+
>
|
|
1872
1888
|
{renderLabel()}
|
|
1873
1889
|
{renderInput()}
|
|
1874
1890
|
{renderFieldLabel()}
|
|
@@ -215,9 +215,9 @@ function Form({
|
|
|
215
215
|
const handleSelectOption = () => {
|
|
216
216
|
updateFormData({ [id]: inputValue });
|
|
217
217
|
|
|
218
|
-
// Update any matching form data properties
|
|
219
|
-
Object.keys(inputValue).forEach((key) => {
|
|
220
|
-
if (formData.hasOwnProperty(key)) {
|
|
218
|
+
// Update any matching form data properties except for the second item
|
|
219
|
+
Object.keys(inputValue).forEach((key, index) => {
|
|
220
|
+
if (index !== 1 && formData.hasOwnProperty(key)) {
|
|
221
221
|
updateFormData({ [key]: inputValue[key] });
|
|
222
222
|
}
|
|
223
223
|
});
|
|
@@ -287,6 +287,7 @@ function Form({
|
|
|
287
287
|
// Switch cases to handle different actions
|
|
288
288
|
switch (action.action) {
|
|
289
289
|
case 'select-option':
|
|
290
|
+
case 'create-option': // New case to handle create-option
|
|
290
291
|
handleSelectOption();
|
|
291
292
|
break;
|
|
292
293
|
case 'clear':
|