@visns-studio/visns-components 4.10.13 → 4.10.15
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 +3 -2
- package/src/components/crm/Field.jsx +179 -9
- package/src/components/crm/Form.jsx +11 -5
- package/src/components/crm/generic/GenericDynamic.jsx +66 -38
- package/src/components/crm/generic/GenericFormBuilder.jsx +60 -2
- package/src/components/crm/sketch/SketchField.jsx +365 -0
- package/src/components/crm/sketch/arrow.jsx +108 -0
- package/src/components/crm/sketch/circle.jsx +75 -0
- package/src/components/crm/sketch/default-tool.jsx +16 -0
- package/src/components/crm/sketch/fabrictool.jsx +22 -0
- package/src/components/crm/sketch/history.jsx +144 -0
- package/src/components/crm/sketch/json/config.json +9 -0
- package/src/components/crm/sketch/line.jsx +64 -0
- package/src/components/crm/sketch/pan.jsx +48 -0
- package/src/components/crm/sketch/pencil.jsx +36 -0
- package/src/components/crm/sketch/rectangle-label-object.jsx +69 -0
- package/src/components/crm/sketch/rectangle-label.jsx +93 -0
- package/src/components/crm/sketch/rectangle.jsx +76 -0
- package/src/components/crm/sketch/select.jsx +16 -0
- package/src/components/crm/sketch/tools.jsx +11 -0
- package/src/components/crm/sketch/utils.jsx +67 -0
- package/src/components/crm/styles/Field.module.scss +159 -0
- package/src/components/crm/styles/Form.module.scss +78 -0
- package/src/index.js +6 -0
package/package.json
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"awesome-debounce-promise": "^2.1.0",
|
|
17
17
|
"axios": "^1.7.7",
|
|
18
18
|
"dayjs": "^1.11.13",
|
|
19
|
+
"fabric": "^6.4.3",
|
|
19
20
|
"file-saver": "^2.0.5",
|
|
20
21
|
"framer-motion": "^11.11.9",
|
|
21
22
|
"html-react-parser": "^5.1.18",
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
76
77
|
},
|
|
77
78
|
"name": "@visns-studio/visns-components",
|
|
78
|
-
"version": "4.10.
|
|
79
|
+
"version": "4.10.15",
|
|
79
80
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
80
81
|
"main": "src/index.js",
|
|
81
82
|
"files": [
|
|
@@ -96,5 +97,5 @@
|
|
|
96
97
|
"url": "https://github.com/visnsstudio/visns-components/issues"
|
|
97
98
|
},
|
|
98
99
|
"homepage": "https://github.com/visnsstudio/visns-components#readme",
|
|
99
|
-
"packageManager": "yarn@4.
|
|
100
|
+
"packageManager": "yarn@4.5.1"
|
|
100
101
|
}
|
|
@@ -11,7 +11,17 @@ import { BlockPicker } from 'react-color';
|
|
|
11
11
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
|
12
12
|
import { NumericFormat, PatternFormat } from 'react-number-format';
|
|
13
13
|
import { Editor } from '@tinymce/tinymce-react';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
Edit,
|
|
16
|
+
ChevronRight,
|
|
17
|
+
Circle,
|
|
18
|
+
CircleFill,
|
|
19
|
+
CloudDownload,
|
|
20
|
+
Minus,
|
|
21
|
+
ArrowBack,
|
|
22
|
+
TrashCan,
|
|
23
|
+
CircleX,
|
|
24
|
+
} from 'akar-icons';
|
|
15
25
|
import { toast } from 'react-toastify';
|
|
16
26
|
import styles from './styles/Field.module.scss';
|
|
17
27
|
|
|
@@ -19,13 +29,15 @@ import CustomFetch from './Fetch';
|
|
|
19
29
|
import Form from './Form';
|
|
20
30
|
import MultiSelect from './MultiSelect';
|
|
21
31
|
import Select from './Select';
|
|
32
|
+
import SketchConfig from './sketch/json/config.json';
|
|
33
|
+
import SketchField from './sketch/SketchField';
|
|
34
|
+
import Tools from './sketch/tools';
|
|
22
35
|
import VisnsAsyncSelect from './AsyncSelect';
|
|
23
36
|
import VisnsAutocomplete from './Autocomplete';
|
|
24
37
|
import VisnsDropZone from '../cms/DropZone';
|
|
25
38
|
|
|
26
39
|
import 'react-toggle/style.css';
|
|
27
40
|
import 'react-datepicker/dist/react-datepicker.css';
|
|
28
|
-
import Item from '../cms/sorting/Item';
|
|
29
41
|
|
|
30
42
|
function Field({
|
|
31
43
|
api,
|
|
@@ -38,6 +50,7 @@ function Field({
|
|
|
38
50
|
inputClass,
|
|
39
51
|
mapbox,
|
|
40
52
|
onChange,
|
|
53
|
+
onChangeCanvas,
|
|
41
54
|
onChangeCheckbox,
|
|
42
55
|
onChangeCheckboxManual,
|
|
43
56
|
onChangeColour,
|
|
@@ -65,6 +78,30 @@ function Field({
|
|
|
65
78
|
const [formItemClass, setFormItemClass] = useState('');
|
|
66
79
|
const [options, setOptions] = useState([]);
|
|
67
80
|
|
|
81
|
+
/** Canvas States */
|
|
82
|
+
const [canvasPopupOpen, setCanvasPopupOpen] = useState(false);
|
|
83
|
+
const [canvasUrl, setCanvasUrl] = useState('');
|
|
84
|
+
const [sketchTool, setSketchTool] = useState(Tools.Pencil);
|
|
85
|
+
const [toolClass, setToolClass] = useState('pencil');
|
|
86
|
+
const [lineWidth, setLineWidth] = useState(2);
|
|
87
|
+
const [lineColor, setLineColor] = useState('rgba(0, 0, 0, 1)');
|
|
88
|
+
const sketchRef = useRef(null);
|
|
89
|
+
|
|
90
|
+
/** Canvas Functions */
|
|
91
|
+
const handleCanvasSave = async () => {
|
|
92
|
+
// Save the current canvas state
|
|
93
|
+
const canvasState = sketchRef.current.saveCanvasState();
|
|
94
|
+
|
|
95
|
+
// Export the canvas image data as a Base64 string
|
|
96
|
+
const imageData = await sketchRef.current.exportCanvasImage(); // Use await here
|
|
97
|
+
|
|
98
|
+
// Call the onChangeCanvas function with both values
|
|
99
|
+
onChangeCanvas(settings, canvasState, imageData);
|
|
100
|
+
|
|
101
|
+
// Close the canvas popup
|
|
102
|
+
setCanvasPopupOpen(false);
|
|
103
|
+
};
|
|
104
|
+
|
|
68
105
|
const cover = {
|
|
69
106
|
position: 'fixed',
|
|
70
107
|
top: '0px',
|
|
@@ -154,6 +191,13 @@ function Field({
|
|
|
154
191
|
setFormItemClass(`${styles.formItem}`);
|
|
155
192
|
break;
|
|
156
193
|
}
|
|
194
|
+
|
|
195
|
+
if (settings.type === 'canvas') {
|
|
196
|
+
const canvasType = SketchConfig.canvasTypes.find(
|
|
197
|
+
(a) => a.id === settings.canvasType
|
|
198
|
+
);
|
|
199
|
+
setCanvasUrl(canvasType.url);
|
|
200
|
+
}
|
|
157
201
|
}, [settings, counter]);
|
|
158
202
|
|
|
159
203
|
const fetchChildDropdownData = (s, v) => {
|
|
@@ -258,6 +302,7 @@ function Field({
|
|
|
258
302
|
'address',
|
|
259
303
|
'async-dropdown-ajax',
|
|
260
304
|
'checkbox',
|
|
305
|
+
'canvas',
|
|
261
306
|
'colour',
|
|
262
307
|
'copytoclipboard',
|
|
263
308
|
'date',
|
|
@@ -386,6 +431,16 @@ function Field({
|
|
|
386
431
|
dataOptions={dataOptions}
|
|
387
432
|
/>
|
|
388
433
|
);
|
|
434
|
+
case 'canvas':
|
|
435
|
+
return canvasUrl ? (
|
|
436
|
+
<div
|
|
437
|
+
onClick={() => setCanvasPopupOpen(true)}
|
|
438
|
+
style={{ cursor: 'pointer' }}
|
|
439
|
+
>
|
|
440
|
+
<img src={canvasUrl} width="200" alt="Canvas Preview" />
|
|
441
|
+
</div>
|
|
442
|
+
) : null;
|
|
443
|
+
|
|
389
444
|
case 'checkbox':
|
|
390
445
|
return (
|
|
391
446
|
<div
|
|
@@ -1469,13 +1524,7 @@ function Field({
|
|
|
1469
1524
|
</td>
|
|
1470
1525
|
{tableRadioColumns.map((cell, cellKey) => (
|
|
1471
1526
|
<td
|
|
1472
|
-
key={`table-radio-cell-${
|
|
1473
|
-
settings.id
|
|
1474
|
-
}-${row.id}-${
|
|
1475
|
-
cell.id
|
|
1476
|
-
}-${Math.random()
|
|
1477
|
-
.toString(36)
|
|
1478
|
-
.substr(2, 9)}`}
|
|
1527
|
+
key={`table-radio-cell-${settings.id}-${row.id}-${cell.id}`}
|
|
1479
1528
|
style={{
|
|
1480
1529
|
textAlign:
|
|
1481
1530
|
tableRadioColumns[cellKey]
|
|
@@ -1706,6 +1755,7 @@ function Field({
|
|
|
1706
1755
|
'address',
|
|
1707
1756
|
'async-dropdown-ajax',
|
|
1708
1757
|
'checkbox',
|
|
1758
|
+
'canvas',
|
|
1709
1759
|
'colour',
|
|
1710
1760
|
'copytoclipboard',
|
|
1711
1761
|
'date',
|
|
@@ -1903,6 +1953,126 @@ function Field({
|
|
|
1903
1953
|
updateForm={setChildForm}
|
|
1904
1954
|
/>
|
|
1905
1955
|
</Popup>
|
|
1956
|
+
<Popup
|
|
1957
|
+
open={canvasPopupOpen}
|
|
1958
|
+
onClose={() => setCanvasPopupOpen(false)}
|
|
1959
|
+
closeOnDocumentClick={false}
|
|
1960
|
+
>
|
|
1961
|
+
<div className={`${styles.modalwrap} ${styles['top--modal']}`}>
|
|
1962
|
+
<div className={styles.modal}>
|
|
1963
|
+
<div className={styles.modal__header}>
|
|
1964
|
+
<h1>Edit Canvas</h1>
|
|
1965
|
+
<button
|
|
1966
|
+
className={styles.modal__close}
|
|
1967
|
+
onClick={() => setCanvasPopupOpen(false)}
|
|
1968
|
+
>
|
|
1969
|
+
<CircleX size={24} color="#FFF" />
|
|
1970
|
+
</button>
|
|
1971
|
+
</div>
|
|
1972
|
+
<div
|
|
1973
|
+
className={`${styles.modal__content} ${styles.drawDiv}`}
|
|
1974
|
+
>
|
|
1975
|
+
{/* Sketch Tools */}
|
|
1976
|
+
<ul className={styles.drawactions}>
|
|
1977
|
+
<li>
|
|
1978
|
+
<button
|
|
1979
|
+
onClick={() => {
|
|
1980
|
+
handleCanvasSave();
|
|
1981
|
+
}}
|
|
1982
|
+
className={styles['drawactions--save']}
|
|
1983
|
+
>
|
|
1984
|
+
<CloudDownload size={16} /> Save
|
|
1985
|
+
</button>
|
|
1986
|
+
</li>
|
|
1987
|
+
<li>
|
|
1988
|
+
<button
|
|
1989
|
+
onClick={() => {
|
|
1990
|
+
setSketchTool(Tools.Pencil);
|
|
1991
|
+
setToolClass('pencil');
|
|
1992
|
+
}}
|
|
1993
|
+
className={`${
|
|
1994
|
+
styles['drawaction-pencil']
|
|
1995
|
+
} ${
|
|
1996
|
+
toolClass === 'pencil'
|
|
1997
|
+
? styles['drawactive']
|
|
1998
|
+
: ''
|
|
1999
|
+
}`}
|
|
2000
|
+
>
|
|
2001
|
+
<Edit size={16} /> Pencil
|
|
2002
|
+
</button>
|
|
2003
|
+
</li>
|
|
2004
|
+
<li>
|
|
2005
|
+
<button
|
|
2006
|
+
onClick={() => {
|
|
2007
|
+
setSketchTool(Tools.Line);
|
|
2008
|
+
|
|
2009
|
+
setToolClass('line');
|
|
2010
|
+
}}
|
|
2011
|
+
className={`${
|
|
2012
|
+
styles['drawaction-line']
|
|
2013
|
+
} ${
|
|
2014
|
+
toolClass === 'line'
|
|
2015
|
+
? styles['drawactive']
|
|
2016
|
+
: ''
|
|
2017
|
+
}`}
|
|
2018
|
+
>
|
|
2019
|
+
<Minus size={16} /> Line
|
|
2020
|
+
</button>
|
|
2021
|
+
</li>
|
|
2022
|
+
<li>
|
|
2023
|
+
<button
|
|
2024
|
+
onClick={() => {
|
|
2025
|
+
setSketchTool(Tools.Circle);
|
|
2026
|
+
|
|
2027
|
+
setToolClass('circle');
|
|
2028
|
+
}}
|
|
2029
|
+
className={`${
|
|
2030
|
+
styles['drawaction-circle']
|
|
2031
|
+
} ${
|
|
2032
|
+
toolClass === 'circle'
|
|
2033
|
+
? styles['drawactive']
|
|
2034
|
+
: ''
|
|
2035
|
+
}`}
|
|
2036
|
+
>
|
|
2037
|
+
<Circle size={16} /> Circle
|
|
2038
|
+
</button>
|
|
2039
|
+
</li>
|
|
2040
|
+
<li>
|
|
2041
|
+
<button
|
|
2042
|
+
onClick={() => sketchRef.current.undo()}
|
|
2043
|
+
className={styles['drawaction-undo']}
|
|
2044
|
+
>
|
|
2045
|
+
<ArrowBack size={16} /> Undo
|
|
2046
|
+
</button>
|
|
2047
|
+
</li>
|
|
2048
|
+
<li>
|
|
2049
|
+
<button
|
|
2050
|
+
onClick={() =>
|
|
2051
|
+
sketchRef.current.clearCanvas()
|
|
2052
|
+
}
|
|
2053
|
+
className={styles['drawactions--clear']}
|
|
2054
|
+
>
|
|
2055
|
+
<TrashCan size={16} /> Clear
|
|
2056
|
+
</button>
|
|
2057
|
+
</li>
|
|
2058
|
+
</ul>
|
|
2059
|
+
{(canvasUrl || inputValue.state) && (
|
|
2060
|
+
<SketchField
|
|
2061
|
+
ref={sketchRef}
|
|
2062
|
+
width={740}
|
|
2063
|
+
height={800}
|
|
2064
|
+
tool={sketchTool}
|
|
2065
|
+
lineColor={lineColor}
|
|
2066
|
+
lineWidth={lineWidth}
|
|
2067
|
+
className={styles.drawcontainer}
|
|
2068
|
+
backgroundImage={canvasUrl}
|
|
2069
|
+
defaultValue={inputValue.state || null}
|
|
2070
|
+
/>
|
|
2071
|
+
)}
|
|
2072
|
+
</div>
|
|
2073
|
+
</div>
|
|
2074
|
+
</div>
|
|
2075
|
+
</Popup>
|
|
1906
2076
|
</div>
|
|
1907
2077
|
);
|
|
1908
2078
|
}
|
|
@@ -151,6 +151,8 @@ function Form({
|
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
+
const handleChangeCanvas = (id, value) => {};
|
|
155
|
+
|
|
154
156
|
const handleChangeCheckbox = (e) => {
|
|
155
157
|
const { checked, name, value } = e.target;
|
|
156
158
|
|
|
@@ -1367,15 +1369,18 @@ function Form({
|
|
|
1367
1369
|
);
|
|
1368
1370
|
} else {
|
|
1369
1371
|
return (
|
|
1370
|
-
<div className=
|
|
1371
|
-
<div className=
|
|
1372
|
-
<div className=
|
|
1372
|
+
<div className={`${styles.modalwrap} ${styles['top--modal']}`}>
|
|
1373
|
+
<div className={styles.modal}>
|
|
1374
|
+
<div className={styles.modal__header}>
|
|
1373
1375
|
<h1>{formSettings[formType]?.title}</h1>
|
|
1374
|
-
<button
|
|
1376
|
+
<button
|
|
1377
|
+
className={styles.modal__close}
|
|
1378
|
+
onClick={closeModal}
|
|
1379
|
+
>
|
|
1375
1380
|
<CircleX strokeWidth={1} size={24} />
|
|
1376
1381
|
</button>
|
|
1377
1382
|
</div>
|
|
1378
|
-
<div className=
|
|
1383
|
+
<div className={styles.modal__content}>
|
|
1379
1384
|
<div className={styles.formcontainer}>
|
|
1380
1385
|
<form className={styles.modalForm}>
|
|
1381
1386
|
{formSettings?.fields?.map((item, index) => {
|
|
@@ -1426,6 +1431,7 @@ function Form({
|
|
|
1426
1431
|
}
|
|
1427
1432
|
mapbox={mapbox}
|
|
1428
1433
|
onChange={handleChange}
|
|
1434
|
+
onChangeCanvas={handleChangeCanvas}
|
|
1429
1435
|
onChangeCheckbox={
|
|
1430
1436
|
handleChangeCheckbox
|
|
1431
1437
|
}
|
|
@@ -31,6 +31,8 @@ const updateField = (fields, name, value) => {
|
|
|
31
31
|
|
|
32
32
|
const renderValue = (field, data) => {
|
|
33
33
|
switch (field.type) {
|
|
34
|
+
case 'canvas':
|
|
35
|
+
return field.value || '';
|
|
34
36
|
case 'datetime':
|
|
35
37
|
case 'date':
|
|
36
38
|
return field.value && moment(field.value).isValid()
|
|
@@ -103,6 +105,7 @@ const GenericDynamic = ({
|
|
|
103
105
|
}) => {
|
|
104
106
|
const [activeForm, setActiveForm] = useState({});
|
|
105
107
|
const [activeFormKey, setActiveFormKey] = useState(0);
|
|
108
|
+
const [canvasSaveCounter, setCanvasSaveCounter] = useState(0);
|
|
106
109
|
|
|
107
110
|
const handleChange = (e) => {
|
|
108
111
|
const {
|
|
@@ -174,6 +177,36 @@ const GenericDynamic = ({
|
|
|
174
177
|
}
|
|
175
178
|
};
|
|
176
179
|
|
|
180
|
+
const handleChangeCanvas = (fieldSetting, value, imageData) => {
|
|
181
|
+
// Check if activeForm has keys
|
|
182
|
+
if (activeForm && typeof activeForm === 'object') {
|
|
183
|
+
// Iterate over the keys in activeForm to find the matching id
|
|
184
|
+
for (const key in activeForm) {
|
|
185
|
+
if (activeForm[key].id === fieldSetting.id) {
|
|
186
|
+
// If a matching id is found, update the corresponding field
|
|
187
|
+
setActiveForm((prevState) => ({
|
|
188
|
+
...prevState,
|
|
189
|
+
[key]: {
|
|
190
|
+
...prevState[key],
|
|
191
|
+
value, // Update the value for the matching id
|
|
192
|
+
imageData,
|
|
193
|
+
},
|
|
194
|
+
}));
|
|
195
|
+
|
|
196
|
+
setCanvasSaveCounter((prevState) => prevState + 1);
|
|
197
|
+
return; // Exit after updating to prevent further iterations
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
useEffect(() => {
|
|
204
|
+
if (canvasSaveCounter > 0) {
|
|
205
|
+
console.info(activeForm);
|
|
206
|
+
handleSaveForm(false);
|
|
207
|
+
}
|
|
208
|
+
}, [canvasSaveCounter]);
|
|
209
|
+
|
|
177
210
|
const handleChangeCheckbox = (e) => {
|
|
178
211
|
const { checked, name, value } = e.target;
|
|
179
212
|
|
|
@@ -247,33 +280,20 @@ const GenericDynamic = ({
|
|
|
247
280
|
return prevActiveForm;
|
|
248
281
|
}
|
|
249
282
|
|
|
250
|
-
// Create a
|
|
283
|
+
// Create a shallow copy of rows to target only the necessary updates
|
|
251
284
|
const updatedRows = prevActiveForm[formKey].rows.map((row) => {
|
|
252
285
|
if (row.id === rowId) {
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
} else if (
|
|
258
|
-
type === 'date' ||
|
|
259
|
-
type === 'time' ||
|
|
260
|
-
type === 'text'
|
|
261
|
-
) {
|
|
262
|
-
newValue = { ...row.value, [columnId]: value };
|
|
263
|
-
} else {
|
|
264
|
-
// For other input types, use the value directly
|
|
265
|
-
newValue = { ...row.value, [columnId]: value };
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
return {
|
|
269
|
-
...row,
|
|
270
|
-
value: newValue,
|
|
286
|
+
// Update only the specific cell in the target row
|
|
287
|
+
const newValue = {
|
|
288
|
+
...row.value,
|
|
289
|
+
[columnId]: type === 'checkbox' ? checked : value,
|
|
271
290
|
};
|
|
291
|
+
return { ...row, value: newValue }; // Return the updated row
|
|
272
292
|
}
|
|
273
|
-
return row;
|
|
293
|
+
return row; // Return other rows unchanged
|
|
274
294
|
});
|
|
275
295
|
|
|
276
|
-
//
|
|
296
|
+
// Update only the formKey section of activeForm
|
|
277
297
|
return {
|
|
278
298
|
...prevActiveForm,
|
|
279
299
|
[formKey]: {
|
|
@@ -563,27 +583,29 @@ const GenericDynamic = ({
|
|
|
563
583
|
});
|
|
564
584
|
};
|
|
565
585
|
|
|
566
|
-
const handleSaveForm = async () => {
|
|
586
|
+
const handleSaveForm = async (validate = true) => {
|
|
567
587
|
try {
|
|
568
588
|
let error = '';
|
|
569
589
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
590
|
+
if (validate) {
|
|
591
|
+
const excludedTypes = [
|
|
592
|
+
'dynamicdata',
|
|
593
|
+
'plaintext',
|
|
594
|
+
'plaintextheading',
|
|
595
|
+
'section',
|
|
596
|
+
'table_radio',
|
|
597
|
+
];
|
|
577
598
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
599
|
+
Object.entries(activeForm).forEach(([key, field]) => {
|
|
600
|
+
if (
|
|
601
|
+
field.required === true &&
|
|
602
|
+
!excludedTypes.includes(field.type) &&
|
|
603
|
+
(field.value === null || field.value === '')
|
|
604
|
+
) {
|
|
605
|
+
error += `<p>${field.label} is required</p>`;
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
}
|
|
587
609
|
|
|
588
610
|
if (error === '') {
|
|
589
611
|
const res = await CustomFetch(setting.save, 'POST', {
|
|
@@ -849,6 +871,9 @@ const GenericDynamic = ({
|
|
|
849
871
|
onChange={
|
|
850
872
|
handleChange
|
|
851
873
|
}
|
|
874
|
+
onChangeCanvas={
|
|
875
|
+
handleChangeCanvas
|
|
876
|
+
}
|
|
852
877
|
onChangeCheckbox={
|
|
853
878
|
handleChangeCheckbox
|
|
854
879
|
}
|
|
@@ -897,6 +922,9 @@ const GenericDynamic = ({
|
|
|
897
922
|
originalData
|
|
898
923
|
)}
|
|
899
924
|
onChange={handleChange}
|
|
925
|
+
onChangeCanvas={
|
|
926
|
+
handleChangeCanvas
|
|
927
|
+
}
|
|
900
928
|
onChangeCheckbox={
|
|
901
929
|
handleChangeCheckbox
|
|
902
930
|
}
|
|
@@ -8,7 +8,7 @@ import Toggle from 'react-toggle';
|
|
|
8
8
|
import { toast } from 'react-toastify';
|
|
9
9
|
import { v4 as uuidv4 } from 'uuid';
|
|
10
10
|
import { Editor } from '@tinymce/tinymce-react';
|
|
11
|
-
import {
|
|
11
|
+
import { CirclePlus, CircleX, TrashCan } from 'akar-icons';
|
|
12
12
|
|
|
13
13
|
import 'react-toggle/style.css';
|
|
14
14
|
import 'react-datepicker/dist/react-datepicker.css';
|
|
@@ -17,6 +17,7 @@ import 'react-confirm-alert/src/react-confirm-alert.css';
|
|
|
17
17
|
import Breadcrumb from '../Breadcrumb';
|
|
18
18
|
import CustomFetch from '../Fetch';
|
|
19
19
|
import SortableList from '../../../components/cms/sorting/List';
|
|
20
|
+
import SketchConfig from '../sketch/json/config.json';
|
|
20
21
|
|
|
21
22
|
import styles from './styles/GenericFormBuilder.module.scss'; // Import the CSS module
|
|
22
23
|
|
|
@@ -44,7 +45,8 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
|
|
|
44
45
|
label: '',
|
|
45
46
|
type: '',
|
|
46
47
|
});
|
|
47
|
-
const [fieldTypes
|
|
48
|
+
const [fieldTypes] = useState([
|
|
49
|
+
{ value: 'canvas', label: 'Canvas' },
|
|
48
50
|
{ value: 'checkbox', label: 'Checkbox' },
|
|
49
51
|
{ value: 'html5_date', label: 'Date' },
|
|
50
52
|
{ value: 'html5_datetime', label: 'Date & Time' },
|
|
@@ -78,6 +80,7 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
|
|
|
78
80
|
});
|
|
79
81
|
const [modalFormShow, setModalFormShow] = useState(false);
|
|
80
82
|
const [roles, setRoles] = useState([]);
|
|
83
|
+
const canvasTypes = SketchConfig.canvasTypes;
|
|
81
84
|
|
|
82
85
|
/** Data Option Functionalities */
|
|
83
86
|
const handleDataOption = (e) => {
|
|
@@ -428,6 +431,21 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
|
|
|
428
431
|
|
|
429
432
|
const renderField = (field) => {
|
|
430
433
|
switch (field.type) {
|
|
434
|
+
case 'canvas':
|
|
435
|
+
const canvasType = canvasTypes.find(
|
|
436
|
+
(item) => item.id === field.canvasType
|
|
437
|
+
);
|
|
438
|
+
return (
|
|
439
|
+
<label className={`${styles.fi__label}`}>
|
|
440
|
+
<span
|
|
441
|
+
className={`${styles.fi__span} ${styles.prefocus}`}
|
|
442
|
+
>
|
|
443
|
+
{field.label}{' '}
|
|
444
|
+
{field.required === 'yes' ? '*' : null}
|
|
445
|
+
</span>
|
|
446
|
+
<img src={canvasType.url} width="200" />
|
|
447
|
+
</label>
|
|
448
|
+
);
|
|
431
449
|
case 'checkbox':
|
|
432
450
|
return (
|
|
433
451
|
<label className={styles.fi__label}>
|
|
@@ -1679,6 +1697,46 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
|
|
|
1679
1697
|
</div>
|
|
1680
1698
|
) : null}
|
|
1681
1699
|
|
|
1700
|
+
{['canvas'].includes(dataField.type) ? (
|
|
1701
|
+
<div className={styles.formItem}>
|
|
1702
|
+
<label className={styles.fi__label}>
|
|
1703
|
+
<select
|
|
1704
|
+
name="canvasType"
|
|
1705
|
+
value={dataField.canvasType}
|
|
1706
|
+
onChange={handleChangeForm}
|
|
1707
|
+
>
|
|
1708
|
+
<option>
|
|
1709
|
+
Please select a type
|
|
1710
|
+
</option>
|
|
1711
|
+
{canvasTypes.map(
|
|
1712
|
+
(
|
|
1713
|
+
canvasType,
|
|
1714
|
+
canvasTypeKey
|
|
1715
|
+
) => (
|
|
1716
|
+
<option
|
|
1717
|
+
value={
|
|
1718
|
+
canvasType.id
|
|
1719
|
+
}
|
|
1720
|
+
key={
|
|
1721
|
+
canvasTypeKey
|
|
1722
|
+
}
|
|
1723
|
+
>
|
|
1724
|
+
{
|
|
1725
|
+
canvasType.label
|
|
1726
|
+
}
|
|
1727
|
+
</option>
|
|
1728
|
+
)
|
|
1729
|
+
)}
|
|
1730
|
+
</select>
|
|
1731
|
+
<span
|
|
1732
|
+
className={styles.fi__span}
|
|
1733
|
+
>
|
|
1734
|
+
Canvas Type
|
|
1735
|
+
</span>
|
|
1736
|
+
</label>
|
|
1737
|
+
</div>
|
|
1738
|
+
) : null}
|
|
1739
|
+
|
|
1682
1740
|
{['signature'].includes(dataField.type) ? (
|
|
1683
1741
|
<div className={styles.formItem}>
|
|
1684
1742
|
<label className={styles.fi__label}>
|