@visns-studio/visns-components 5.11.1 → 5.11.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 (48) hide show
  1. package/package.json +2 -2
  2. package/src/components/cms/DataGrid.jsx +8 -8
  3. package/src/components/cms/DropZone.jsx +1 -1
  4. package/src/components/cms/Form.jsx +1 -1
  5. package/src/components/cms/Gallery.jsx +1 -1
  6. package/src/components/cms/sorting/Item.jsx +1 -1
  7. package/src/components/crm/Autocomplete.jsx +3 -3
  8. package/src/components/crm/Breadcrumb.jsx +4 -4
  9. package/src/components/crm/BusinessCardOcr.jsx +681 -95
  10. package/src/components/crm/DataGrid.jsx +34 -32
  11. package/src/components/crm/Field.jsx +12 -12
  12. package/src/components/crm/Form.jsx +2 -2
  13. package/src/components/crm/Navigation.jsx +11 -11
  14. package/src/components/crm/Notification.jsx +2 -2
  15. package/src/components/crm/QuickAction.jsx +3 -3
  16. package/src/components/crm/SectionHeader.jsx +1 -1
  17. package/src/components/crm/SwitchAccount.jsx +4 -4
  18. package/src/components/crm/auth/ClientLogin.jsx +2 -2
  19. package/src/components/crm/auth/ClientOTPVerify.jsx +2 -2
  20. package/src/components/crm/auth/Login.jsx +3 -3
  21. package/src/components/crm/auth/Reset.jsx +2 -2
  22. package/src/components/crm/auth/TwoFactorAuth.jsx +2 -2
  23. package/src/components/crm/columns/ColumnRenderers.jsx +320 -259
  24. package/src/components/crm/controls/DataGridSearch.jsx +5 -5
  25. package/src/components/crm/generic/AlternativeActionModal.jsx +100 -0
  26. package/src/components/crm/generic/ContactSelectorModal.jsx +59 -16
  27. package/src/components/crm/generic/DateRangeSelectorModal.jsx +181 -0
  28. package/src/components/crm/generic/GenericClientPortal.jsx +1 -1
  29. package/src/components/crm/generic/GenericDashboard.jsx +4 -4
  30. package/src/components/crm/generic/GenericDetail.jsx +6 -6
  31. package/src/components/crm/generic/GenericDynamic.jsx +3 -3
  32. package/src/components/crm/generic/GenericEditableTable.jsx +4 -4
  33. package/src/components/crm/generic/GenericFormBuilder.jsx +6 -6
  34. package/src/components/crm/generic/GenericGrid.jsx +1622 -268
  35. package/src/components/crm/generic/GenericReport.jsx +966 -646
  36. package/src/components/crm/generic/GenericReportForm.jsx +1 -1
  37. package/src/components/crm/generic/NotificationList.jsx +1 -1
  38. package/src/components/crm/generic/ReasonCollectorModal.jsx +194 -0
  39. package/src/components/crm/generic/SortableQuoteItems.jsx +3 -3
  40. package/src/components/crm/generic/shared/formatters.js +107 -1
  41. package/src/components/crm/generic/styles/AlternativeActionModal.css +127 -0
  42. package/src/components/crm/generic/styles/DateRangeSelectorModal.css +115 -0
  43. package/src/components/crm/generic/styles/GenericIndex.module.scss +206 -0
  44. package/src/components/crm/generic/styles/GenericReport.module.scss +96 -0
  45. package/src/components/crm/generic/styles/ReasonCollectorModal.css +217 -0
  46. package/src/components/crm/modals/GalleryModal.jsx +2 -2
  47. package/src/components/crm/sorting/Item.jsx +3 -3
  48. package/src/components/crm/styles/BusinessCardOcr.module.scss +197 -4
@@ -1,12 +1,17 @@
1
1
  import numeral from 'numeral';
2
2
  import moment from 'moment';
3
3
  import parse from 'html-react-parser';
4
- import { CloudDownload, Alarm } from 'akar-icons';
4
+ import { Download, AlarmClock } from 'lucide-react';
5
5
  import { toast } from 'react-toastify';
6
6
  import CellWithTooltip from '../cells/CellWithTooltip';
7
7
 
8
8
  // Boolean Column Renderer
