@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,915 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import moment from 'moment';
3
- import 'react-confirm-alert/src/react-confirm-alert.css';
4
- import { toast } from 'react-toastify';
5
- import { confirmAlert } from 'react-confirm-alert';
6
- import { saveAs } from 'file-saver';
7
- import parse from 'html-react-parser';
8
- import { Backspace, CloudDownload } from 'akar-icons';
9
-
10
- import CustomFetch from '../Fetch';
11
- import Download from '../Download';
12
- import Field from '../Field';
13
- import styles from './styles/GenericDynamic.module.css';
14
-
15
- const updateField = (fields, name, value) => {
16
- if (Array.isArray(fields)) {
17
- return fields.map((field) => ({
18
- ...field,
19
- value: field.id === name ? value : field.value,
20
- }));
21
- }
22
-
23
- return Object.entries(fields).reduce(
24
- (acc, [key, field]) => ({
25
- ...acc,
26
- [key]: field.id === name ? { ...field, value } : field,
27
- }),
28
- {}
29
- );
30
- };
31
-
32
- const renderValue = (field, data) => {
33
- switch (field.type) {
34
- case 'datetime':
35
- case 'date':
36
- return field.value && moment(field.value).isValid()
37
- ? moment(field.value).toDate()
38
- : '';
39
-
40
- case 'dynamicdata':
41
- if (field.dynamicfield && typeof field.dynamicfield === 'string') {
42
- const [table, key] = field.dynamicfield.split('::');
43
-
44
- if (table && key) {
45
- switch (table) {
46
- case 'opportunities':
47
- return data[table][key];
48
- case 'clients':
49
- return data['client'] ? data['client'][key] : null;
50
- default:
51
- if (key === 'surname' && !data[key]) {
52
- return data['lastname'] || '';
53
- }
54
- return data[key];
55
- }
56
- } else {
57
- console.warn(
58
- `Dynamic field not found or invalid: ${field.dynamicfield}`
59
- );
60
- }
61
- } else {
62
- console.warn('Dynamic field is missing or not a string');
63
- }
64
- break;
65
-
66
- case 'time':
67
- return field.value && moment(field.value).isValid()
68
- ? moment(field.value).toDate()
69
- : '';
70
- default:
71
- return field.value || '';
72
- }
73
- };
74
-
75
- const GenericDynamic = ({
76
- buttons,
77
- data,
78
- fetchData,
79
- label,
80
- multiple = true,
81
- originalData = {},
82
- primaryKey,
83
- setData,
84
- setting,
85
- templateStatus = true,
86
- type,
87
- userProfile,
88
- }) => {
89
- const [activeForm, setActiveForm] = useState({});
90
- const [activeFormKey, setActiveFormKey] = useState(0);
91
-
92
- const handleChange = (e) => {
93
- const {
94
- checked,
95
- dataset: { name },
96
- files,
97
- value,
98
- } = e.target;
99
-
100
- let newValue;
101
-
102
- if (checked) {
103
- newValue = checked;
104
- setActiveForm((prevState) =>
105
- updateField(prevState, name, newValue)
106
- );
107
- } else if (files && files[0]) {
108
- const toastId = toast.loading('Uploading file...');
109
- Vapor.store(files[0], {
110
- progress: (progress) => {
111
- console.info(`Upload Progress: ${progress}`);
112
- },
113
- }).then((response) => {
114
- if (files[0].type.startsWith('image/')) {
115
- const reader = new FileReader();
116
- reader.onload = (e) => {
117
- const imageSrc = e.target.result;
118
-
119
- setActiveForm((prevState) =>
120
- updateField(prevState, name, {
121
- extension: response.extension,
122
- key: response.key,
123
- url: response.url,
124
- uuid: response.uuid,
125
- bucket: response.bucket,
126
- filename: files[0].name,
127
- filesize: files[0].size,
128
- imageSrc: imageSrc,
129
- })
130
- );
131
- };
132
- reader.readAsDataURL(files[0]);
133
- } else {
134
- setActiveForm((prevState) =>
135
- updateField(prevState, name, {
136
- extension: response.extension,
137
- key: response.key,
138
- url: response.url,
139
- uuid: response.uuid,
140
- bucket: response.bucket,
141
- filename: files[0].name,
142
- filesize: files[0].size,
143
- })
144
- );
145
- }
146
- toast.update(toastId, {
147
- render: 'Upload successful!',
148
- type: 'success',
149
- isLoading: false,
150
- autoClose: 5000,
151
- closeButton: true,
152
- });
153
- });
154
- } else {
155
- newValue = value;
156
- setActiveForm((prevState) =>
157
- updateField(prevState, name, newValue)
158
- );
159
- }
160
- };
161
-
162
- const handleChangeCheckbox = (e) => {
163
- const { checked, name, value } = e.target;
164
-
165
- let tmpValue;
166
-
167
- Object.entries(activeForm).forEach(([key, field]) => {
168
- if (field.id && field.id === name) {
169
- if (
170
- field.value === null ||
171
- field.value === '' ||
172
- field.value.length === 0
173
- ) {
174
- tmpValue = [];
175
-
176
- field.options.forEach((option) => {
177
- tmpValue.push(false);
178
- });
179
- } else {
180
- tmpValue = [...field.value];
181
- }
182
-
183
- field.options.forEach((option, optionKey) => {
184
- if (option.label === value) {
185
- tmpValue[optionKey] = checked;
186
- }
187
- });
188
- }
189
- });
190
-
191
- setActiveForm((prevState) => updateField(prevState, name, tmpValue));
192
- };
193
-
194
- const handleChangeDate = (value, id) => {
195
- setActiveForm((prevState) => updateField(prevState, id, value));
196
- };
197
-
198
- const handleChangeNumberFormat = (value, id) => {
199
- setActiveForm((prevState) => updateField(prevState, id, value.value));
200
- };
201
-
202
- const handleChangeSignature = (id) => {
203
- if (userProfile.signature) {
204
- setActiveForm((prevState) =>
205
- updateField(prevState, id, {
206
- signature: userProfile.signature,
207
- name: userProfile.name,
208
- date: moment().toString(),
209
- })
210
- );
211
- }
212
- };
213
-
214
- const handleChangeTableRadio = (e) => {
215
- const {
216
- dataset: { id, rowId, columnId },
217
- } = e.target;
218
-
219
- setActiveForm((prevActiveForm) => {
220
- // Find the form element that matches the given id
221
- const formKey = Object.keys(prevActiveForm).find(
222
- (key) => prevActiveForm[key].id === id
223
- );
224
-
225
- if (!formKey || !prevActiveForm[formKey]?.rows) {
226
- console.info(
227
- `Form with id ${id} does not exist or has no rows`
228
- );
229
- return prevActiveForm;
230
- }
231
-
232
- // Create a new rows array with toggled value properties
233
- const updatedRows = prevActiveForm[formKey].rows.map((row) => {
234
- if (row.id === rowId) {
235
- // Ensure the value is an object to handle multiple columns
236
- const updatedValue = {
237
- ...row.value,
238
- [columnId]: !row.value?.[columnId], // Toggle the specific column value
239
- };
240
- return {
241
- ...row,
242
- value: updatedValue,
243
- };
244
- }
245
- return row;
246
- });
247
-
248
- // Return the updated activeForm state
249
- return {
250
- ...prevActiveForm,
251
- [formKey]: {
252
- ...prevActiveForm[formKey],
253
- rows: updatedRows,
254
- },
255
- };
256
- });
257
- };
258
-
259
- const handleChangeAddTableTextRow = (id) => {
260
- setActiveForm((prevActiveForm) => {
261
- // Find the key of the form that matches the id
262
- const formKey = Object.keys(prevActiveForm).find(
263
- (key) => prevActiveForm[key].id === id
264
- );
265
-
266
- if (!formKey) {
267
- console.info(`Form with id ${id} does not exist.`);
268
- return prevActiveForm;
269
- }
270
-
271
- // Create a new row with placeholders based on the options length
272
- const numOptions = prevActiveForm[formKey].options.length;
273
- const newRow = Array(numOptions).fill(''); // Create an array of empty strings
274
-
275
- return {
276
- ...prevActiveForm,
277
- [formKey]: {
278
- ...prevActiveForm[formKey],
279
- value: [
280
- ...(prevActiveForm[formKey].value || []), // Handle null by initializing to empty array
281
- newRow,
282
- ],
283
- },
284
- };
285
- });
286
- };
287
-
288
- const handleChangeTableText = (e, rowIndex, columnIndex) => {
289
- const { value, checked, type } = e.target;
290
- const { id } = e.target.dataset;
291
-
292
- setActiveForm((prevActiveForm) => {
293
- const formKey = Object.keys(prevActiveForm).find(
294
- (key) => prevActiveForm[key].id === id
295
- );
296
-
297
- if (!formKey) return prevActiveForm;
298
-
299
- const updatedRows = (prevActiveForm[formKey].value || []).map(
300
- (row, index) =>
301
- index === rowIndex
302
- ? row.map((cell, colIndex) =>
303
- colIndex === columnIndex
304
- ? type === 'checkbox'
305
- ? checked
306
- : value
307
- : cell
308
- )
309
- : row
310
- );
311
-
312
- return {
313
- ...prevActiveForm,
314
- [formKey]: {
315
- ...prevActiveForm[formKey],
316
- value: updatedRows,
317
- },
318
- };
319
- });
320
- };
321
-
322
- const handleChangeToggle = (e) => {
323
- if (!e) {
324
- return;
325
- }
326
-
327
- const { name, checked } = e.target;
328
-
329
- setActiveForm((prevState) => updateField(prevState, name, checked));
330
- };
331
-
332
- const handleFileDownload = async (d) => {
333
- const toastId = toast.loading('Downloading file...');
334
- try {
335
- const res = await Download(setting.file, 'POST', {
336
- extension: d.extension,
337
- uuid: d.uuid,
338
- filename: d.filename,
339
- });
340
-
341
- if (res.data) {
342
- saveAs(res.data, d.filename);
343
- toast.update(toastId, {
344
- render: 'Download successful!',
345
- type: 'success',
346
- isLoading: false,
347
- autoClose: 5000,
348
- closeButton: true,
349
- });
350
- } else {
351
- toast.update(toastId, {
352
- render: 'Error downloading form',
353
- type: 'error',
354
- isLoading: false,
355
- autoClose: 5000,
356
- closeButton: true,
357
- });
358
- }
359
- } catch (err) {
360
- toast.update(toastId, {
361
- render: 'Error downloading form',
362
- type: 'error',
363
- isLoading: false,
364
- autoClose: 5000,
365
- closeButton: true,
366
- });
367
- }
368
- };
369
-
370
- const handleSelectForm = (form, key) => {
371
- setActiveForm(form);
372
- setActiveFormKey(key);
373
- };
374
-
375
- const handleCustomButton = async (s) => {
376
- let payload = {};
377
- switch (s.type) {
378
- case 'save':
379
- if (s.payload?.length > 0) {
380
- s.payload.forEach((p) => {
381
- if (data[p]) {
382
- payload[p] = data[p];
383
- }
384
- });
385
- }
386
-
387
- const res = await Download(s.url, s.method, payload);
388
-
389
- if (res.data) {
390
- saveAs(res.data);
391
- }
392
- break;
393
- default:
394
- console.info(s, 'default');
395
- break;
396
- }
397
- };
398
-
399
- const handleAddNewForm = async (showToast = true) => {
400
- try {
401
- if (activeForm && activeForm.id) {
402
- await CustomFetch(setting.save, 'POST', {
403
- client_id: data.id,
404
- form_data: {
405
- ...activeForm,
406
- },
407
- form_key: activeFormKey,
408
- form_type: type,
409
- });
410
- }
411
-
412
- if (setting.add) {
413
- const res = await CustomFetch(setting.add, 'POST', {
414
- client_id: data.id,
415
- form_name: type,
416
- });
417
-
418
- if (res.data.error === '') {
419
- if (showToast) {
420
- toast.success('Form added successfully');
421
- }
422
- fetchData();
423
- }
424
- }
425
- } catch (err) {
426
- console.error(err);
427
- toast.error('Error adding form');
428
- }
429
- };
430
-
431
- const handleDownloadForm = async (item, label, data) => {
432
- const toastId = toast.loading('Downloading form...');
433
-
434
- try {
435
- const response = await Download(setting.download, 'POST', {
436
- data: item,
437
- dynamicData: data,
438
- label: label,
439
- });
440
-
441
- if (response && response.data) {
442
- const contentDisposition = response.headers.get(
443
- 'Content-Disposition'
444
- );
445
- let filename = null;
446
-
447
- if (contentDisposition) {
448
- const filenameMatch = contentDisposition.match(
449
- /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
450
- );
451
- if (filenameMatch && filenameMatch[1]) {
452
- filename = filenameMatch[1].replace(/['"]/g, '');
453
- }
454
- }
455
-
456
- if (filename) {
457
- saveAs(response.data, filename);
458
- } else {
459
- saveAs(response.data);
460
- }
461
-
462
- toast.update(toastId, {
463
- render: 'Download successful!',
464
- type: 'success',
465
- isLoading: false,
466
- autoClose: 5000,
467
- closeButton: true,
468
- });
469
- } else {
470
- throw new Error('No data received from the server');
471
- }
472
- } catch (err) {
473
- console.error(err);
474
- toast.update(toastId, {
475
- render: 'Error downloading form: ' + err.message,
476
- type: 'error',
477
- isLoading: false,
478
- autoClose: 5000,
479
- closeButton: true,
480
- });
481
- }
482
- };
483
-
484
- const handleDeleteForm = async (id, key) => {
485
- const deleteForm = async () => {
486
- try {
487
- const res = await CustomFetch(setting.delete, 'POST', {
488
- client_id: data.id,
489
- form_id: id,
490
- form_key: key,
491
- form_type: type,
492
- });
493
-
494
- if (res.data.error === '') {
495
- toast.success('Form deleted successfully.');
496
- fetchData();
497
- } else {
498
- toast.error('Error: ' + res.data.error);
499
- }
500
- } catch (err) {
501
- console.error(err);
502
- toast.error('Error deleting form');
503
- }
504
- };
505
-
506
- confirmAlert({
507
- title: 'Delete File',
508
- message: 'Are you sure?',
509
- buttons: [
510
- {
511
- label: 'Yes',
512
- onClick: deleteForm,
513
- },
514
- {
515
- label: 'No',
516
- },
517
- ],
518
- });
519
- };
520
-
521
- const handleSaveForm = async () => {
522
- try {
523
- let error = '';
524
-
525
- Object.entries(activeForm).forEach(([key, field]) => {
526
- if (
527
- field.required === true &&
528
- field.type !== 'dynamicdata' &&
529
- (field.value === null || field.value === '')
530
- ) {
531
- error += `<p>${field.label} is required</p>`;
532
- }
533
- });
534
-
535
- if (error === '') {
536
- const res = await CustomFetch(setting.save, 'POST', {
537
- [primaryKey]: data.id,
538
- form_data: {
539
- ...activeForm,
540
- },
541
- form_key: activeFormKey,
542
- form_type: type,
543
- });
544
-
545
- if (res.data.error === '') {
546
- toast.success('Form saved successfully.');
547
- fetchData();
548
- }
549
- } else {
550
- toast.error(<div>{parse(error)}</div>);
551
- }
552
- } catch (err) {
553
- console.log(err);
554
- }
555
- };
556
-
557
- useEffect(() => {
558
- if (data[type] && data[type].length > 0) {
559
- if (multiple) {
560
- if (templateStatus) {
561
- let lastForm = data[type][data[type].length - 1];
562
-
563
- if (lastForm && typeof lastForm === 'object') {
564
- Object.entries(lastForm).forEach(([key, field]) => {
565
- if (field && field.required) {
566
- if (
567
- field.required === 'yes' ||
568
- field.required === 'no'
569
- ) {
570
- lastForm[key].required =
571
- field.required === 'yes';
572
- }
573
- }
574
- });
575
-
576
- setActiveForm(lastForm);
577
- setActiveFormKey(data[type].length - 1);
578
- }
579
- }
580
- } else {
581
- if (data[type].hasOwnProperty('id')) {
582
- if (
583
- Object.keys(activeForm).length === 0 &&
584
- templateStatus &&
585
- data[type][0]
586
- ) {
587
- setActiveForm(data[type][0]);
588
- setActiveFormKey(0);
589
- }
590
- } else {
591
- setActiveForm(data[type]);
592
- setActiveFormKey(0);
593
- }
594
- }
595
- } else {
596
- setActiveForm({});
597
- }
598
- }, [data, type]);
599
-
600
- useEffect(() => {
601
- if (data[type] && data[type].length > 0) {
602
- } else {
603
- if (templateStatus) {
604
- if (multiple) {
605
- if (activeForm.hasOwnProperty('id') === false) {
606
- handleAddNewForm(false);
607
- }
608
- } else {
609
- if (Object.keys(activeForm).length === 0) {
610
- handleAddNewForm(false);
611
- }
612
- }
613
- }
614
- }
615
- }, [activeForm]);
616
-
617
- const shouldDisplayFormList = (data, type) => {
618
- if (!data[type] || !Array.isArray(data[type])) {
619
- return false;
620
- }
621
- return (
622
- data[type].length !== 1 ||
623
- moment(data[type][0].updated_at).isAfter(
624
- moment(data[type][0].created_at)
625
- )
626
- );
627
- };
628
-
629
- return (
630
- <>
631
- <div className={styles.formSplit}>
632
- {multiple && shouldDisplayFormList(data, type) && (
633
- <>
634
- <div className={styles.gridtxt__header}>
635
- <span>Form List</span>
636
- </div>
637
- <table className={styles.contentTable}>
638
- <thead>
639
- <tr>
640
- <th>ID</th>
641
- <th>Form</th>
642
- <th>Created By</th>
643
- <th>Created At</th>
644
- <th>Updated By</th>
645
- <th>Updated At</th>
646
- <th></th>
647
- </tr>
648
- </thead>
649
- <tbody>
650
- {typeof data[type]?.map === 'function' &&
651
- data[type].map((item, index) => {
652
- const idAsNumber = parseFloat(item.id);
653
- if (
654
- !isNaN(idAsNumber) &&
655
- Number.isInteger(idAsNumber)
656
- ) {
657
- return (
658
- <tr
659
- key={`form-list-${index}`}
660
- onClick={(e) => {
661
- e.preventDefault();
662
- handleSelectForm(
663
- item,
664
- index
665
- );
666
- }}
667
- >
668
- <td>{item.id}</td>
669
- <td>{item.form_label}</td>
670
- <td>{item.created_by}</td>
671
- <td>
672
- {item.created_at
673
- ? moment(
674
- item.created_at
675
- ).format(
676
- 'DD-MM-YYYY hh:mm A'
677
- )
678
- : null}
679
- </td>
680
- <td>{item.updated_by}</td>
681
- <td>
682
- {item.updated_at
683
- ? moment(
684
- item.updated_at
685
- ).format(
686
- 'DD-MM-YYYY hh:mm A'
687
- )
688
- : null}
689
- </td>
690
- <td>
691
- <div
692
- className={
693
- styles.tdActions
694
- }
695
- >
696
- <span
697
- data-tooltip-id="system-tooltip"
698
- data-tooltip-content="Download Form"
699
- className="tooltip"
700
- onClick={() =>
701
- handleDownloadForm(
702
- item,
703
- label,
704
- originalData
705
- )
706
- }
707
- >
708
- <CloudDownload
709
- strokeWidth={
710
- 2
711
- }
712
- size={18}
713
- className={
714
- styles.tdAction
715
- }
716
- />
717
- </span>
718
- <span
719
- data-tooltip-id="system-tooltip"
720
- data-tooltip-content="Delete Form"
721
- className="tooltip"
722
- onClick={() =>
723
- handleDeleteForm(
724
- item.id,
725
- index
726
- )
727
- }
728
- >
729
- <Backspace
730
- strokeWidth={
731
- 2
732
- }
733
- size={18}
734
- className={
735
- styles.tdAction
736
- }
737
- />
738
- </span>
739
- </div>
740
- </td>
741
- </tr>
742
- );
743
- }
744
- return null;
745
- })}
746
- </tbody>
747
- </table>
748
- </>
749
- )}
750
-
751
- {activeForm && (
752
- <>
753
- <div className={styles.gridtxt__header}>
754
- <span>
755
- {label}
756
- {multiple && ` - Form #${activeForm?.id ?? ''}`}
757
- </span>
758
- </div>
759
- <div className={styles.formcontainer}>
760
- <div className={styles.modalForm}>
761
- {typeof activeForm === 'object' &&
762
- !Array.isArray(activeForm)
763
- ? Object.entries(activeForm)
764
- .filter(
765
- ([key, value]) =>
766
- typeof value === 'object' &&
767
- [
768
- 'id',
769
- 'label',
770
- 'type',
771
- 'size',
772
- 'value',
773
- ].every((k) =>
774
- value.hasOwnProperty(k)
775
- )
776
- )
777
- .map(
778
- ([key, field]) =>
779
- field.hide === 0 && (
780
- <Field
781
- settings={field}
782
- key={`field-${key}-${field.id}`}
783
- formData={activeForm}
784
- inputClass={''}
785
- inputValue={renderValue(
786
- field,
787
- originalData
788
- )}
789
- onChange={
790
- handleChange
791
- }
792
- onChangeCheckbox={
793
- handleChangeCheckbox
794
- }
795
- onChangeDate={
796
- handleChangeDate
797
- }
798
- onChangeNumberFormat={
799
- handleChangeNumberFormat
800
- }
801
- onChangeSignature={
802
- handleChangeSignature
803
- }
804
- onChangeTableRadio={
805
- handleChangeTableRadio
806
- }
807
- onChangeAddTableTextRow={
808
- handleChangeAddTableTextRow
809
- }
810
- onChangeTableText={
811
- handleChangeTableText
812
- }
813
- onChangeToggle={
814
- handleChangeToggle
815
- }
816
- onFileDownload={
817
- handleFileDownload
818
- }
819
- style={{}}
820
- userProfile={
821
- userProfile
822
- }
823
- />
824
- )
825
- )
826
- : typeof activeForm?.map === 'function' &&
827
- activeForm.map(
828
- (field, index) =>
829
- field.hide === 0 && (
830
- <Field
831
- settings={field}
832
- key={`field-array-${index}-${field.id}`}
833
- formData={activeForm}
834
- inputClass={''}
835
- inputValue={renderValue(
836
- field,
837
- originalData
838
- )}
839
- onChange={handleChange}
840
- onChangeCheckbox={
841
- handleChangeCheckbox
842
- }
843
- onChangeDate={
844
- handleChangeDate
845
- }
846
- onChangeTableRadio={
847
- handleChangeTableRadio
848
- }
849
- onChangeAddTableTextRow={
850
- handleChangeAddTableTextRow
851
- }
852
- onChangeTableText={
853
- handleChangeTableText
854
- }
855
- onChangeToggle={
856
- handleChangeToggle
857
- }
858
- onFileDownload={
859
- handleFileDownload
860
- }
861
- style={{}}
862
- userProfile={userProfile}
863
- />
864
- )
865
- )}
866
- </div>
867
- </div>
868
- </>
869
- )}
870
- </div>
871
- <div className={styles.polActions}>
872
- {buttons.length > 0 &&
873
- buttons.map((button, buttonKey) => (
874
- <button
875
- className={button.className}
876
- key={`button-${buttonKey}`}
877
- onClick={(e) => {
878
- e.preventDefault();
879
-
880
- handleCustomButton(button);
881
- }}
882
- >
883
- {button.label}
884
- </button>
885
- ))}
886
-
887
- {multiple && templateStatus && (
888
- <button className="btn" onClick={handleAddNewForm}>
889
- Add New Form
890
- </button>
891
- )}
892
-
893
- {activeForm.id ? (
894
- <>
895
- {multiple && activeForm.form_status === 0 ? (
896
- <button className="btn" onClick={handleSaveForm}>
897
- Save
898
- </button>
899
- ) : (
900
- <button className="btn" onClick={handleSaveForm}>
901
- Save
902
- </button>
903
- )}
904
- </>
905
- ) : (
906
- <button className="btn" onClick={handleSaveForm}>
907
- Save
908
- </button>
909
- )}
910
- </div>
911
- </>
912
- );
913
- };
914
-
915
- export default GenericDynamic;