@visns-studio/visns-components 4.7.0 → 4.7.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.
Files changed (110) hide show
  1. package/dist/104e5636d8ddb791614c.woff2 +0 -0
  2. package/dist/11fe6a83d647de5daf95.woff +0 -0
  3. package/dist/141e2a8c7836495afe2a.woff +0 -0
  4. package/dist/2ba5877f7079830b5383.woff +0 -0
  5. package/dist/2d6836f45b2037be41f3.woff +0 -0
  6. package/dist/399.0a0f3e0d21be1057d599.css +8 -0
  7. package/dist/399.b8f57fa3f8c0c10119e4.js +1 -0
  8. package/dist/47d566c3b1293dfd9d77.woff +0 -0
  9. package/dist/6282a13cbba671a71913.woff2 +0 -0
  10. package/dist/78266f551031aa9db127.woff +0 -0
  11. package/dist/7b7da89f1e3fdcbfe36c.woff2 +0 -0
  12. package/dist/7e78e8338af7efeda712.woff2 +0 -0
  13. package/dist/7fa387951673abf164b1.woff2 +0 -0
  14. package/dist/819d59862c2d0640aad8.woff +0 -0
  15. package/dist/b615e1a6c838ea059a56.woff +0 -0
  16. package/dist/b9b1aa739c660c4ce67c.woff2 +0 -0
  17. package/dist/c5f3640b11df9414facb.woff +0 -0
  18. package/dist/da26d162ff5af71d6590.woff2 +0 -0
  19. package/dist/dd5b2912dbf896310865.woff2 +0 -0
  20. package/dist/f282b331272463c1aa6c.woff2 +0 -0
  21. package/dist/index.css +2902 -0
  22. package/dist/index.js +2 -0
  23. package/dist/index.js.LICENSE.txt +150 -0
  24. package/dist/main.83b033670d64419bb497.css +1 -0
  25. package/dist/main.b1723d17cd2d3513ab62.js +1 -0
  26. package/dist/report.html +39 -0
  27. package/dist/runtime.33c276593b23f8035b8d.js +1 -0
  28. package/package.json +26 -6
  29. package/.idea/codeStyles/Project.xml +0 -50
  30. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  31. package/.idea/deployment.xml +0 -4
  32. package/.idea/modules.xml +0 -8
  33. package/.idea/php.xml +0 -19
  34. package/.idea/vcs.xml +0 -6
  35. package/.idea/visns-components.iml +0 -8
  36. package/.prettierrc.json +0 -7
  37. package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +0 -541
  38. package/.yarn/releases/yarn-3.6.1.cjs +0 -874
  39. package/.yarnrc.yml +0 -7
  40. package/components/cms/DataGrid.jsx +0 -1461
  41. package/components/cms/DropZone.jsx +0 -349
  42. package/components/cms/Field.jsx +0 -802
  43. package/components/cms/Form.jsx +0 -476
  44. package/components/cms/generic/CmsDetail.jsx +0 -36
  45. package/components/cms/generic/CmsIndex.jsx +0 -73
  46. package/components/cms/generic/CmsSort.jsx +0 -125
  47. package/components/cms/sorting/Item.jsx +0 -115
  48. package/components/cms/sorting/List.jsx +0 -30
  49. package/components/crm/AsyncSelect.jsx +0 -125
  50. package/components/crm/Autocomplete.jsx +0 -174
  51. package/components/crm/Breadcrumb.jsx +0 -52
  52. package/components/crm/Call.jsx +0 -220
  53. package/components/crm/DataGrid.jsx +0 -2701
  54. package/components/crm/Download.jsx +0 -101
  55. package/components/crm/Fetch.jsx +0 -119
  56. package/components/crm/Field.jsx +0 -1557
  57. package/components/crm/Form.jsx +0 -1409
  58. package/components/crm/Loader.jsx +0 -29
  59. package/components/crm/MultiSelect.jsx +0 -78
  60. package/components/crm/Navigation.jsx +0 -619
  61. package/components/crm/Notification.jsx +0 -197
  62. package/components/crm/QrCode.jsx +0 -83
  63. package/components/crm/Select.jsx +0 -58
  64. package/components/crm/SelectList.jsx +0 -21
  65. package/components/crm/TableFilter.jsx +0 -198
  66. package/components/crm/auth/Login.jsx +0 -223
  67. package/components/crm/auth/Profile.jsx +0 -280
  68. package/components/crm/auth/Reset.jsx +0 -111
  69. package/components/crm/auth/Verify.jsx +0 -174
  70. package/components/crm/auth/styles/Login.module.css +0 -243
  71. package/components/crm/auth/styles/Profile.module.css +0 -222
  72. package/components/crm/auth/styles/Reset.module.css +0 -216
  73. package/components/crm/auth/styles/Verify.module.css +0 -216
  74. package/components/crm/generic/AuditLog.jsx +0 -108
  75. package/components/crm/generic/AuditLogs.jsx +0 -115
  76. package/components/crm/generic/GenericAuth.jsx +0 -166
  77. package/components/crm/generic/GenericDashboard.jsx +0 -42
  78. package/components/crm/generic/GenericDetail.jsx +0 -1499
  79. package/components/crm/generic/GenericDynamic.jsx +0 -915
  80. package/components/crm/generic/GenericFormBuilder.jsx +0 -1765
  81. package/components/crm/generic/GenericIndex.jsx +0 -376
  82. package/components/crm/generic/GenericMain.jsx +0 -129
  83. package/components/crm/generic/GenericSort.jsx +0 -188
  84. package/components/crm/generic/NotificationList.jsx +0 -64
  85. package/components/crm/generic/styles/AuditLog.module.css +0 -147
  86. package/components/crm/generic/styles/AuditLogs.module.css +0 -92
  87. package/components/crm/generic/styles/GenericDetail.module.css +0 -634
  88. package/components/crm/generic/styles/GenericDynamic.module.css +0 -932
  89. package/components/crm/generic/styles/GenericFormBuilder.module.css +0 -944
  90. package/components/crm/generic/styles/GenericIndex.module.css +0 -247
  91. package/components/crm/generic/styles/GenericMain.module.css +0 -91
  92. package/components/crm/generic/styles/GenericSort.module.css +0 -123
  93. package/components/crm/generic/styles/NotificationList.module.css +0 -67
  94. package/components/crm/sorting/Item.jsx +0 -117
  95. package/components/crm/sorting/List.jsx +0 -32
  96. package/components/crm/sorting/styles/Item.module.css +0 -68
  97. package/components/crm/sorting/styles/List.module.css +0 -68
  98. package/components/crm/styles/AsyncSelect.module.css +0 -8
  99. package/components/crm/styles/Autocomplete.module.css +0 -44
  100. package/components/crm/styles/DataGrid.module.css +0 -210
  101. package/components/crm/styles/Field.module.css +0 -311
  102. package/components/crm/styles/Form.module.css +0 -499
  103. package/components/crm/styles/Loader.module.css +0 -94
  104. package/components/crm/styles/MultiSelect.module.css +0 -8
  105. package/components/crm/styles/Navigation.module.css +0 -978
  106. package/components/crm/styles/Notification.module.css +0 -147
  107. package/components/crm/styles/QrCode.module.css +0 -87
  108. package/components/crm/styles/TableFilter.module.css +0 -52
  109. package/components/styles/global.css +0 -73
  110. package/index.js +0 -86
