@visns-studio/visns-components 4.6.13 → 4.7.1

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 (107) 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/main.83b033670d64419bb497.css +1 -0
  22. package/dist/main.b1723d17cd2d3513ab62.js +1 -0
  23. package/dist/report.html +39 -0
  24. package/dist/runtime.33c276593b23f8035b8d.js +1 -0
  25. package/package.json +26 -6
  26. package/.idea/codeStyles/Project.xml +0 -50
  27. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  28. package/.idea/deployment.xml +0 -4
  29. package/.idea/modules.xml +0 -8
  30. package/.idea/php.xml +0 -19
  31. package/.idea/vcs.xml +0 -6
  32. package/.idea/visns-components.iml +0 -8
  33. package/.prettierrc.json +0 -7
  34. package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +0 -541
  35. package/.yarn/releases/yarn-3.6.1.cjs +0 -874
  36. package/.yarnrc.yml +0 -7
  37. package/components/cms/DataGrid.jsx +0 -1461
  38. package/components/cms/DropZone.jsx +0 -349
  39. package/components/cms/Field.jsx +0 -802
  40. package/components/cms/Form.jsx +0 -476
  41. package/components/cms/generic/CmsDetail.jsx +0 -36
  42. package/components/cms/generic/CmsIndex.jsx +0 -73
  43. package/components/cms/generic/CmsSort.jsx +0 -125
  44. package/components/cms/sorting/Item.jsx +0 -115
  45. package/components/cms/sorting/List.jsx +0 -30
  46. package/components/crm/AsyncSelect.jsx +0 -125
  47. package/components/crm/Autocomplete.jsx +0 -174
  48. package/components/crm/Breadcrumb.jsx +0 -52
  49. package/components/crm/Call.jsx +0 -220
  50. package/components/crm/DataGrid.jsx +0 -2701
  51. package/components/crm/Download.jsx +0 -101
  52. package/components/crm/Fetch.jsx +0 -119
  53. package/components/crm/Field.jsx +0 -1557
  54. package/components/crm/Form.jsx +0 -1409
  55. package/components/crm/Loader.jsx +0 -29
  56. package/components/crm/MultiSelect.jsx +0 -78
  57. package/components/crm/Navigation.jsx +0 -619
  58. package/components/crm/Notification.jsx +0 -197
  59. package/components/crm/QrCode.jsx +0 -83
  60. package/components/crm/Select.jsx +0 -58
  61. package/components/crm/SelectList.jsx +0 -21
  62. package/components/crm/TableFilter.jsx +0 -198
  63. package/components/crm/auth/Login.jsx +0 -230
  64. package/components/crm/auth/Profile.jsx +0 -280
  65. package/components/crm/auth/Reset.jsx +0 -111
  66. package/components/crm/auth/Verify.jsx +0 -174
  67. package/components/crm/auth/styles/Login.module.css +0 -245
  68. package/components/crm/auth/styles/Profile.module.css +0 -222
  69. package/components/crm/auth/styles/Reset.module.css +0 -216
  70. package/components/crm/auth/styles/Verify.module.css +0 -216
  71. package/components/crm/generic/AuditLog.jsx +0 -108
  72. package/components/crm/generic/AuditLogs.jsx +0 -115
  73. package/components/crm/generic/GenericAuth.jsx +0 -166
  74. package/components/crm/generic/GenericDashboard.jsx +0 -42
  75. package/components/crm/generic/GenericDetail.jsx +0 -1499
  76. package/components/crm/generic/GenericDynamic.jsx +0 -915
  77. package/components/crm/generic/GenericFormBuilder.jsx +0 -1765
  78. package/components/crm/generic/GenericIndex.jsx +0 -376
  79. package/components/crm/generic/GenericMain.jsx +0 -129
  80. package/components/crm/generic/GenericSort.jsx +0 -188
  81. package/components/crm/generic/NotificationList.jsx +0 -64
  82. package/components/crm/generic/styles/AuditLog.module.css +0 -147
  83. package/components/crm/generic/styles/AuditLogs.module.css +0 -92
  84. package/components/crm/generic/styles/GenericDetail.module.css +0 -634
  85. package/components/crm/generic/styles/GenericDynamic.module.css +0 -932
  86. package/components/crm/generic/styles/GenericFormBuilder.module.css +0 -944
  87. package/components/crm/generic/styles/GenericIndex.module.css +0 -247
  88. package/components/crm/generic/styles/GenericMain.module.css +0 -91
  89. package/components/crm/generic/styles/GenericSort.module.css +0 -123
  90. package/components/crm/generic/styles/NotificationList.module.css +0 -67
  91. package/components/crm/sorting/Item.jsx +0 -117
  92. package/components/crm/sorting/List.jsx +0 -32
  93. package/components/crm/sorting/styles/Item.module.css +0 -68
  94. package/components/crm/sorting/styles/List.module.css +0 -68
  95. package/components/crm/styles/AsyncSelect.module.css +0 -8
  96. package/components/crm/styles/Autocomplete.module.css +0 -44
  97. package/components/crm/styles/DataGrid.module.css +0 -210
  98. package/components/crm/styles/Field.module.css +0 -311
  99. package/components/crm/styles/Form.module.css +0 -499
  100. package/components/crm/styles/Loader.module.css +0 -94
  101. package/components/crm/styles/MultiSelect.module.css +0 -8
  102. package/components/crm/styles/Navigation.module.css +0 -978
  103. package/components/crm/styles/Notification.module.css +0 -147
  104. package/components/crm/styles/QrCode.module.css +0 -87
  105. package/components/crm/styles/TableFilter.module.css +0 -52
  106. package/components/styles/global.css +0 -73
  107. 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;