9
- export const renderBooleanColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
9
+ export const renderBooleanColumn = ({
10
+ column,
11
+ commonProps,
12
+ filterEditor,
13
+ filterEditorProps,
14
+ }) => {
10
15
  return {
11
16
  ...commonProps,
12
17
  filterEditor: filterEditor,
@@ -16,10 +21,7 @@ export const renderBooleanColumn = ({ column, commonProps, filterEditor, filterE
16
21
  render: ({ data }) => {
17
22
  const value = data[column.id] ? 'Yes' : 'No';
18
23
  return (
19
- <CellWithTooltip
20
- value={data[column.id]}
21
- columnType="boolean"
22
- >
24
+ <CellWithTooltip value={data[column.id]} columnType="boolean">
23
25
  <span>{value}</span>
24
26
  </CellWithTooltip>
25
27
  );
@@ -34,7 +36,9 @@ export const renderCurrencyColumn = ({ column, commonProps }) => {
34
36
  name: column.id,
35
37
  render: ({ data }) => {
36
38
  if (data) {
37
- const formattedValue = numeral(data[column.id]).format('$0,0.00');
39
+ const formattedValue = numeral(data[column.id]).format(
40
+ '$0,0.00'
41
+ );
38
42
 
39
43
  return (
40
44
  <CellWithTooltip
@@ -52,7 +56,12 @@ export const renderCurrencyColumn = ({ column, commonProps }) => {
52
56
  };
53
57
 
54
58
  // Date Column Renderer
55
- export const renderDateColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
59
+ export const renderDateColumn = ({
60
+ column,
61
+ commonProps,
62
+ filterEditor,
63
+ filterEditorProps,
64
+ }) => {
56
65
  return {
57
66
  ...commonProps,
58
67
  name: column.id,
@@ -88,13 +97,8 @@ export const renderDateColumn = ({ column, commonProps, filterEditor, filterEdit
88
97
  }
89
98
 
90
99
  return (
91
- <CellWithTooltip
92
- value={data[column.id]}
93
- columnType="date"
94
- >
95
- <span style={columnStyle}>
96
- {value}
97
- </span>
100
+ <CellWithTooltip value={data[column.id]} columnType="date">
101
+ <span style={columnStyle}>{value}</span>
98
102
  </CellWithTooltip>
99
103
  );
100
104
  } else {
@@ -105,7 +109,12 @@ export const renderDateColumn = ({ column, commonProps, filterEditor, filterEdit
105
109
  };
106
110
 
107
111
  // DateTime Column Renderer
108
- export const renderDateTimeColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
112
+ export const renderDateTimeColumn = ({
113
+ column,
114
+ commonProps,
115
+ filterEditor,
116
+ filterEditorProps,
117
+ }) => {
109
118
  return {
110
119
  ...commonProps,
111
120
  name: column.id,
@@ -168,7 +177,8 @@ export const renderColourColumn = ({ column, commonProps }) => {
168
177
  <div
169
178
  style={{
170
179
  background:
171
- data[column.id] + ' none repeat scroll 0% 0%',
180
+ data[column.id] +
181
+ ' none repeat scroll 0% 0%',
172
182
  height: '100%',
173
183
  width: '100%',
174
184
  cursor: 'pointer',
@@ -186,17 +196,15 @@ export const renderColourColumn = ({ column, commonProps }) => {
186
196
  };
187
197
 
188
198
  // Dropdown Column Renderer
189
- export const renderDropdownColumn = ({
190
- column,
191
- commonProps,
192
- filterEditor,
193
- filterEditorProps,
194
- dropdownData,
195
- handleDropdownUpdate
199
+ export const renderDropdownColumn = ({
200
+ column,
201
+ commonProps,
202
+ filterEditor,
203
+ filterEditorProps,
204
+ dropdownData,
205
+ handleDropdownUpdate,
196
206
  }) => {
197
- const columnId = Array.isArray(column.id)
198
- ? column.id.join('-')
199
- : column.id;
207
+ const columnId = Array.isArray(column.id) ? column.id.join('-') : column.id;
200
208
 
201
209
  return {
202
210
  ...commonProps,
@@ -227,8 +235,7 @@ export const renderDropdownColumn = ({
227
235
  }}
228
236
  >
229
237
  <option value="">
230
- Select{' '}
231
- {/^[aeioAEIO]/.test(column.label) ? 'an' : 'a'}{' '}
238
+ Select {/^[aeioAEIO]/.test(column.label) ? 'an' : 'a'}{' '}
232
239
  {column.label}
233
240
  </option>
234
241
  {dropdownData[column.id] &&
@@ -252,7 +259,8 @@ export const renderImageColumn = ({ column, commonProps }) => {
252
259
  name: column.id,
253
260
  render: ({ data }) => {
254
261
  if (data && data[column.id]) {
255
- const fileUrl = data[column.id][0]?.file_url || data[column.id]?.file_url;
262
+ const fileUrl =
263
+ data[column.id][0]?.file_url || data[column.id]?.file_url;
256
264
 
257
265
  if (fileUrl) {
258
266
  return (
@@ -269,7 +277,12 @@ export const renderImageColumn = ({ column, commonProps }) => {
269
277
  };
270
278
 
271
279
  // File Column Renderer
272
- export const renderFileColumn = ({ column, commonProps, handleDownload, styles }) => {
280
+ export const renderFileColumn = ({
281
+ column,
282
+ commonProps,
283
+ handleDownload,
284
+ styles,
285
+ }) => {
273
286
  return {
274
287
  ...commonProps,
275
288
  name: column.id,
@@ -292,7 +305,7 @@ export const renderFileColumn = ({ column, commonProps, handleDownload, styles }
292
305
  display: 'inline-block',
293
306
  }}
294
307
  >
295
- <CloudDownload
308
+ <Download
296
309
  data-tooltip-id="system-tooltip"
297
310
  data-tooltip-content={`Download File ${file.file_name}`}
298
311
  strokeWidth={2}
@@ -315,9 +328,11 @@ export const renderFileColumn = ({ column, commonProps, handleDownload, styles }
315
328
  display: 'inline-block',
316
329
  }}
317
330
  >
318
- <CloudDownload
331
+ <Download
319
332
  data-tooltip-id="system-tooltip"
320
- data-tooltip-content={`Download File ${data[column.id].file_name}`}
333
+ data-tooltip-content={`Download File ${
334
+ data[column.id].file_name
335
+ }`}
321
336
  strokeWidth={2}
322
337
  size={14}
323
338
  className={styles.tdaction}
@@ -370,49 +385,81 @@ export const renderJsonColumn = ({ column, commonProps }) => {
370
385
  ...commonProps,
371
386
  name: `${column.id}.${column.jsonData}`,
372
387
  render: ({ data }) => {
373
- if (
374
- data &&
375
- data[column.id] &&
376
- data[column.id][column.jsonData]
377
- ) {
388
+ if (data && data[column.id] && data[column.id][column.jsonData]) {
378
389
  const jsonValue = data[column.id][column.jsonData];
379
-
390
+
380
391
  if (!jsonValue) return null;
381
-
392
+
382
393
  let displayContent;
383
394
  let tooltipValue = jsonValue;
384
-
395
+
385
396
  try {
386
- const jsonData = typeof jsonValue === 'string' ? JSON.parse(jsonValue) : jsonValue;
387
-
397
+ const jsonData =
398
+ typeof jsonValue === 'string'
399
+ ? JSON.parse(jsonValue)
400
+ : jsonValue;
401
+
388
402
  // Check if this looks like a question/answer format
389
- const isQuestionAnswerFormat = Object.values(jsonData).every(item =>
390
- item && typeof item === 'object' &&
391
- (item.hasOwnProperty('question') || item.hasOwnProperty('answer'))
403
+ const isQuestionAnswerFormat = Object.values(
404
+ jsonData
405
+ ).every(
406
+ (item) =>
407
+ item &&
408
+ typeof item === 'object' &&
409
+ (item.hasOwnProperty('question') ||
410
+ item.hasOwnProperty('answer'))
392
411
  );
393
-
412
+
394
413
  if (isQuestionAnswerFormat) {
395
414
  const entries = Object.entries(jsonData);
396
415
  if (entries.length === 1) {
397
416
  const [key, item] = entries[0];
398
- const question = item.question || key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
399
- const answer = item.answer !== undefined ?
400
- (typeof item.answer === 'boolean' ? (item.answer ? 'Yes' : 'No') : String(item.answer)) :
401
- 'N/A';
402
-
417
+ const question =
418
+ item.question ||
419
+ key
420
+ .replace(/_/g, ' ')
421
+ .replace(/\b\w/g, (l) => l.toUpperCase());
422
+ const answer =
423
+ item.answer !== undefined
424
+ ? typeof item.answer === 'boolean'
425
+ ? item.answer
426
+ ? 'Yes'
427
+ : 'No'
428
+ : String(item.answer)
429
+ : 'N/A';
430
+
403
431
  displayContent = (
404
432
  <div style={{ fontSize: '0.8rem' }}>
405
- <div style={{ fontWeight: '600', color: 'var(--primary-color)', marginBottom: '0.1rem', fontSize: '0.75rem' }}>
406
- {question.length > 50 ? question.substring(0, 50) + '...' : question}
433
+ <div
434
+ style={{
435
+ fontWeight: '600',
436
+ color: 'var(--primary-color)',
437
+ marginBottom: '0.1rem',
438
+ fontSize: '0.75rem',
439
+ }}
440
+ >
441
+ {question.length > 50
442
+ ? question.substring(0, 50) + '...'
443
+ : question}
407
444
  </div>
408
- <div style={{ color: 'var(--paragraph-color)', fontSize: '0.75rem' }}>
445
+ <div
446
+ style={{
447
+ color: 'var(--paragraph-color)',
448
+ fontSize: '0.75rem',
449
+ }}
450
+ >
409
451
  {answer}
410
452
  </div>
411
453
  </div>
412
454
  );
413
455
  } else {
414
456
  displayContent = (
415
- <div style={{ fontSize: '0.75rem', color: 'var(--paragraph-color)' }}>
457
+ <div
458
+ style={{
459
+ fontSize: '0.75rem',
460
+ color: 'var(--paragraph-color)',
461
+ }}
462
+ >
416
463
  Q&A ({entries.length} items)
417
464
  </div>
418
465
  );
@@ -420,20 +467,54 @@ export const renderJsonColumn = ({ column, commonProps }) => {
420
467
  tooltipValue = JSON.stringify(jsonData, null, 2);
421
468
  }
422
469
  // Check if this is a simple key-value object
423
- else if (Object.values(jsonData).every(val => typeof val !== 'object' || val === null)) {
470
+ else if (
471
+ Object.values(jsonData).every(
472
+ (val) => typeof val !== 'object' || val === null
473
+ )
474
+ ) {
424
475
  const entries = Object.entries(jsonData);
425
476
  if (entries.length <= 2) {
426
477
  displayContent = (
427
478
  <div style={{ fontSize: '0.8rem' }}>
428
479
  {entries.map(([key, val]) => (
429
- <div key={key} style={{ marginBottom: '0.1rem', display: 'flex', gap: '0.3rem' }}>
430
- <strong style={{ color: 'var(--primary-color)', fontSize: '0.7rem' }}>
431
- {key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}:
480
+ <div
481
+ key={key}
482
+ style={{
483
+ marginBottom: '0.1rem',
484
+ display: 'flex',
485
+ gap: '0.3rem',
486
+ }}
487
+ >
488
+ <strong
489
+ style={{
490
+ color: 'var(--primary-color)',
491
+ fontSize: '0.7rem',
492
+ }}
493
+ >
494
+ {key
495
+ .replace(/_/g, ' ')
496
+ .replace(/\b\w/g, (l) =>
497
+ l.toUpperCase()
498
+ )}
499
+ :
432
500
  </strong>
433
- <span style={{ color: 'var(--paragraph-color)', fontSize: '0.7rem' }}>
434
- {val !== null && val !== undefined ?
435
- (typeof val === 'boolean' ? (val ? 'Yes' : 'No') : String(val).substring(0, 15)) :
436
- 'N/A'}
501
+ <span
502
+ style={{
503
+ color: 'var(--paragraph-color)',
504
+ fontSize: '0.7rem',
505
+ }}
506
+ >
507
+ {val !== null &&
508
+ val !== undefined
509
+ ? typeof val === 'boolean'
510
+ ? val
511
+ ? 'Yes'
512
+ : 'No'
513
+ : String(val).substring(
514
+ 0,
515
+ 15
516
+ )
517
+ : 'N/A'}
437
518
  </span>
438
519
  </div>
439
520
  ))}
@@ -441,7 +522,12 @@ export const renderJsonColumn = ({ column, commonProps }) => {
441
522
  );
442
523
  } else {
443
524
  displayContent = (
444
- <div style={{ fontSize: '0.75rem', color: 'var(--paragraph-color)' }}>
525
+ <div
526
+ style={{
527
+ fontSize: '0.75rem',
528
+ color: 'var(--paragraph-color)',
529
+ }}
530
+ >
445
531
  Data ({entries.length} properties)
446
532
  </div>
447
533
  );
@@ -452,20 +538,33 @@ export const renderJsonColumn = ({ column, commonProps }) => {
452
538
  else {
453
539
  const keyCount = Object.keys(jsonData).length;
454
540
  displayContent = (
455
- <div style={{ fontSize: '0.75rem', color: 'var(--paragraph-color)', fontStyle: 'italic' }}>
456
- JSON ({keyCount} {keyCount === 1 ? 'property' : 'properties'})
541
+ <div
542
+ style={{
543
+ fontSize: '0.75rem',
544
+ color: 'var(--paragraph-color)',
545
+ fontStyle: 'italic',
546
+ }}
547
+ >
548
+ JSON ({keyCount}{' '}
549
+ {keyCount === 1 ? 'property' : 'properties'})
457
550
  </div>
458
551
  );
459
552
  tooltipValue = JSON.stringify(jsonData, null, 2);
460
553
  }
461
-
462
554
  } catch (error) {
463
555
  // If parsing fails, show truncated raw value
464
- const displayValue = typeof jsonValue === 'string' && jsonValue.length > 30
465
- ? jsonValue.substring(0, 30) + '...'
466
- : jsonValue;
556
+ const displayValue =
557
+ typeof jsonValue === 'string' && jsonValue.length > 30
558
+ ? jsonValue.substring(0, 30) + '...'
559
+ : jsonValue;
467
560
  displayContent = (
468
- <span style={{ fontSize: '0.75rem', fontFamily: 'monospace', color: 'var(--paragraph-color)' }}>
561
+ <span
562
+ style={{
563
+ fontSize: '0.75rem',
564
+ fontFamily: 'monospace',
565
+ color: 'var(--paragraph-color)',
566
+ }}
567
+ >
469
568
  {displayValue}
470
569
  </span>
471
570
  );
@@ -473,10 +572,7 @@ export const renderJsonColumn = ({ column, commonProps }) => {
473
572
  }
474
573
 
475
574
  return (
476
- <CellWithTooltip
477
- value={tooltipValue}
478
- columnType="json"
479
- >
575
+ <CellWithTooltip value={tooltipValue} columnType="json">
480
576
  {displayContent}
481
577
  </CellWithTooltip>
482
578
  );
@@ -497,7 +593,12 @@ export const renderNumberColumn = ({ column, commonProps }) => {
497
593
  };
498
594
 
499
595
  // Option Column Renderer
500
- export const renderOptionColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
596
+ export const renderOptionColumn = ({
597
+ column,
598
+ commonProps,
599
+ filterEditor,
600
+ filterEditorProps,
601
+ }) => {
501
602
  return {
502
603
  ...commonProps,
503
604
  name: column.id,
@@ -506,11 +607,7 @@ export const renderOptionColumn = ({ column, commonProps, filterEditor, filterEd
506
607
  render: ({ data }) => {
507
608
  let newData;
508
609
 
509
- if (
510
- data &&
511
- column.options &&
512
- column.options[data[column.id]]
513
- ) {
610
+ if (data && column.options && column.options[data[column.id]]) {
514
611
  if (
515
612
  column.key &&
516
613
  data[column.key] > 0 &&
@@ -525,10 +622,7 @@ export const renderOptionColumn = ({ column, commonProps, filterEditor, filterEd
525
622
  }
526
623
 
527
624
  return (
528
- <CellWithTooltip
529
- value={newData}
530
- columnType="option"
531
- >
625
+ <CellWithTooltip value={newData} columnType="option">
532
626
  <span>{newData}</span>
533
627
  </CellWithTooltip>
534
628
  );
@@ -613,7 +707,13 @@ export const renderCodingColumn = ({ column, commonProps, handleCoding }) => {
613
707
  };
614
708
 
615
709
  // Relation Column Renderer
616
- export const renderRelationColumn = ({ column, commonProps, filterEditor, filterEditorProps, relationName }) => {
710
+ export const renderRelationColumn = ({
711
+ column,
712
+ commonProps,
713
+ filterEditor,
714
+ filterEditorProps,
715
+ relationName,
716
+ }) => {
617
717
  return {
618
718
  ...commonProps,
619
719
  name: relationName,
@@ -649,23 +749,13 @@ export const renderRelationColumn = ({ column, commonProps, filterEditor, filter
649
749
  .map((nf) => value?.[nf] ?? '')
650
750
  .join(' ');
651
751
  } else {
652
- if (
653
- value &&
654
- value.hasOwnProperty(column.nameFrom)
655
- ) {
752
+ if (value && value.hasOwnProperty(column.nameFrom)) {
656
753
  value = value[column.nameFrom];
657
754
  }
658
755
  }
659
756
 
660
- if (
661
- column.placeholder &&
662
- column.placeholder !== ''
663
- ) {
664
- return (
665
- <span>
666
- {column.placeholder}
667
- </span>
668
- );
757
+ if (column.placeholder && column.placeholder !== '') {
758
+ return <span>{column.placeholder}</span>;
669
759
  } else {
670
760
  if (column.hasOwnProperty('format')) {
671
761
  if (column.format) {
@@ -697,7 +787,13 @@ export const renderRelationColumn = ({ column, commonProps, filterEditor, filter
697
787
  };
698
788
 
699
789
  // RelationArray Column Renderer
700
- export const renderRelationArrayColumn = ({ column, commonProps, filterEditor, filterEditorProps, relationName }) => {
790
+ export const renderRelationArrayColumn = ({
791
+ column,
792
+ commonProps,
793
+ filterEditor,
794
+ filterEditorProps,
795
+ relationName,
796
+ }) => {
701
797
  return {
702
798
  ...commonProps,
703
799
  name: relationName,
@@ -707,11 +803,7 @@ export const renderRelationArrayColumn = ({ column, commonProps, filterEditor, f
707
803
  render: ({ data }) => {
708
804
  const relationValue = column.id.reduce(
709
805
  (acc, id) =>
710
- acc === ''
711
- ? data[id]
712
- : acc && acc[id]
713
- ? acc[id]
714
- : '',
806
+ acc === '' ? data[id] : acc && acc[id] ? acc[id] : '',
715
807
  ''
716
808
  );
717
809
 
@@ -720,17 +812,13 @@ export const renderRelationArrayColumn = ({ column, commonProps, filterEditor, f
720
812
  Array.isArray(relationValue) &&
721
813
  relationValue.length > 0
722
814
  ) {
723
- const nameProperties =
724
- Array.isArray(column.nameFrom)
725
- ? column.nameFrom
726
- : [column.nameFrom];
815
+ const nameProperties = Array.isArray(column.nameFrom)
816
+ ? column.nameFrom
817
+ : [column.nameFrom];
727
818
 
728
819
  const values = relationValue
729
820
  .map((rv) => {
730
- if (
731
- column.childId &&
732
- Array.isArray(column.childId)
733
- ) {
821
+ if (column.childId && Array.isArray(column.childId)) {
734
822
  let childValue = rv;
735
823
 
736
824
  column.childId.forEach((a) => {
@@ -740,25 +828,22 @@ export const renderRelationArrayColumn = ({ column, commonProps, filterEditor, f
740
828
  });
741
829
 
742
830
  if (childValue) {
743
- const propertyValues =
744
- nameProperties
745
- .map((prop) => childValue[prop])
746
- .filter(
747
- (value) =>
748
- value !== undefined &&
749
- value !== null
750
- );
751
- return propertyValues.join(' ');
752
- }
753
- } else {
754
- const propertyValues =
755
- nameProperties
756
- .map((prop) => rv[prop])
831
+ const propertyValues = nameProperties
832
+ .map((prop) => childValue[prop])
757
833
  .filter(
758
834
  (value) =>
759
835
  value !== undefined &&
760
836
  value !== null
761
837
  );
838
+ return propertyValues.join(' ');
839
+ }
840
+ } else {
841
+ const propertyValues = nameProperties
842
+ .map((prop) => rv[prop])
843
+ .filter(
844
+ (value) =>
845
+ value !== undefined && value !== null
846
+ );
762
847
  return propertyValues.join(' ');
763
848
  }
764
849
  })
@@ -766,33 +851,22 @@ export const renderRelationArrayColumn = ({ column, commonProps, filterEditor, f
766
851
 
767
852
  let result = '';
768
853
 
769
- if (
770
- column.relation?.id &&
771
- column.relation?.key
772
- ) {
773
- const relationValue =
774
- column.relation.key.reduce(
775
- (acc, id) =>
776
- acc === ''
777
- ? data[id]
778
- : acc && acc[id]
779
- ? acc[id]
780
- : '',
781
- ''
782
- );
854
+ if (column.relation?.id && column.relation?.key) {
855
+ const relationValue = column.relation.key.reduce(
856
+ (acc, id) =>
857
+ acc === ''
858
+ ? data[id]
859
+ : acc && acc[id]
860
+ ? acc[id]
861
+ : '',
862
+ ''
863
+ );
783
864
 
784
865
  result = `${relationValue[column.relation.id]}<br />`;
785
866
  }
786
867
 
787
- if (
788
- column.where &&
789
- column.where.id &&
790
- column.where.value
791
- ) {
792
- if (
793
- data[column.where.id] ===
794
- column.where.value
795
- ) {
868
+ if (column.where && column.where.id && column.where.value) {
869
+ if (data[column.where.id] === column.where.value) {
796
870
  result += values.join('<br />');
797
871
  }
798
872
  } else {
@@ -800,43 +874,32 @@ export const renderRelationArrayColumn = ({ column, commonProps, filterEditor, f
800
874
  }
801
875
 
802
876
  return (
803
- <CellWithTooltip
804
- value={result}
805
- columnType="relationArray"
806
- >
877
+ <CellWithTooltip value={result} columnType="relationArray">
807
878
  <span>{parse(result)}</span>
808
879
  </CellWithTooltip>
809
880
  );
810
881
  } else {
811
882
  let result = '';
812
883
 
813
- if (
814
- column.relation?.id &&
815
- column.relation?.key
816
- ) {
817
- const relationValue =
818
- column.relation.key.reduce(
819
- (acc, id) =>
820
- acc === ''
821
- ? data[id]
822
- : acc && acc[id]
823
- ? acc[id]
824
- : '',
825
- ''
826
- );
884
+ if (column.relation?.id && column.relation?.key) {
885
+ const relationValue = column.relation.key.reduce(
886
+ (acc, id) =>
887
+ acc === ''
888
+ ? data[id]
889
+ : acc && acc[id]
890
+ ? acc[id]
891
+ : '',
892
+ ''
893
+ );
827
894
 
828
895
  result =
829
- relationValue &&
830
- relationValue[column.relation.id]
896
+ relationValue && relationValue[column.relation.id]
831
897
  ? relationValue[column.relation.id]
832
898
  : '';
833
899
  }
834
900
 
835
901
  return (
836
- <CellWithTooltip
837
- value={result}
838
- columnType="relationArray"
839
- >
902
+ <CellWithTooltip value={result} columnType="relationArray">
840
903
  <span>{parse(result)}</span>
841
904
  </CellWithTooltip>
842
905
  );
@@ -859,9 +922,7 @@ export const renderRichTextColumn = ({ column, commonProps }) => {
859
922
  value={data[column.id]}
860
923
  columnType="richtext"
861
924
  >
862
- <span>
863
- {parse(data[column.id])}
864
- </span>
925
+ <span>{parse(data[column.id])}</span>
865
926
  </CellWithTooltip>
866
927
  );
867
928
  } else {
@@ -887,10 +948,7 @@ export const renderStageColumn = ({ column, commonProps }) => {
887
948
  });
888
949
 
889
950
  return (
890
- <CellWithTooltip
891
- value={stage}
892
- columnType="stage"
893
- >
951
+ <CellWithTooltip value={stage} columnType="stage">
894
952
  <span>{stage}</span>
895
953
  </CellWithTooltip>
896
954
  );
@@ -915,10 +973,7 @@ export const renderTimeColumn = ({ column, commonProps }) => {
915
973
  );
916
974
 
917
975
  return (
918
- <CellWithTooltip
919
- value={data[column.id]}
920
- columnType="time"
921
- >
976
+ <CellWithTooltip value={data[column.id]} columnType="time">
922
977
  <span>{formattedTime}</span>
923
978
  </CellWithTooltip>
924
979
  );
@@ -930,7 +985,14 @@ export const renderTimeColumn = ({ column, commonProps }) => {
930
985
  };
931
986
 
932
987
  // Timer Column Renderer
933
- export const renderTimerColumn = ({ column, commonProps, handleTimer, form, columns, styles }) => {
988
+ export const renderTimerColumn = ({
989
+ column,
990
+ commonProps,
991
+ handleTimer,
992
+ form,
993
+ columns,
994
+ styles,
995
+ }) => {
934
996
  return {
935
997
  ...commonProps,
936
998
  name: column.id,
@@ -946,10 +1008,7 @@ export const renderTimerColumn = ({ column, commonProps, handleTimer, form, colu
946
1008
  );
947
1009
 
948
1010
  return (
949
- <CellWithTooltip
950
- value={data[column.id]}
951
- columnType="timer"
952
- >
1011
+ <CellWithTooltip value={data[column.id]} columnType="timer">
953
1012
  <span>{formattedData}</span>
954
1013
  </CellWithTooltip>
955
1014
  );
@@ -991,9 +1050,8 @@ export const renderTimerColumn = ({ column, commonProps, handleTimer, form, colu
991
1050
  column.validate &&
992
1051
  column.validate.length > 0
993
1052
  ) {
994
- const missingFields = column.validate.filter(
995
- (v) => !data[v]
996
- );
1053
+ const missingFields =
1054
+ column.validate.filter((v) => !data[v]);
997
1055
 
998
1056
  if (missingFields.length === 0) {
999
1057
  handleTimer(
@@ -1003,21 +1061,27 @@ export const renderTimerColumn = ({ column, commonProps, handleTimer, form, colu
1003
1061
  );
1004
1062
  } else {
1005
1063
  // Format field names to be more readable
1006
- const formattedFields = missingFields.map(
1007
- (field) => {
1064
+ const formattedFields =
1065
+ missingFields.map((field) => {
1008
1066
  // Try to find the column with this field ID to get its label
1009
- const fieldColumn = columns.find(
1010
- (col) => col.id === field
1011
- );
1067
+ const fieldColumn =
1068
+ columns.find(
1069
+ (col) =>
1070
+ col.id === field
1071
+ );
1012
1072
  // Use the label if found, otherwise use the field ID
1013
- return fieldColumn?.label || field;
1014
- }
1015
- );
1073
+ return (
1074
+ fieldColumn?.label || field
1075
+ );
1076
+ });
1016
1077
 
1017
- const fieldList = formattedFields.join(', ');
1078
+ const fieldList =
1079
+ formattedFields.join(', ');
1018
1080
  toast.error(
1019
1081
  `Please complete the following required field${
1020
- missingFields.length > 1 ? 's' : ''
1082
+ missingFields.length > 1
1083
+ ? 's'
1084
+ : ''
1021
1085
  } before starting the timer: ${fieldList}`
1022
1086
  );
1023
1087
  }
@@ -1030,7 +1094,7 @@ export const renderTimerColumn = ({ column, commonProps, handleTimer, form, colu
1030
1094
  }
1031
1095
  }}
1032
1096
  >
1033
- <Alarm
1097
+ <AlarmClock
1034
1098
  data-tooltip-id="system-tooltip"
1035
1099
  data-tooltip-content={`${column.label} Timer`}
1036
1100
  strokeWidth={2}
@@ -1071,15 +1135,9 @@ export const renderUrlColumn = ({ column, commonProps }) => {
1071
1135
  render: ({ data }) => {
1072
1136
  if (data && data[column.id]) {
1073
1137
  return (
1074
- <CellWithTooltip
1075
- value={data[column.id]}
1076
- columnType="url"
1077
- >
1138
+ <CellWithTooltip value={data[column.id]} columnType="url">
1078
1139
  <span>
1079
- <a
1080
- href={data[column.id]}
1081
- target="_blank"
1082
- >
1140
+ <a href={data[column.id]} target="_blank">
1083
1141
  Link
1084
1142
  </a>
1085
1143
  </span>
@@ -1093,12 +1151,12 @@ export const renderUrlColumn = ({ column, commonProps }) => {
1093
1151
  };
1094
1152
 
1095
1153
  // Input Text Column Renderer
1096
- export const renderInputTextColumn = ({
1097
- column,
1098
- commonProps,
1099
- localInputValuesRef,
1100
- setLocalInputValues,
1101
- handleInputUpdate
1154
+ export const renderInputTextColumn = ({
1155
+ column,
1156
+ commonProps,
1157
+ localInputValuesRef,
1158
+ setLocalInputValues,
1159
+ handleInputUpdate,
1102
1160
  }) => {
1103
1161
  return {
1104
1162
  ...commonProps,
@@ -1165,7 +1223,12 @@ export const renderInputTextColumn = ({
1165
1223
  };
1166
1224
 
1167
1225
  // Address Column Renderer
1168
- export const renderAddressColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
1226
+ export const renderAddressColumn = ({
1227
+ column,
1228
+ commonProps,
1229
+ filterEditor,
1230
+ filterEditorProps,
1231
+ }) => {
1169
1232
  return {
1170
1233
  ...commonProps,
1171
1234
  name: `${column.type}.${column.id}`,
@@ -1184,18 +1247,12 @@ export const renderAddressColumn = ({ column, commonProps, filterEditor, filterE
1184
1247
  .map((field) => data[field])
1185
1248
  .join(' ');
1186
1249
 
1187
- const stateValue =
1188
- data.state?.name ||
1189
- data.state ||
1190
- '';
1250
+ const stateValue = data.state?.name || data.state || '';
1191
1251
 
1192
1252
  const value = `${addressValue} ${stateValue}`;
1193
1253
 
1194
1254
  return (
1195
- <CellWithTooltip
1196
- value={value}
1197
- columnType="address"
1198
- >
1255
+ <CellWithTooltip value={value} columnType="address">
1199
1256
  <span>{value}</span>
1200
1257
  </CellWithTooltip>
1201
1258
  );
@@ -1226,7 +1283,12 @@ export const renderCreatedByColumn = ({ column, commonProps }) => {
1226
1283
  };
1227
1284
 
1228
1285
  // Date Range Column Renderer
1229
- export const renderDateRangeColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
1286
+ export const renderDateRangeColumn = ({
1287
+ column,
1288
+ commonProps,
1289
+ filterEditor,
1290
+ filterEditorProps,
1291
+ }) => {
1230
1292
  return {
1231
1293
  ...commonProps,
1232
1294
  name: `${column.id[0]}.${column.id[1]}.`,
@@ -1271,18 +1333,11 @@ export const renderStageCounterColumn = ({ column, commonProps, navigate }) => {
1271
1333
  name: column.id,
1272
1334
  sortable: false,
1273
1335
  render: ({ data }) => {
1274
- if (
1275
- data &&
1276
- column.stageConfig &&
1277
- column.stageConfig.key
1278
- ) {
1336
+ if (data && column.stageConfig && column.stageConfig.key) {
1279
1337
  // Check if the data has the specified key and it's an array
1280
1338
  const stageData = data[column.stageConfig.key];
1281
1339
 
1282
- if (
1283
- stageData &&
1284
- Array.isArray(stageData)
1285
- ) {
1340
+ if (stageData && Array.isArray(stageData)) {
1286
1341
  const stageCount = stageData.length;
1287
1342
 
1288
1343
  // Create a clickable element if link is provided
@@ -1313,10 +1368,12 @@ export const renderStageCounterColumn = ({ column, commonProps, navigate }) => {
1313
1368
  if (
1314
1369
  column.stageConfig.stageLabelKey &&
1315
1370
  stageItem &&
1316
- stageItem[column.stageConfig.stageLabelKey] !== undefined
1371
+ stageItem[column.stageConfig.stageLabelKey] !==
1372
+ undefined
1317
1373
  ) {
1318
1374
  // Get the value from the stage item
1319
- const rawValue = stageItem[column.stageConfig.stageLabelKey];
1375
+ const rawValue =
1376
+ stageItem[column.stageConfig.stageLabelKey];
1320
1377
 
1321
1378
  // If it's an object with a name property, use that
1322
1379
  if (
@@ -1349,13 +1406,16 @@ export const renderStageCounterColumn = ({ column, commonProps, navigate }) => {
1349
1406
  stageItem &&
1350
1407
  stageItem[column.stageConfig.stageLabelKey]
1351
1408
  ) {
1352
- const rawValue = stageItem[column.stageConfig.stageLabelKey];
1409
+ const rawValue =
1410
+ stageItem[column.stageConfig.stageLabelKey];
1353
1411
  if (
1354
1412
  rawValue &&
1355
1413
  typeof rawValue === 'object' &&
1356
1414
  rawValue.name
1357
1415
  ) {
1358
- tooltipContent = `${rawValue.name} (Stage ${i + 1})`;
1416
+ tooltipContent = `${rawValue.name} (Stage ${
1417
+ i + 1
1418
+ })`;
1359
1419
  } else if (
1360
1420
  rawValue !== null &&
1361
1421
  rawValue !== undefined
@@ -1373,32 +1433,33 @@ export const renderStageCounterColumn = ({ column, commonProps, navigate }) => {
1373
1433
  column.stageConfig.stageColour.options &&
1374
1434
  stageItem
1375
1435
  ) {
1376
- const colourKey = column.stageConfig.stageColour.key;
1377
- const colourOptions = column.stageConfig.stageColour.options;
1436
+ const colourKey =
1437
+ column.stageConfig.stageColour.key;
1438
+ const colourOptions =
1439
+ column.stageConfig.stageColour.options;
1378
1440
 
1379
1441
  // Get the value for the color key
1380
1442
  if (stageItem[colourKey] !== undefined) {
1381
1443
  const keyValue = stageItem[colourKey];
1382
1444
 
1383
1445
  // Find matching option
1384
- const matchingOption = colourOptions.find((option) => {
1385
- // Handle both direct value and object with id
1386
- if (
1387
- typeof keyValue === 'object' &&
1388
- keyValue !== null
1389
- ) {
1446
+ const matchingOption = colourOptions.find(
1447
+ (option) => {
1448
+ // Handle both direct value and object with id
1449
+ if (
1450
+ typeof keyValue === 'object' &&
1451
+ keyValue !== null
1452
+ ) {
1453
+ // Use loose equality (==) to handle type coercion between string and number
1454
+ return keyValue.id == option.id;
1455
+ }
1390
1456
  // Use loose equality (==) to handle type coercion between string and number
1391
- return keyValue.id == option.id;
1457
+ return keyValue == option.id;
1392
1458
  }
1393
- // Use loose equality (==) to handle type coercion between string and number
1394
- return keyValue == option.id;
1395
- });
1459
+ );
1396
1460
 
1397
1461
  // Use the color from the matching option if found
1398
- if (
1399
- matchingOption &&
1400
- matchingOption.colour
1401
- ) {
1462
+ if (matchingOption && matchingOption.colour) {
1402
1463
  backgroundColor = matchingOption.colour;
1403
1464
  }
1404
1465
  }