@@ -1,1409 +0,0 @@
1
- import '../styles/global.css';
2
-
3
- import React, { useState, useEffect } from 'react';
4
- import { useNavigate } from 'react-router-dom';
5
- import { motion } from 'framer-motion';
6
- import { toast } from 'react-toastify';
7
- import { saveAs } from 'file-saver';
8
- import moment from 'moment';
9
- import parse from 'html-react-parser';
10
- import _ from 'lodash';
11
- import ReactDataGrid from '@inovua/reactdatagrid-community';
12
- import { CircleX } from 'akar-icons';
13
- import { confirmAlert } from 'react-confirm-alert';
14
-
15
- import '@inovua/reactdatagrid-community/index.css';
16
- import 'react-confirm-alert/src/react-confirm-alert.css';
17
-
18
- import CustomFetch from './Fetch';
19
- import Download from './Download';
20
- import Field from './Field';
21
- import Table from './DataGrid';
22
-
23
- import styles from './styles/Form.module.css';
24
-
25
- function Form({
26
- ajaxSetting,
27
- api,
28
- closeModal,
29
- columnId,
30
- formType,
31
- formSettings,
32
- fetchTable,
33
- mapbox,
34
- modalOpen,
35
- paramValue,
36
- style,
37
- type,
38
- updateForm,
39
- userProfile,
40
- }) {
41
- const navigate = useNavigate();
42
- const [fetchTrigger, setFetchTrigger] = useState(false);
43
- const [formData, setFormData] = useState({});
44
- const [inputClass, setInputClass] = useState({});
45
- const [tableData, setTableData] = useState({ columns: [], dataSource: [] });
46
- const [uploadProgress, setUploadProgress] = useState(0);
47
-
48
- const childDropdownCallback = (data) => {
49
- let _form = { ...formSettings };
50
-
51
- if (formSettings.fields.length > 0) {
52
- formSettings.fields.forEach((a, b) => {
53
- if (a.id === data.id) {
54
- _form.fields[b].options = data.data;
55
- }
56
- });
57
- }
58
-
59
- if (updateForm) {
60
- updateForm(_form);
61
- }
62
- };
63
-
64
- const handleChange = (e) => {
65
- const id = e.target.dataset.jsonkey || e.target.dataset.name;
66
- const value = e.target.value;
67
- const parent = e.target.dataset.parent ? e.target.dataset.parent : '';
68
- let _dataset = {};
69
-
70
- if (e.target[e.target.selectedIndex]) {
71
- _dataset = e.target[e.target.selectedIndex].dataset;
72
- }
73
-
74
- if (e.target.files) {
75
- setFormData((prevState) => ({
76
- ...prevState,
77
- [id]:
78
- e.target.files.length > 1
79
- ? Array.from(e.target.files)
80
- : e.target.files[0],
81
- }));
82
- } else {
83
- if (parent) {
84
- setFormData((prevState) => ({
85
- ...prevState,
86
- [parent]: {
87
- ...prevState[parent],
88
- [id]: value,
89
- },
90
- }));
91
- } else {
92
- setFormData((prevState) => ({
93
- ...prevState,
94
- [id]: value,
95
- }));
96
- }
97
- }
98
-
99
- if (!_.isEmpty(_dataset)) {
100
- Object.keys(_dataset).forEach((c) => {
101
- if (formData.hasOwnProperty(c)) {
102
- setFormData((prevState) => ({
103
- ...prevState,
104
- [c]: _dataset[c],
105
- }));
106
- }
107
- });
108
- }
109
-
110
- if (e.target.dataset.hasOwnProperty('show')) {
111
- const _show =
112
- e.target.dataset.show !== ''
113
- ? JSON.parse(e.target.dataset.show)
114
- : [];
115
-
116
- if (_show.length > 0) {
117
- _show.forEach((showObject) => {
118
- if (
119
- showObject.hasOwnProperty('id') &&
120
- showObject.hasOwnProperty('value')
121
- ) {
122
- if (
123
- showObject.id !== '' &&
124
- showObject.value.length > 0
125
- ) {
126
- const _fields = formSettings.fields;
127
- let _counter;
128
- _fields.forEach((a, b) => {
129
- if (a.id === showObject.id) {
130
- _counter = b;
131
- }
132
- });
133
-
134
- const _valueChecker = parseInt(e.target.value);
135
-
136
- _fields[_counter].hide = !(
137
- _counter >= 0 &&
138
- showObject.value.includes(_valueChecker)
139
- );
140
-
141
- if (updateForm) {
142
- updateForm((prevState) => ({
143
- ...prevState,
144
- fields: _fields,
145
- }));
146
- }
147
- }
148
- }
149
- });
150
- }
151
- }
152
- };
153
-
154
- const handleChangeCheckbox = (e) => {
155
- const { checked, name, value } = e.target;
156
-
157
- setFormData((prevFormData) => ({
158
- ...prevFormData,
159
- [name]: checked
160
- ? [...prevFormData.options, value]
161
- : prevFormData.options.filter((item) => item !== value),
162
- }));
163
- };
164
-
165
- const handleChangeColour = (event, color, id) => {
166
- if (color && event && id) {
167
- setFormData((prevState) => ({
168
- ...prevState,
169
- [id]: color.hex,
170
- }));
171
- }
172
- };
173
-
174
- const handleChangeNumberFormat = (value, id) => {
175
- setFormData((prevState) => ({
176
- ...prevState,
177
- [id]: value.value,
178
- }));
179
- };
180
-
181
- const handleChangeDate = (date, id) => {
182
- setFormData((prevState) => ({
183
- ...prevState,
184
- [id]: date,
185
- }));
186
- };
187
-
188
- const handleChangeRicheditor = (e, value, id) => {
189
- if (e) {
190
- setFormData((prevState) => ({
191
- ...prevState,
192
- [id]: value,
193
- }));
194
- }
195
- };
196
-
197
- const handleChangeSelect = (inputValue, action, id) => {
198
- const updateFormData = (update) => {
199
- setFormData((prevState) => ({
200
- ...prevState,
201
- ...update,
202
- }));
203
- };
204
-
205
- switch (action.action) {
206
- case 'select-option':
207
- updateFormData({ [id]: inputValue });
208
-
209
- Object.keys(inputValue).forEach((a) => {
210
- if (formData.hasOwnProperty(a)) {
211
- updateFormData({ [a]: inputValue[a] });
212
- }
213
- });
214
-
215
- formSettings.fields.forEach((f) => {
216
- if (f.id === id && f.trigger) {
217
- switch (f.trigger.type) {
218
- case 'addDays':
219
- let newDate = moment();
220
- let add = false;
221
-
222
- if (
223
- inputValue.no_of_days &&
224
- parseFloat(inputValue.no_of_days) > 0
225
- ) {
226
- newDate.add(
227
- parseFloat(inputValue.no_of_days),
228
- 'days'
229
- );
230
- add = true;
231
- }
232
-
233
- if (
234
- inputValue.no_of_hours &&
235
- parseFloat(inputValue.no_of_hours) > 0
236
- ) {
237
- newDate.add(
238
- parseFloat(inputValue.no_of_hours),
239
- 'hours'
240
- );
241
- add = true;
242
- }
243
-
244
- if (add) {
245
- updateFormData({
246
- [f.trigger.id]: newDate.toDate(),
247
- });
248
- }
249
- break;
250
- case 'setContent':
251
- updateFormData({
252
- [f.trigger.id]: inputValue[f.trigger.key],
253
- });
254
- break;
255
- }
256
- }
257
- });
258
- break;
259
- case 'clear':
260
- updateFormData({ [id]: '' });
261
- break;
262
- case 'remove-value':
263
- updateFormData({ [id]: inputValue });
264
- break;
265
- }
266
- };
267
-
268
- const handleChangeSignature = (e) => {
269
- if (e) {
270
- e.preventDefault();
271
- }
272
-
273
- console.info(`Debug Mode: ${userProfile}`);
274
- };
275
-
276
- const handleChangeToggle = (e) => {
277
- if (!e) {
278
- return;
279
- }
280
-
281
- const id = e.target.dataset.jsonkey || e.target.dataset.name;
282
-
283
- if (formData.hasOwnProperty(id)) {
284
- setFormData((prevState) => ({
285
- ...prevState,
286
- [id]: e.target.checked,
287
- }));
288
- }
289
-
290
- const updateFormData = (dataToUpdate) => {
291
- setFormData((prevState) => ({
292
- ...prevState,
293
- ...dataToUpdate,
294
- }));
295
- };
296
-
297
- const updatePostalData = (checked) => {
298
- const postalData = checked
299
- ? {
300
- postal_address1: formData.address1,
301
- postal_address2: formData.address2,
302
- postal_suburb: formData.suburb,
303
- postal_postcode: formData.postcode,
304
- postal_state: formData.state,
305
- postal_country: formData.country,
306
- }
307
- : {
308
- postal_address1: '',
309
- postal_address2: '',
310
- postal_suburb: '',
311
- postal_postcode: '',
312
- postal_state: '',
313
- postal_country: '',
314
- };
315
-
316
- updateFormData(postalData);
317
- };
318
-
319
- if (id === 'same_address') {
320
- updatePostalData(e.target.checked);
321
- }
322
-
323
- if (e.target.dataset.show) {
324
- const _show = e.target.dataset.show
325
- ? JSON.parse(e.target.dataset.show)
326
- : [];
327
-
328
- if (_show.length > 0) {
329
- const updatedFields = formSettings.fields.map((field) => {
330
- const showObject = _show.find(
331
- (showItem) => showItem.id === field.id
332
- );
333
- if (
334
- showObject &&
335
- showObject.value &&
336
- showObject.value.length > 0
337
- ) {
338
- field.hide = !showObject.value.includes(
339
- e.target.checked
340
- );
341
- }
342
- return field;
343
- });
344
-
345
- if (updateForm) {
346
- updateForm((prevState) => ({
347
- ...prevState,
348
- fields: updatedFields,
349
- }));
350
- }
351
- }
352
- }
353
- };
354
-
355
- const handleFileDownload = async (d) => {
356
- try {
357
- console.info(d);
358
- } catch (error) {
359
- console.error(error);
360
- }
361
- };
362
-
363
- const autocompleteSelect = (place, id) => {
364
- const { address, text, context } = place;
365
-
366
- const address1 = address
367
- ? text
368
- ? `${address} ${text}`
369
- : address
370
- : text;
371
- const address2 = '';
372
- const suburb = context[1]?.text || '';
373
- const postcode = context[0]?.text || '';
374
-
375
- const [state, country] =
376
- context.length === 5
377
- ? [context[3]?.text, context[4]?.text]
378
- : [context[2]?.text, context[3]?.text];
379
-
380
- const formDataUpdate = {
381
- address1,
382
- address2,
383
- suburb,
384
- postcode,
385
- state,
386
- country,
387
- };
388
-
389
- if (formData.same_address === true || id !== 'address1') {
390
- Object.assign(formDataUpdate, {
391
- postal_address1: address1,
392
- postal_address2: address2,
393
- postal_suburb: suburb,
394
- postal_postcode: postcode,
395
- postal_state: state,
396
- postal_country: country,
397
- });
398
- }
399
-
400
- setFormData((prevState) => ({
401
- ...prevState,
402
- ...formDataUpdate,
403
- }));
404
- };
405
-
406
- const parseTableData = (d) => {
407
- const dataSource = d;
408
- const keys = Object.keys(dataSource[0]);
409
- let columns = [];
410
-
411
- keys.forEach((key) => {
412
- columns.push({
413
- name: key,
414
- header: transformKey(key),
415
- defaultFlex: 1,
416
- });
417
- });
418
-
419
- return { columns, dataSource };
420
- };
421
-
422
- const renderInputValue = (i, f) => {
423
- let value = '';
424
-
425
- if (i.hasOwnProperty('parent') && i.parent) {
426
- if (f[i.parent]) {
427
- value = i.hasOwnProperty('key')
428
- ? f[i.parent][i.key]
429
- : f[i.parent][i.id];
430
- }
431
- } else {
432
- value = i.hasOwnProperty('key') ? f[i.key] : f[i.id];
433
- }
434
-
435
- return value;
436
- };
437
-
438
- // Helper function to transform snake_case to Title Case
439
- const transformKey = (key) => {
440
- return key
441
- .replace(/_/g, ' ')
442
- .split(' ')
443
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
444
- .join(' ');
445
- };
446
-
447
- const handleDownload = async (e) => {
448
- try {
449
- if (e) {
450
- e.preventDefault();
451
- }
452
-
453
- const extension = formSettings.download.extension;
454
- const filename = formSettings.download.filename;
455
- const method = 'POST';
456
- const url = formSettings.download.url;
457
-
458
- const res = await Download(url, method, formData);
459
-
460
- const blob = new Blob([res.data], {
461
- type: 'application/octet-stream',
462
- });
463
- saveAs(blob, `${filename}.${extension}`);
464
- } catch (error) {
465
- console.error(error);
466
- }
467
- };
468
-
469
- const handleSort = async (e) => {
470
- try {
471
- if (e) {
472
- e.preventDefault();
473
- }
474
-
475
- const url = formSettings.sortButton.url;
476
- const method = 'POST';
477
-
478
- const res = await CustomFetch(url, method, {
479
- id: formData[formSettings.primaryKey],
480
- });
481
-
482
- if (res.data.error === '') {
483
- toast.success('Files successfully sorted by name.');
484
-
485
- fetchData();
486
- }
487
- } catch (err) {
488
- console.info(err);
489
- }
490
- };
491
-
492
- const handleCustom = async (s) => {
493
- const executeRequest = async () => {
494
- try {
495
- const url = formSettings.customButton.url;
496
- const method = 'POST';
497
-
498
- const res = await CustomFetch(url, method, {
499
- id: formData[formSettings.primaryKey],
500
- });
501
-
502
- if (res.data.error === '') {
503
- if (res.data.message) {
504
- toast.success(res.data.message);
505
- }
506
-
507
- fetchData();
508
- } else {
509
- toast.error(res.data.error);
510
- }
511
- } catch (error) {
512
- console.error('Request failed:', error);
513
- }
514
- };
515
-
516
- try {
517
- if (s.customButton.confirmation) {
518
- confirmAlert({
519
- title: '',
520
- message:
521
- s.customButton.confirmation.message ||
522
- 'Are you sure you want to proceed?',
523
- buttons: [
524
- {
525
- label: 'Yes',
526
- onClick: executeRequest,
527
- },
528
- {
529
- label: 'No',
530
- onClick: () => close(),
531
- },
532
- ],
533
- });
534
- } else {
535
- await executeRequest();
536
- }
537
- } catch (err) {
538
- console.error('An error occurred:', err);
539
- }
540
- };
541
-
542
- const handleSubmit = async (e) => {
543
- try {
544
- if (e) {
545
- e.preventDefault();
546
-
547
- const { type } = e.target.dataset;
548
- let fields = formSettings.fields;
549
- let _inputClass = inputClass;
550
- let validation = '';
551
-
552
- if (['create', 'update'].includes(formType)) {
553
- fields.forEach((item) => {
554
- if (formType === 'update' && item.createOnly) {
555
- return;
556
- }
557
-
558
- if (item.required) {
559
- if (!formData[item.id]) {
560
- if (
561
- item.hasOwnProperty('required_check') &&
562
- item.required_check &&
563
- !formData[item.required_check]
564
- ) {
565
- validation += `${item.label} is a required field.<br/>`;
566
- _inputClass[item.id] = styles.inputError;
567
- } else {
568
- validation += `${item.label} is a required field.<br/>`;
569
- _inputClass[item.id] = styles.inputError;
570
- }
571
- } else {
572
- _inputClass[item.id] = '';
573
- }
574
- } else if (
575
- item.hasOwnProperty('required_rely') &&
576
- item.required_rely &&
577
- formData[item.required_rely] &&
578
- !formData[item.id]
579
- ) {
580
- validation += `${item.label} is a required field.<br/>`;
581
- _inputClass[item.id] = styles.inputError;
582
- } else {
583
- _inputClass[item.id] = '';
584
- }
585
- });
586
-
587
- setInputClass(_inputClass);
588
- }
589
-
590
- if (validation) {
591
- toast.error(<div>{parse(validation)}</div>);
592
- } else {
593
- let url = formSettings.url;
594
- let method = 'POST';
595
- let fileUpload = false;
596
- let fileKey = '';
597
-
598
- if (formSettings.customUrl && formSettings.customMethod) {
599
- url = formSettings.customUrl;
600
- if (formSettings.customDataId) {
601
- url += `/${formData[formSettings.primaryKey]}`;
602
- }
603
- method = formSettings.customMethod;
604
- } else {
605
- switch (formType) {
606
- case 'create':
607
- if (formSettings.json) {
608
- url += '/jsonStore';
609
- }
610
- break;
611
- case 'update':
612
- case 'delete':
613
- if (formSettings.json) {
614
- url +=
615
- formType === 'update'
616
- ? '/jsonUpdate'
617
- : `/jsonDelete/${
618
- formData[
619
- formSettings.primaryKey
620
- ]
621
- }`;
622
- } else {
623
- url += `/${
624
- formData[formSettings.primaryKey]
625
- }`;
626
- }
627
- method =
628
- formType === 'update' ? 'PUT' : 'DELETE';
629
- break;
630
- }
631
- }
632
-
633
- if (!_.isEmpty(formData)) {
634
- Object.keys(formData).forEach((item) => {
635
- if (formData[item] instanceof File) {
636
- fileUpload = true;
637
- fileKey = item;
638
- }
639
- });
640
- }
641
-
642
- if (fileUpload && formData[fileKey]) {
643
- if (Array.isArray(formData[fileKey])) {
644
- const uploadPromises = formData[fileKey].map(
645
- async (file) => {
646
- const fileRes = await Vapor.store(file, {
647
- progress: (progress) => {
648
- setUploadProgress(progress * 100);
649
- },
650
- });
651
- return {
652
- uuid: fileRes.uuid,
653
- key: fileRes.key,
654
- bucket: fileRes.bucket,
655
- filename: file.name,
656
- filesize: file.size,
657
- extension: fileRes.extension,
658
- file_relationship: fileKey,
659
- };
660
- }
661
- );
662
- formData['uploadedFiles'] = await Promise.all(
663
- uploadPromises
664
- );
665
- } else {
666
- const fileRes = await Vapor.store(
667
- formData[fileKey],
668
- {
669
- progress: (progress) => {
670
- setUploadProgress(progress * 100);
671
- },
672
- }
673
- );
674
- formData['uuid'] = fileRes.uuid;
675
- formData['key'] = fileRes.key;
676
- formData['bucket'] = fileRes.bucket;
677
- formData['filename'] = formData[fileKey].name;
678
- formData['filesize'] = formData[fileKey].size;
679
- formData['extension'] = fileRes.extension;
680
- formData['file_relationship'] = fileKey;
681
- }
682
- }
683
-
684
- // Transform keys with dots into nested objects
685
- const payload = Object.keys(formData).reduce((acc, key) => {
686
- if (key.includes('.')) {
687
- const [root, sub] = key.split('.');
688
- if (!acc[root]) acc[root] = {};
689
- acc[root][sub] = formData[key];
690
- } else {
691
- acc[key] = formData[key];
692
- }
693
- return acc;
694
- }, {});
695
-
696
- console.info(payload);
697
-
698
- const res = await CustomFetch(url, method, payload);
699
-
700
- if (res.data.error === '') {
701
- if (fetchTable) fetchTable();
702
- if (closeModal) {
703
- closeModal();
704
- if (type === 'saveAnother') {
705
- fetchData();
706
- modalOpen('create', 0);
707
- }
708
- }
709
- toast.success(
710
- formSettings?.save?.toast?.success ||
711
- 'Entry successfully saved into the system.'
712
- );
713
-
714
- if (formSettings.redirect && res.data.data?.id) {
715
- navigate(
716
- `${formSettings.redirect}${res.data.data.id}`
717
- );
718
- }
719
-
720
- if (res.data.redirect) {
721
- navigate(res.data.redirect);
722
- }
723
-
724
- if (
725
- formSettings?.save?.return?.type === 'table' &&
726
- formSettings?.save?.return?.param
727
- ) {
728
- if (
729
- res.data[formSettings.save.return.param]
730
- ?.length > 0
731
- ) {
732
- const td = parseTableData(
733
- res.data[formSettings.save.return.param]
734
- );
735
- setTableData((prevState) => ({
736
- ...prevState,
737
- ...td,
738
- }));
739
- } else {
740
- setTableData((prevState) => ({
741
- ...prevState,
742
- columns: [],
743
- dataSource: [],
744
- }));
745
- }
746
- }
747
- }
748
- }
749
- }
750
- } catch (err) {
751
- console.error(err);
752
- }
753
- };
754
-
755
- const fetchData = async () => {
756
- let _formData = { ...formData };
757
-
758
- if (formSettings.fields.length > 0) {
759
- formSettings.fields.forEach((item) => {
760
- const { id, value, type, parent, urlParam } = item;
761
- let newValue = value;
762
-
763
- if (urlParam) {
764
- newValue = paramValue;
765
- }
766
-
767
- if (parent) {
768
- _formData[parent] = {
769
- ..._formData[parent],
770
- [id]: newValue ? newValue : '',
771
- };
772
- } else {
773
- if (newValue !== '') {
774
- if (['date', 'datetime'].includes(type)) {
775
- _formData[id] =
776
- newValue instanceof Date
777
- ? newValue
778
- : moment(newValue).toDate();
779
- } else {
780
- _formData[id] = newValue;
781
- }
782
- } else {
783
- _formData[id] = '';
784
- }
785
- }
786
- });
787
- }
788
-
789
- if (formType !== 'create' && columnId > 0) {
790
- try {
791
- let urlSuffix,
792
- method,
793
- payload = {};
794
-
795
- const getDataId = () => {
796
- for (const item of ajaxSetting.where) {
797
- if (
798
- item.hasOwnProperty('urlParam') &&
799
- item.urlParam === 'dataId'
800
- ) {
801
- return item.value;
802
- }
803
- }
804
- return 0;
805
- };
806
-
807
- if (
808
- formSettings.hasOwnProperty('json') &&
809
- formSettings.json === true
810
- ) {
811
- let dataId = getDataId();
812
-
813
- urlSuffix = '/jsonGet';
814
- method = 'POST';
815
- payload = { id: columnId, dataId };
816
- } else {
817
- urlSuffix = `/${columnId}`;
818
- method = 'GET';
819
- }
820
-
821
- const url = `${formSettings.url}${urlSuffix}`;
822
- const result = await CustomFetch(url, method, payload);
823
-
824
- const data = result.hasOwnProperty('data')
825
- ? result.data
826
- : result;
827
-
828
- const updatedFormData = { ..._formData };
829
-
830
- Object.keys(updatedFormData).forEach((item) => {
831
- let tempRes = '';
832
- let tempResKey = '';
833
- let field = formSettings.fields.find((f) => f.id === item);
834
-
835
- if (data[item] === undefined) {
836
- if (field && field.hasOwnProperty('relation')) {
837
- let tempRes = data[field.relation];
838
-
839
- if (
840
- [
841
- 'multi-dropdown',
842
- 'multi-dropdown-ajax',
843
- 'async-dropdown-ajax',
844
- ].includes(field.type) &&
845
- Array.isArray(tempRes)
846
- ) {
847
- tempRes = tempRes.map((a) => ({
848
- value: a.name,
849
- label: a.name,
850
- }));
851
- }
852
-
853
- if (tempRes) {
854
- const relationFrom = field.hasOwnProperty(
855
- 'relation_from'
856
- )
857
- ? field.relation_from
858
- : field.id;
859
- tempRes = Array.isArray(tempRes)
860
- ? tempRes[0][relationFrom]
861
- : tempRes[relationFrom];
862
- } else {
863
- tempRes = '';
864
- }
865
-
866
- updatedFormData[item] = tempRes;
867
- }
868
-
869
- if (
870
- field &&
871
- field.hasOwnProperty('relation') &&
872
- [
873
- 'multi-dropdown',
874
- 'multi-dropdown-ajax',
875
- 'async-dropdown-ajax',
876
- ].includes(field.type)
877
- ) {
878
- let tempObj = data;
879
- let tempRes = {};
880
-
881
- const relationLength = Array.isArray(field.relation)
882
- ? field.relation.length
883
- : 1;
884
- for (let i = 0; i < relationLength; i++) {
885
- tempObj = tempObj[field.relation[i]];
886
- }
887
-
888
- if (tempObj !== undefined && tempObj !== null) {
889
- let labelValue;
890
-
891
- if (Array.isArray(field.relationName)) {
892
- labelValue = field.relationName.map(
893
- (name) => `${tempObj[name]} `
894
- );
895
- } else {
896
- labelValue = tempObj[field.relationName];
897
- }
898
-
899
- tempRes = {
900
- value: tempObj.id,
901
- label: labelValue,
902
- };
903
- }
904
-
905
- updatedFormData[field.id] = tempRes;
906
- }
907
-
908
- if (
909
- field &&
910
- field.hasOwnProperty('relation') &&
911
- ['address', 'text'].includes(field.type)
912
- ) {
913
- let tempObj = data;
914
- let tempRes = '';
915
-
916
- const relationLength = Array.isArray(field.relation)
917
- ? field.relation.length
918
- : 1;
919
- for (let i = 0; i < relationLength; i++) {
920
- tempObj = tempObj[field.relation[i]];
921
- }
922
-
923
- if (tempObj !== undefined && tempObj !== null) {
924
- let labelValue;
925
-
926
- if (Array.isArray(field.relationName)) {
927
- labelValue = field.relationName.map(
928
- (name) => `${tempObj[name]} `
929
- );
930
- } else {
931
- labelValue = tempObj[field.relationName];
932
- }
933
-
934
- tempRes = labelValue;
935
- }
936
-
937
- updatedFormData[field.id] = tempRes;
938
- }
939
-
940
- if (field && field.hasOwnProperty('parent')) {
941
- let tempObj = data;
942
- let tempRes = '';
943
-
944
- tempRes = tempObj[field.parent][field.id];
945
-
946
- updatedFormData[field.parent][field.id] = tempRes;
947
- }
948
-
949
- if (item.includes('.')) {
950
- let keys = item.split('.');
951
-
952
- let value = data;
953
-
954
- for (let key of keys) {
955
- value = value[key];
956
- }
957
-
958
- updatedFormData[item] = value;
959
- }
960
- } else {
961
- if (
962
- field &&
963
- ['date', 'datetime', 'time'].includes(field.type)
964
- ) {
965
- if (data[item] === null || data[item] === '') {
966
- updatedFormData[item] = '';
967
- } else {
968
- const momentDate = moment(data[item]);
969
- updatedFormData[item] = momentDate.isValid()
970
- ? momentDate.toDate()
971
- : null;
972
- }
973
- } else if (
974
- field &&
975
- field.hasOwnProperty('relation') &&
976
- !field.multi
977
- ) {
978
- const relationTypes = [
979
- 'dropdown-ajax',
980
- 'multi-dropdown',
981
- 'multi-dropdown-ajax',
982
- 'async-dropdown-ajax',
983
- ];
984
-
985
- if (relationTypes.includes(field.type)) {
986
- let relationLength = Array.isArray(
987
- field.relation
988
- )
989
- ? field.relation.length
990
- : 1;
991
- let tempObj = data;
992
- let relationFound = false;
993
-
994
- for (let i = 0; i < relationLength; i++) {
995
- if (tempObj[field.relation[i]]) {
996
- relationFound = true;
997
- tempObj = tempObj[field.relation[i]];
998
- }
999
- }
1000
-
1001
- if (relationFound === false) {
1002
- tempObj = {};
1003
- }
1004
-
1005
- let labelValue;
1006
-
1007
- if (Array.isArray(field.relationName)) {
1008
- labelValue = field.relationName.map(
1009
- (name) => `${tempObj[name]} `
1010
- );
1011
- } else {
1012
- labelValue = tempObj[field.relationName];
1013
- }
1014
-
1015
- tempRes =
1016
- tempObj !== undefined &&
1017
- tempObj !== null &&
1018
- tempObj.id
1019
- ? {
1020
- value: tempObj.id,
1021
- label: labelValue,
1022
- }
1023
- : {};
1024
-
1025
- tempResKey = field.id;
1026
- }
1027
- } else {
1028
- updatedFormData[item] = data[item];
1029
- }
1030
- }
1031
-
1032
- if (
1033
- item === tempResKey &&
1034
- tempRes &&
1035
- tempRes.hasOwnProperty('value') &&
1036
- tempRes.hasOwnProperty('label')
1037
- ) {
1038
- updatedFormData[item] = tempRes;
1039
- }
1040
- });
1041
-
1042
- setFormData(updatedFormData);
1043
-
1044
- setFetchTrigger(!fetchTrigger);
1045
- } catch (error) {
1046
- toast.error('Failed to fetch data:', error);
1047
- }
1048
- } else {
1049
- setFormData(_formData);
1050
- }
1051
- };
1052
-
1053
- useEffect(() => {
1054
- fetchData();
1055
- }, []);
1056
-
1057
- useEffect(() => {
1058
- formSettings.fields.forEach((field) => {
1059
- const showConditions = field.show || [];
1060
-
1061
- showConditions.forEach((showObject) => {
1062
- const { id, value } = showObject;
1063
-
1064
- if (id !== '' && value.length > 0) {
1065
- const targetField = formSettings.fields.find(
1066
- (f) => f.id === id
1067
- );
1068
-
1069
- if (targetField) {
1070
- const valueChecker = formData[field.id];
1071
-
1072
- if (valueChecker) {
1073
- const shouldShow =
1074
- valueChecker && value.includes(valueChecker);
1075
-
1076
- targetField.hide = !shouldShow;
1077
-
1078
- if (updateForm) {
1079
- updateForm((prevState) => ({
1080
- ...prevState,
1081
- fields: [...formSettings.fields],
1082
- }));
1083
- }
1084
- }
1085
- }
1086
- }
1087
- });
1088
- });
1089
- }, [fetchTrigger]);
1090
-
1091
- if (type && type === 'inline') {
1092
- return (
1093
- <div className={styles.formcontainer}>
1094
- <form className={styles.modalForm}>
1095
- {formSettings.fields.map((item, index) => {
1096
- if (item.hasOwnProperty('hide') && item.hide === true) {
1097
- return null;
1098
- }
1099
- if (
1100
- item.hasOwnProperty('createOnly') &&
1101
- item.createOnly === true &&
1102
- formType === 'update'
1103
- ) {
1104
- return null;
1105
- }
1106
- if (
1107
- item.hasOwnProperty('updateOnly') &&
1108
- item.updateOnly === true &&
1109
- formType === 'create'
1110
- ) {
1111
- return null;
1112
- }
1113
-
1114
- switch (item.type) {
1115
- case 'table':
1116
- let ajaxSetting = item.ajaxSetting;
1117
-
1118
- item.ajaxSetting.where.forEach((a, b) => {
1119
- if (a.urlParam) {
1120
- ajaxSetting.where[b].value = paramValue;
1121
- }
1122
- });
1123
-
1124
- return (
1125
- <div
1126
- className={styles.grid__full}
1127
- key={
1128
- index +
1129
- '-fields-' +
1130
- (item.hasOwnProperty('key')
1131
- ? item.id + '-' + item.key
1132
- : item.id)
1133
- }
1134
- >
1135
- <Table
1136
- ajaxSetting={ajaxSetting}
1137
- form={item.form}
1138
- columns={item.columns}
1139
- mapbox={mapbox}
1140
- paramValue={paramValue}
1141
- settings={item.settings}
1142
- style={
1143
- userProfile?.settings?.style ||
1144
- {}
1145
- }
1146
- />
1147
- </div>
1148
- );
1149
- default:
1150
- return (
1151
- <Field
1152
- api={api}
1153
- autocompleteCallback={
1154
- autocompleteSelect
1155
- }
1156
- childDropdownCallback={
1157
- childDropdownCallback
1158
- }
1159
- fetchData={fetchData}
1160
- formData={formData}
1161
- inputClass={inputClass}
1162
- inputValue={renderInputValue(
1163
- item,
1164
- formData
1165
- )}
1166
- key={
1167
- index +
1168
- '-fields-' +
1169
- (item.hasOwnProperty('key')
1170
- ? item.id + '-' + item.key
1171
- : item.id)
1172
- }
1173
- mapbox={mapbox}
1174
- onChange={handleChange}
1175
- onChangeCheckbox={handleChangeCheckbox}
1176
- onChangeDate={handleChangeDate}
1177
- onChangeNumberFormat={
1178
- handleChangeNumberFormat
1179
- }
1180
- onChangeRicheditor={
1181
- handleChangeRicheditor
1182
- }
1183
- onChangeSelect={handleChangeSelect}
1184
- onChangeSignature={
1185
- handleChangeSignature
1186
- }
1187
- onChangeToggle={handleChangeToggle}
1188
- settings={item}
1189
- setFormData={setFormData}
1190
- style={style}
1191
- uploadProgress={uploadProgress}
1192
- userProfile={userProfile}
1193
- />
1194
- );
1195
- }
1196
- })}
1197
- <div className={`${styles.formItem} ${styles.fwItem}`}>
1198
- <motion.div
1199
- className={styles.progress__bar}
1200
- initial={{ width: '0%' }}
1201
- animate={{ width: uploadProgress + '%' }}
1202
- transition={{
1203
- duration: 3,
1204
- ease: [0.165, 0.84, 0.44, 1.0],
1205
- }}
1206
- />
1207
- </div>
1208
- {tableData?.dataSource?.length > 0 && (
1209
- <div className={`${styles.formItem} ${styles.fwItem}`}>
1210
- <ReactDataGrid
1211
- idProperty="form-table-result"
1212
- columns={tableData.columns}
1213
- dataSource={tableData.dataSource}
1214
- style={{ minHeight: 550 }}
1215
- showActiveRowIndicator={false}
1216
- />
1217
- </div>
1218
- )}
1219
- </form>
1220
- <div className={styles.polActions}>
1221
- {formSettings.hasOwnProperty('customButton') &&
1222
- formSettings.customButton.url ? (
1223
- <button
1224
- className={styles.btn}
1225
- onClick={(e) => {
1226
- e.preventDefault();
1227
- handleCustom(formSettings);
1228
- }}
1229
- >
1230
- {formSettings.customButton.label
1231
- ? formSettings.customButton.label
1232
- : 'Sort'}
1233
- </button>
1234
- ) : null}
1235
-
1236
- {formSettings?.download?.button?.label && (
1237
- <button className={styles.btn} onClick={handleDownload}>
1238
- {formSettings.download.button.label}
1239
- </button>
1240
- )}
1241
-
1242
- {formSettings.hasOwnProperty('sortButton') &&
1243
- formSettings.sortButton.url ? (
1244
- <button className={styles.btn} onClick={handleSort}>
1245
- {formSettings.sortButton.label
1246
- ? formSettings.sortButton.label
1247
- : 'Sort'}
1248
- </button>
1249
- ) : null}
1250
-
1251
- <button className={styles.btn} onClick={handleSubmit}>
1252
- {formSettings?.save?.button?.label
1253
- ? formSettings.save.button.label
1254
- : 'Save'}
1255
- </button>
1256
- </div>
1257
- </div>
1258
- );
1259
- } else {
1260
- return (
1261
- <div className="modalwrap top--modal">
1262
- <div className="modal">
1263
- <div className="modal__header">
1264
- <h1>{formSettings[formType]?.title}</h1>
1265
- <button className="modal__close" onClick={closeModal}>
1266
- <CircleX strokeWidth={1} size={24} />
1267
- </button>
1268
- </div>
1269
- <div className="modal__content">
1270
- <div className={styles.formcontainer}>
1271
- <form className={styles.modalForm}>
1272
- {formSettings?.fields?.map((item, index) => {
1273
- if (
1274
- item.hasOwnProperty('hide') &&
1275
- item.hide === true
1276
- ) {
1277
- return null;
1278
- }
1279
- if (
1280
- item.hasOwnProperty('createOnly') &&
1281
- item.createOnly === true &&
1282
- formType === 'update'
1283
- ) {
1284
- return null;
1285
- }
1286
- if (
1287
- item.hasOwnProperty('updateOnly') &&
1288
- item.updateOnly === true &&
1289
- formType === 'create'
1290
- ) {
1291
- return null;
1292
- }
1293
-
1294
- return (
1295
- <Field
1296
- api={api}
1297
- autocompleteCallback={
1298
- autocompleteSelect
1299
- }
1300
- childDropdownCallback={
1301
- childDropdownCallback
1302
- }
1303
- fetchData={fetchData}
1304
- formData={formData}
1305
- inputClass={inputClass}
1306
- inputValue={renderInputValue(
1307
- item,
1308
- formData
1309
- )}
1310
- key={
1311
- index +
1312
- '-fields-' +
1313
- (item.hasOwnProperty('key')
1314
- ? item.id + '-' + item.key
1315
- : item.id)
1316
- }
1317
- mapbox={mapbox}
1318
- onChange={handleChange}
1319
- onChangeCheckbox={
1320
- handleChangeCheckbox
1321
- }
1322
- onChangeColour={handleChangeColour}
1323
- onChangeDate={handleChangeDate}
1324
- onChangeNumberFormat={
1325
- handleChangeNumberFormat
1326
- }
1327
- onChangeRicheditor={
1328
- handleChangeRicheditor
1329
- }
1330
- onChangeSignature={
1331
- handleChangeSignature
1332
- }
1333
- onChangeSelect={handleChangeSelect}
1334
- onChangeToggle={handleChangeToggle}
1335
- onFileDownload={handleFileDownload}
1336
- settings={item}
1337
- setFormData={setFormData}
1338
- style={style}
1339
- uploadProgress={uploadProgress}
1340
- userProfile={userProfile}
1341
- />
1342
- );
1343
- })}
1344
- <div
1345
- className={`${styles.formItem} ${styles.fwItem}`}
1346
- >
1347
- <motion.div
1348
- className={styles.progress__bar}
1349
- initial={{ width: '0%' }}
1350
- animate={{
1351
- width: uploadProgress + '%',
1352
- }}
1353
- transition={{
1354
- duration: 3,
1355
- ease: [0.165, 0.84, 0.44, 1.0],
1356
- }}
1357
- />
1358
- </div>
1359
- {formType === 'create' &&
1360
- formSettings.create?.hasOwnProperty(
1361
- 'saveAnother'
1362
- ) ? (
1363
- <>
1364
- <div
1365
- className={`${styles.formItem} ${styles.lastItem}`}
1366
- >
1367
- <button
1368
- className={styles.btn}
1369
- onClick={handleSubmit}
1370
- data-type="save"
1371
- >
1372
- Save & Close
1373
- </button>
1374
- </div>
1375
- <div
1376
- className={`${styles.formItem} ${styles.lastItem}`}
1377
- >
1378
- <button
1379
- className={styles.btn}
1380
- onClick={handleSubmit}
1381
- data-type="saveAnother"
1382
- >
1383
- Save & Create Another
1384
- </button>
1385
- </div>
1386
- </>
1387
- ) : (
1388
- <div
1389
- className={`${styles.formItem} ${styles.fwItem} ${styles.lastItem}`}
1390
- >
1391
- <button
1392
- className={styles.btn}
1393
- onClick={handleSubmit}
1394
- data-type="save"
1395
- >
1396
- Save
1397
- </button>
1398
- </div>
1399
- )}
1400
- </form>
1401
- </div>
1402
- </div>
1403
- </div>
1404
- </div>
1405
- );
1406
- }
1407
- }
1408
-
1409
- export default Form;