@visns-studio/visns-components 5.11.20 → 5.11.22

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 (159) hide show
  1. package/package.json +5 -5
  2. package/src/components/{crm/Autocomplete.jsx → Autocomplete.jsx} +1 -1
  3. package/src/components/{crm/BusinessCardOcr.jsx → BusinessCardOcr.jsx} +1 -1
  4. package/src/components/{crm/DataGrid.jsx → DataGrid.jsx} +27 -4
  5. package/src/components/{crm/Download.jsx → Download.jsx} +1 -1
  6. package/src/components/{cms/DropZone.jsx → DropZone.jsx} +1 -1
  7. package/src/components/{crm/Field.jsx → Field.jsx} +2 -2
  8. package/src/components/{crm/Form.jsx → Form.jsx} +1 -1
  9. package/src/components/{crm/auth → auth}/ClientLogin.jsx +2 -2
  10. package/src/components/{crm/auth → auth}/ClientOTPVerify.jsx +2 -2
  11. package/src/components/{crm/auth → auth}/Login.jsx +2 -2
  12. package/src/components/{crm/auth → auth}/Profile.jsx +3 -3
  13. package/src/components/{crm/auth → auth}/Reset.jsx +2 -2
  14. package/src/components/{crm/auth → auth}/TwoFactorAuth.jsx +2 -2
  15. package/src/components/{crm/auth → auth}/Verify.jsx +2 -2
  16. package/src/components/{crm/client → client}/ClientDashboard.jsx +1 -1
  17. package/src/components/{crm/client → client}/ClientPortal.jsx +1 -1
  18. package/src/components/{crm/columns → columns}/ColumnRenderers.jsx +171 -3
  19. package/src/components/{crm/generic → generic}/ActionButtons.jsx +1 -1
  20. package/src/components/{crm/generic → generic}/AlternativeActionModal.jsx +2 -2
  21. package/src/components/{crm/generic → generic}/AuditLog.jsx +1 -1
  22. package/src/components/{crm/generic → generic}/AuditLogs.jsx +1 -1
  23. package/src/components/{cms/generic → generic}/CmsDetail.jsx +2 -2
  24. package/src/components/{cms/generic → generic}/CmsSort.jsx +1 -1
  25. package/src/components/{crm/generic → generic}/ConfirmationDialog.jsx +1 -1
  26. package/src/components/{crm/generic → generic}/ContactSelectorModal.jsx +2 -2
  27. package/src/components/{crm/generic → generic}/DatePickerDialog.jsx +2 -2
  28. package/src/components/{crm/generic → generic}/DateRangeSelectorModal.jsx +2 -2
  29. package/src/components/{crm/generic → generic}/GenericClientPortal.jsx +1 -1
  30. package/src/components/{crm/generic → generic}/GenericDashboard.jsx +4 -4
  31. package/src/components/{crm/generic → generic}/GenericDetail.jsx +5 -5
  32. package/src/components/{crm/generic → generic}/GenericDynamic.jsx +1 -1
  33. package/src/components/{crm/generic → generic}/GenericEditableTable.jsx +1 -1
  34. package/src/components/{crm/generic → generic}/GenericFormBuilder.jsx +2 -2
  35. package/src/components/{crm/generic → generic}/GenericGrid.jsx +2 -2
  36. package/src/components/{crm/generic → generic}/GenericIndex.jsx +2 -2
  37. package/src/components/{crm/generic → generic}/GenericMain.jsx +2 -2
  38. package/src/components/{crm/generic → generic}/GenericQuote.jsx +4 -4
  39. package/src/components/{crm/generic → generic}/GenericReport.jsx +2 -2
  40. package/src/components/{crm/generic → generic}/GenericReportForm.jsx +1 -1
  41. package/src/components/{crm/generic → generic}/GenericSort.jsx +2 -2
  42. package/src/components/{crm/generic → generic}/NotificationList.jsx +1 -1
  43. package/src/components/{crm/generic → generic}/ReasonCollectorModal.jsx +2 -2
  44. package/src/components/{crm/generic → generic}/SortableQuoteItems.jsx +1 -1
  45. package/src/components/proposal/SectionEditor.jsx +1 -1
  46. package/src/components/{crm/sorting → sorting}/Item.jsx +1 -1
  47. package/src/components/{crm/sorting → sorting}/List.jsx +1 -1
  48. package/src/index.js +57 -59
  49. package/src/components/cms/DataGrid.jsx +0 -1652
  50. package/src/components/cms/Field.jsx +0 -802
  51. package/src/components/cms/Form.jsx +0 -475
  52. package/src/components/cms/sorting/Item.jsx +0 -121
  53. package/src/components/cms/sorting/List.jsx +0 -32
  54. package/src/components/cms/sorting/styles/Item.module.scss +0 -38
  55. package/src/components/crm/sorting/styles/List.module.scss +0 -74
  56. /package/src/components/{crm/AssociationManager.jsx → AssociationManager.jsx} +0 -0
  57. /package/src/components/{crm/AsyncSelect.jsx → AsyncSelect.jsx} +0 -0
  58. /package/src/components/{crm/Breadcrumb.jsx → Breadcrumb.jsx} +0 -0
  59. /package/src/components/{crm/Call.jsx → Call.jsx} +0 -0
  60. /package/src/components/{crm/ClientAssociationManager.jsx → ClientAssociationManager.jsx} +0 -0
  61. /package/src/components/{crm/Fetch.jsx → Fetch.jsx} +0 -0
  62. /package/src/components/{cms/Gallery.jsx → Gallery.jsx} +0 -0
  63. /package/src/components/{crm/Loader.jsx → Loader.jsx} +0 -0
  64. /package/src/components/{crm/MergeEntity.jsx → MergeEntity.jsx} +0 -0
  65. /package/src/components/{crm/MultiSelect.jsx → MultiSelect.jsx} +0 -0
  66. /package/src/components/{crm/Navigation.jsx → Navigation.jsx} +0 -0
  67. /package/src/components/{crm/Notification.jsx → Notification.jsx} +0 -0
  68. /package/src/components/{crm/QrCode.jsx → QrCode.jsx} +0 -0
  69. /package/src/components/{crm/QuickAction.jsx → QuickAction.jsx} +0 -0
  70. /package/src/components/{crm/SectionHeader.jsx → SectionHeader.jsx} +0 -0
  71. /package/src/components/{crm/Select.jsx → Select.jsx} +0 -0
  72. /package/src/components/{crm/SelectList.jsx → SelectList.jsx} +0 -0
  73. /package/src/components/{crm/SwitchAccount.jsx → SwitchAccount.jsx} +0 -0
  74. /package/src/components/{crm/TableFilter.jsx → TableFilter.jsx} +0 -0
  75. /package/src/components/{crm/cells → cells}/CellWithTooltip.jsx +0 -0
  76. /package/src/components/{crm/controls → controls}/AudioPlayer.jsx +0 -0
  77. /package/src/components/{crm/controls → controls}/AutoRefreshControls.jsx +0 -0
  78. /package/src/components/{crm/controls → controls}/DataGridSearch.jsx +0 -0
  79. /package/src/components/{crm/examples → examples}/FilterExample.jsx +0 -0
  80. /package/src/components/{crm/examples → examples}/FormStylingGuide.md +0 -0
  81. /package/src/components/{crm/examples → examples}/FormWithSectionHeaders.jsx +0 -0
  82. /package/src/components/{crm/examples → examples}/README.md +0 -0
  83. /package/src/components/{cms/generic → generic}/CmsIndex.jsx +0 -0
  84. /package/src/components/{crm/generic → generic}/GenericAuth.jsx +0 -0
  85. /package/src/components/{crm/generic → generic}/shared/formatters.js +0 -0
  86. /package/src/components/{crm/generic → generic}/shared/gridUtils.js +0 -0
  87. /package/src/components/{crm/generic → generic}/utils/formatters.js +0 -0
  88. /package/src/components/{crm/modals → modals}/GalleryModal.jsx +0 -0
  89. /package/src/components/{crm/sketch → sketch}/SketchField.jsx +0 -0
  90. /package/src/components/{crm/sketch → sketch}/arrow.jsx +0 -0
  91. /package/src/components/{crm/sketch → sketch}/circle.jsx +0 -0
  92. /package/src/components/{crm/sketch → sketch}/default-tool.jsx +0 -0
  93. /package/src/components/{crm/sketch → sketch}/fabrictool.jsx +0 -0
  94. /package/src/components/{crm/sketch → sketch}/history.jsx +0 -0
  95. /package/src/components/{crm/sketch → sketch}/json/config.json +0 -0
  96. /package/src/components/{crm/sketch → sketch}/line.jsx +0 -0
  97. /package/src/components/{crm/sketch → sketch}/pan.jsx +0 -0
  98. /package/src/components/{crm/sketch → sketch}/pencil.jsx +0 -0
  99. /package/src/components/{crm/sketch → sketch}/rectangle-label-object.jsx +0 -0
  100. /package/src/components/{crm/sketch → sketch}/rectangle-label.jsx +0 -0
  101. /package/src/components/{crm/sketch → sketch}/rectangle.jsx +0 -0
  102. /package/src/components/{crm/sketch → sketch}/select.jsx +0 -0
  103. /package/src/components/{crm/sketch → sketch}/tools.jsx +0 -0
  104. /package/src/components/{crm/sketch → sketch}/utils.jsx +0 -0
  105. /package/src/components/{crm/generic/styles → styles}/ActionButtons.module.scss +0 -0
  106. /package/src/components/{crm/generic/styles → styles}/AlternativeActionModal.css +0 -0
  107. /package/src/components/{crm/styles → styles}/AssociationManager.module.scss +0 -0
  108. /package/src/components/{crm/styles → styles}/AsyncSelect.module.scss +0 -0
  109. /package/src/components/{crm/generic/styles → styles}/AuditLog.module.scss +0 -0
  110. /package/src/components/{crm/generic/styles → styles}/AuditLogs.module.scss +0 -0
  111. /package/src/components/{crm/auth/styles → styles}/AuthForm.module.scss +0 -0
  112. /package/src/components/{crm/styles → styles}/Autocomplete.module.scss +0 -0
  113. /package/src/components/{crm/styles → styles}/BusinessCardOcr.module.scss +0 -0
  114. /package/src/components/{crm/styles → styles}/ClientAssociationManager.module.scss +0 -0
  115. /package/src/components/{crm/auth/styles → styles}/ClientAuth.module.scss +0 -0
  116. /package/src/components/{crm/client/styles → styles}/ClientDashboard.module.scss +0 -0
  117. /package/src/components/{crm/client/styles → styles}/ClientPortal.module.scss +0 -0
  118. /package/src/components/{crm/generic/styles → styles}/ContactSelectorModal.css +0 -0
  119. /package/src/components/{crm/styles → styles}/DataGrid.module.scss +0 -0
  120. /package/src/components/{crm/generic/styles → styles}/DatePickerDialog.css +0 -0
  121. /package/src/components/{crm/generic/styles → styles}/DateRangeSelectorModal.css +0 -0
  122. /package/src/components/{cms/styles → styles}/DropZone.module.css +0 -0
  123. /package/src/components/{crm/styles → styles}/Field.module.scss +0 -0
  124. /package/src/components/{crm/styles → styles}/Form.module.scss +0 -0
  125. /package/src/components/{cms/styles → styles}/Gallery.module.css +0 -0
  126. /package/src/components/{crm/generic/styles → styles}/GenericClientPortal.module.scss +0 -0
  127. /package/src/components/{crm/generic/styles → styles}/GenericDashboard.module.scss +0 -0
  128. /package/src/components/{crm/generic/styles → styles}/GenericDetail.module.scss +0 -0
  129. /package/src/components/{crm/generic/styles → styles}/GenericDynamic.module.scss +0 -0
  130. /package/src/components/{crm/generic/styles → styles}/GenericEditableTable.module.scss +0 -0
  131. /package/src/components/{crm/generic/styles → styles}/GenericFormBuilder.module.scss +0 -0
  132. /package/src/components/{crm/generic/styles → styles}/GenericIndex.module.scss +0 -0
  133. /package/src/components/{crm/generic/styles → styles}/GenericMain.module.scss +0 -0
  134. /package/src/components/{crm/generic/styles → styles}/GenericQuote.module.scss +0 -0
  135. /package/src/components/{crm/generic/styles → styles}/GenericReport.module.scss +0 -0
  136. /package/src/components/{crm/generic/styles → styles}/GenericSort.module.scss +0 -0
  137. /package/src/components/{crm/sorting/styles → styles}/Item.module.scss +0 -0
  138. /package/src/components/{cms/sorting/styles → styles}/List.module.scss +0 -0
  139. /package/src/components/{crm/styles → styles}/Loader.module.scss +0 -0
  140. /package/src/components/{crm/auth/styles → styles}/Login.module.scss +0 -0
  141. /package/src/components/{crm/styles → styles}/MergeEntity.module.scss +0 -0
  142. /package/src/components/{crm/styles → styles}/MultiSelect.module.scss +0 -0
  143. /package/src/components/{crm/styles → styles}/Navigation.module.scss +0 -0
  144. /package/src/components/{crm/styles → styles}/Notification.module.scss +0 -0
  145. /package/src/components/{crm/generic/styles → styles}/NotificationList.module.scss +0 -0
  146. /package/src/components/{crm/auth/styles → styles}/Profile.module.scss +0 -0
  147. /package/src/components/{crm/styles → styles}/QrCode.module.scss +0 -0
  148. /package/src/components/{crm/styles → styles}/QuickAction.module.scss +0 -0
  149. /package/src/components/{crm/generic/styles → styles}/ReasonCollectorModal.css +0 -0
  150. /package/src/components/{crm/generic/styles → styles}/ReportForm.module.scss +0 -0
  151. /package/src/components/{crm/auth/styles → styles}/Reset.module.scss +0 -0
  152. /package/src/components/{crm/generic/styles → styles}/SortableQuoteItems.module.scss +0 -0
  153. /package/src/components/{crm/generic/styles → styles}/SweetAlert.module.css +0 -0
  154. /package/src/components/{crm/styles → styles}/SwitchAccount.module.scss +0 -0
  155. /package/src/components/{crm/styles → styles}/TableFilter.module.scss +0 -0
  156. /package/src/components/{crm/auth/styles → styles}/TwoFactorAuth.module.scss +0 -0
  157. /package/src/components/{crm/auth/styles → styles}/Verify.module.scss +0 -0
  158. /package/src/components/{crm/styles → styles}/global-datagrid.css +0 -0
  159. /package/src/utils/{ConfirmDialog.js → ConfirmDialog.jsx} +0 -0
package/package.json CHANGED
@@ -14,8 +14,8 @@
14
14
  "@tinymce/miniature": "^6.0.0",
15
15
  "@tinymce/tinymce-react": "^6.2.1",
16
16
  "@uiw/react-color": "^2.6.0",
17
- "@visns-studio/visns-datagrid-community": "^1.0.14",
18
- "@visns-studio/visns-datagrid-enterprise": "^1.0.14",
17
+ "@visns-studio/visns-datagrid-community": "^1.0.23",
18
+ "@visns-studio/visns-datagrid-enterprise": "^1.0.23",
19
19
  "@vitejs/plugin-react": "^4.6.0",
20
20
  "add": "^2.0.6",
21
21
  "array-move": "^4.0.0",
@@ -24,13 +24,13 @@
24
24
  "dayjs": "^1.11.13",
25
25
  "fabric": "^6.7.0",
26
26
  "file-saver": "^2.0.5",
27
- "framer-motion": "^12.19.1",
27
+ "framer-motion": "^12.19.2",
28
28
  "html-react-parser": "^5.2.5",
29
29
  "lodash": "^4.17.21",
30
30
  "lodash.debounce": "^4.0.8",
31
31
  "lucide-react": "^0.518.0",
32
32
  "moment": "^2.30.1",
33
- "motion": "^12.19.1",
33
+ "motion": "^12.19.2",
34
34
  "numeral": "^2.0.6",
35
35
  "pluralize": "^8.0.0",
36
36
  "qrcode.react": "^4.2.0",
@@ -87,7 +87,7 @@
87
87
  "react-dom": "^17.0.0 || ^18.0.0"
88
88
  },
89
89
  "name": "@visns-studio/visns-components",
90
- "version": "5.11.20",
90
+ "version": "5.11.22",
91
91
  "description": "Various packages to assist in the development of our Custom Applications.",
92
92
  "main": "src/index.js",
93
93
  "files": [
@@ -2,7 +2,7 @@ import { useState, useEffect, useCallback, useMemo, memo, useRef } from 'react';
2
2
  import AwesomeDebouncePromise from 'awesome-debounce-promise';
3
3
  import { ToggleLeft, ToggleRight, Search } from 'lucide-react';
4
4
  import styles from './styles/Autocomplete.module.scss';
5
- import fetchUtil from '../../utils/fetchUtil';
5
+ import fetchUtil from '../utils/fetchUtil';
6
6
 
7
7
  // Create the debounced function outside the component to prevent recreation
8
8
  const createDebouncedSearch = (fn) =>
@@ -1,4 +1,4 @@
1
- import '../styles/global.css';
1
+ import './styles/global.css';
2
2
 
3
3
  import { useState, useRef, useCallback, useEffect } from 'react';
4
4
  import { motion } from 'framer-motion';
@@ -1,4 +1,4 @@
1
- import '../styles/global.css';
1
+ import './styles/global.css';
2
2
  import './styles/global-datagrid.css';
3
3
 
4
4
  /**
@@ -39,10 +39,10 @@ import SelectFilter from '@visns-studio/visns-datagrid-enterprise/SelectFilter';
39
39
  import DateFilter from '@visns-studio/visns-datagrid-enterprise/DateFilter';
40
40
  import ReactDataGrid from '@visns-studio/visns-datagrid-enterprise';
41
41
  import { toast } from 'react-toastify';
42
- import fetchUtil from '../../utils/fetchUtil';
42
+ import fetchUtil from '../utils/fetchUtil';
43
43
  import { confirmDialog } from '../utils/ConfirmDialog';
44
- import { DEFAULT_INTELLIGENT_SORTING_CONFIG } from '../../utils/relationshipSortingUtils';
45
- import { extractColumnsMetadata, isColumnSortable } from '../../utils/columnsMetadataUtils';
44
+ import { DEFAULT_INTELLIGENT_SORTING_CONFIG } from '../utils/relationshipSortingUtils';
45
+ import { extractColumnsMetadata, isColumnSortable } from '../utils/columnsMetadataUtils';
46
46
  import {
47
47
  AlarmClock,
48
48
  RotateCcw,
@@ -110,6 +110,7 @@ import {
110
110
  renderCreatedByColumn,
111
111
  renderDateRangeColumn,
112
112
  renderStageCounterColumn,
113
+ renderGalleryColumn,
113
114
  } from './columns/ColumnRenderers.jsx';
114
115
  import _ from 'lodash';
115
116
 
@@ -2448,7 +2449,21 @@ const DataGrid = forwardRef(
2448
2449
  ? column.filter.placeholder
2449
2450
  : 'All Options',
2450
2451
  dataSource: selectedDataSource,
2452
+ searchable: column.filter.searchable !== false,
2453
+ // Enable clear functionality even when searchable is false
2454
+ allowClearWhenNotSearchable: column.filter.searchable === false,
2455
+ // Explicitly enable clear icon
2456
+ clearIcon: true,
2451
2457
  };
2458
+
2459
+ // Debug: Check if fix is applied
2460
+ if (column.filter.searchable === false) {
2461
+ console.log('Filter Debug - searchable=false:', {
2462
+ columnName: column.name || 'unknown',
2463
+ props: filterEditorProps,
2464
+ visnsDataGridVersion: 'v1.0.18'
2465
+ });
2466
+ }
2452
2467
  break;
2453
2468
  default:
2454
2469
  filterEditor = null;
@@ -2549,6 +2564,14 @@ const DataGrid = forwardRef(
2549
2564
  column,
2550
2565
  commonProps,
2551
2566
  });
2567
+ case 'gallery':
2568
+ return renderGalleryColumn({
2569
+ column,
2570
+ commonProps,
2571
+ modalGalleryOpen,
2572
+ setGalleryData,
2573
+ setCurrentItem,
2574
+ });
2552
2575
  case 'image':
2553
2576
  return renderImageColumn({
2554
2577
  column,
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { trackPromise } from 'react-promise-tracker';
3
3
  import { toast } from 'react-toastify';
4
4
  import parse from 'html-react-parser';
5
- import fetchUtil from '../../utils/fetchUtil';
5
+ import fetchUtil from '../utils/fetchUtil';
6
6
 
7
7
  const CustomDownload = (
8
8
  url,
@@ -8,7 +8,7 @@ import Popup from 'reactjs-popup';
8
8
  import imageCompression from 'browser-image-compression';
9
9
 
10
10
  import { confirmDialog } from '../utils/ConfirmDialog';
11
- import CustomFetch from '../crm/Fetch';
11
+ import CustomFetch from './Fetch';
12
12
  import Gallery from './Gallery';
13
13
  import styles from './styles/DropZone.module.css';
14
14
 
@@ -1,4 +1,4 @@
1
- import '../styles/global.css';
1
+ import './styles/global.css';
2
2
 
3
3
  import React, { useEffect, useRef, useState, useMemo } from 'react';
4
4
  import DatePicker from 'react-datepicker';
@@ -36,7 +36,7 @@ import SketchField from './sketch/SketchField';
36
36
  import Tools from './sketch/tools';
37
37
  import VisnsAsyncSelect from './AsyncSelect';
38
38
  import VisnsAutocomplete from './Autocomplete';
39
- import VisnsDropZone from '../cms/DropZone';
39
+ import VisnsDropZone from './DropZone';
40
40
 
41
41
  import 'react-toggle/style.css';
42
42
  import 'react-datepicker/dist/react-datepicker.css';
@@ -1,4 +1,4 @@
1
- import '../styles/global.css';
1
+ import './styles/global.css';
2
2
 
3
3
  import React, { useState, useEffect, useRef, useCallback } from 'react';
4
4
  import { useNavigate } from 'react-router-dom';
@@ -1,4 +1,4 @@
1
- import '../../styles/global.css';
1
+ import '../styles/global.css';
2
2
 
3
3
  import React, { useState } from 'react';
4
4
  import { useLocation, useNavigate } from 'react-router-dom';
@@ -7,7 +7,7 @@ import { User } from 'lucide-react';
7
7
 
8
8
  import CustomFetch from '../Fetch';
9
9
 
10
- import styles from './styles/ClientAuth.module.scss';
10
+ import styles from '../styles/ClientAuth.module.scss';
11
11
 
12
12
  const ClientLogin = ({ logo, setSystemAuth, urls = {} }) => {
13
13
  const location = useLocation();
@@ -1,4 +1,4 @@
1
- import '../../styles/global.css';
1
+ import '../styles/global.css';
2
2
 
3
3
  import React, { useState, useEffect } from 'react';
4
4
  import { useNavigate, useLocation } from 'react-router-dom';
@@ -7,7 +7,7 @@ import { Lock, ArrowLeft } from 'lucide-react';
7
7
 
8
8
  import CustomFetch from '../Fetch';
9
9
 
10
- import styles from './styles/ClientAuth.module.scss';
10
+ import styles from '../styles/ClientAuth.module.scss';
11
11
 
12
12
  const ClientOTPVerify = ({
13
13
  logo,
@@ -1,4 +1,4 @@
1
- import '../../styles/global.css';
1
+ import '../styles/global.css';
2
2
 
3
3
  import React, { useState } from 'react';
4
4
  import { Link, useLocation, useNavigate } from 'react-router-dom';
@@ -8,7 +8,7 @@ import { User, Lock } from 'lucide-react';
8
8
 
9
9
  import CustomFetch from '../Fetch';
10
10
 
11
- import styles from './styles/Login.module.scss';
11
+ import styles from '../styles/Login.module.scss';
12
12
 
13
13
  const Login = ({ logo, providers, setSystemAuth, setUserProfile }) => {
14
14
  const location = useLocation();
@@ -1,5 +1,5 @@
1
- // src/components/crm/auth/Profile.jsx
2
- import '../../styles/global.css';
1
+ // src/components/auth/Profile.jsx
2
+ import '../styles/global.css';
3
3
 
4
4
  import React, { useState, useEffect, useRef, useCallback, memo } from 'react';
5
5
  import { useLocation } from 'react-router-dom';
@@ -9,7 +9,7 @@ import SignaturePad from 'react-signature-pad-wrapper';
9
9
  import Swal from 'sweetalert2';
10
10
  import CustomFetch from '../Fetch';
11
11
  import TableFilter from '../TableFilter';
12
- import styles from './styles/Profile.module.scss';
12
+ import styles from '../styles/Profile.module.scss';
13
13
 
14
14
  // Form field component to reduce repetition
15
15
  const FormField = memo(
@@ -1,4 +1,4 @@
1
- import '../../styles/global.css';
1
+ import '../styles/global.css';
2
2
 
3
3
  import React, { useState } from 'react';
4
4
  import Reveal from 'react-reveal/Reveal';
@@ -8,7 +8,7 @@ import { User } from 'lucide-react';
8
8
 
9
9
  import CustomFetch from '../Fetch';
10
10
 
11
- import styles from './styles/Reset.module.scss';
11
+ import styles from '../styles/Reset.module.scss';
12
12
 
13
13
  const Reset = ({ logo }) => {
14
14
  const [email, setEmail] = useState('');
@@ -1,4 +1,4 @@
1
- import '../../styles/global.css';
1
+ import '../styles/global.css';
2
2
 
3
3
  import React, { useState, useEffect } from 'react';
4
4
  import { useNavigate, useLocation } from 'react-router-dom';
@@ -8,7 +8,7 @@ import { Lock } from 'lucide-react';
8
8
 
9
9
  import CustomFetch from '../Fetch';
10
10
 
11
- import styles from './styles/TwoFactorAuth.module.scss';
11
+ import styles from '../styles/TwoFactorAuth.module.scss';
12
12
 
13
13
  const TwoFactorAuth = ({ logo, setSystemAuth, setUserProfile }) => {
14
14
  const navigate = useNavigate();
@@ -1,4 +1,4 @@
1
- import '../../styles/global.css';
1
+ import '../styles/global.css';
2
2
 
3
3
  import React, { useState } from 'react';
4
4
  import { useNavigate, useParams } from 'react-router-dom';
@@ -9,7 +9,7 @@ import Reveal from 'react-reveal/Reveal';
9
9
 
10
10
  import CustomFetch from '../Fetch';
11
11
 
12
- import styles from './styles/Verify.module.scss';
12
+ import styles from '../styles/Verify.module.scss';
13
13
 
14
14
  const Verify = ({ logo }) => {
15
15
  const navigate = useNavigate();
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- import styles from './styles/ClientDashboard.module.scss';
3
+ import styles from '../styles/ClientDashboard.module.scss';
4
4
 
5
5
  /**
6
6
  * ClientDashboard - Example dashboard component for client portal
@@ -4,7 +4,7 @@ import { toast } from 'react-toastify';
4
4
 
5
5
  import CustomFetch from '../Fetch';
6
6
 
7
- import styles from './styles/ClientPortal.module.scss';
7
+ import styles from '../styles/ClientPortal.module.scss';
8
8
 
9
9
  const ClientPortal = ({
10
10
  clientProfile,
@@ -8,7 +8,7 @@ import {
8
8
  isRelationshipColumnSortable,
9
9
  getRelationshipPath,
10
10
  DEFAULT_INTELLIGENT_SORTING_CONFIG,
11
- } from '../../../utils/relationshipSortingUtils';
11
+ } from '../../utils/relationshipSortingUtils';
12
12
 
13
13
  // Boolean Column Renderer
14
14
  export const renderBooleanColumn = ({
@@ -135,11 +135,11 @@ export const renderDateTimeColumn = ({
135
135
  moment(data[column.id]).format('YYYY-MM-DD') !== '1970-01-01'
136
136
  ) {
137
137
  let dateValue = moment(data[column.id]);
138
-
138
+
139
139
  // Apply modifier if present
140
140
  if (column.modifier) {
141
141
  const { operator, value, unit } = column.modifier;
142
-
142
+
143
143
  if (operator === '+') {
144
144
  dateValue = dateValue.add(value, unit);
145
145
  } else if (operator === '-') {
@@ -1424,6 +1424,174 @@ export const renderDateRangeColumn = ({
1424
1424
  };
1425
1425
 
1426
1426
  // Stage Counter Column Renderer
1427
+ // Gallery Column Renderer
1428
+ export const renderGalleryColumn = ({
1429
+ column,
1430
+ commonProps,
1431
+ modalGalleryOpen,
1432
+ setGalleryData,
1433
+ setCurrentItem,
1434
+ }) => {
1435
+ return {
1436
+ ...commonProps,
1437
+ name: column.id,
1438
+ sortable: false,
1439
+ render: ({ data }) => {
1440
+ // Function to access nested property using a series of keys
1441
+ const getNestedValue = (data, keys) =>
1442
+ keys.reduce(
1443
+ (currentValue, key) =>
1444
+ currentValue && currentValue[key] !== undefined
1445
+ ? currentValue[key]
1446
+ : undefined,
1447
+ data
1448
+ );
1449
+
1450
+ // Get the images array from the nested structure
1451
+ const imagesArray = column.relation
1452
+ ? getNestedValue(data, column.relation)
1453
+ : data[column.id];
1454
+
1455
+ // Check if we have valid image data
1456
+ if (
1457
+ !imagesArray ||
1458
+ !Array.isArray(imagesArray) ||
1459
+ imagesArray.length === 0
1460
+ ) {
1461
+ return (
1462
+ <div
1463
+ style={{
1464
+ display: 'flex',
1465
+ alignItems: 'center',
1466
+ justifyContent: 'center',
1467
+ height: '40px',
1468
+ color: '#999',
1469
+ fontSize: '12px',
1470
+ }}
1471
+ >
1472
+ No images
1473
+ </div>
1474
+ );
1475
+ }
1476
+
1477
+ const maxThumbnails = column.maxThumbnails || 3;
1478
+ const displayImages = imagesArray.slice(0, maxThumbnails);
1479
+ const remainingCount = imagesArray.length - maxThumbnails;
1480
+
1481
+ const handleGalleryClick = (e) => {
1482
+ e.stopPropagation();
1483
+ e.preventDefault();
1484
+
1485
+ // Prepare gallery data in the format expected by the modal
1486
+ const galleryData = imagesArray.map((item) => ({
1487
+ src: item[column.key],
1488
+ caption: item[column.captionKey || 'file_name'],
1489
+ width: 320,
1490
+ height: 240,
1491
+ }));
1492
+
1493
+ // Set gallery data and current item
1494
+ setGalleryData(galleryData);
1495
+ setCurrentItem({
1496
+ data: data,
1497
+ settings: {
1498
+ relation: column.relation,
1499
+ key: column.key,
1500
+ captionKey: column.captionKey || 'file_name',
1501
+ },
1502
+ });
1503
+
1504
+ // Open the gallery modal
1505
+ modalGalleryOpen();
1506
+ };
1507
+
1508
+ return (
1509
+ <div
1510
+ onClick={handleGalleryClick}
1511
+ style={{
1512
+ display: 'flex',
1513
+ flexDirection: 'column',
1514
+ alignItems: 'flex-start',
1515
+ gap: '6px',
1516
+ cursor: 'pointer',
1517
+ padding: '6px',
1518
+ borderRadius: '4px',
1519
+ transition: 'background-color 0.2s',
1520
+ width: '100%',
1521
+ height: '100%',
1522
+ minHeight: '60px',
1523
+ }}
1524
+ onMouseEnter={(e) => {
1525
+ e.target.style.backgroundColor = '#f0f0f0';
1526
+ }}
1527
+ onMouseLeave={(e) => {
1528
+ e.target.style.backgroundColor = 'transparent';
1529
+ }}
1530
+ >
1531
+ {/* Thumbnail images */}
1532
+ <div
1533
+ style={{
1534
+ display: 'flex',
1535
+ gap: '4px',
1536
+ flexWrap: 'wrap',
1537
+ }}
1538
+ >
1539
+ {displayImages.map((image, index) => {
1540
+ const imageUrl = image[column.key];
1541
+ if (!imageUrl) return null;
1542
+
1543
+ return (
1544
+ <div
1545
+ key={index}
1546
+ style={{
1547
+ width: '28px',
1548
+ height: '28px',
1549
+ borderRadius: '3px',
1550
+ overflow: 'hidden',
1551
+ border: '1px solid #ddd',
1552
+ flexShrink: 0,
1553
+ }}
1554
+ >
1555
+ <img
1556
+ src={imageUrl}
1557
+ alt={
1558
+ image[
1559
+ column.captionKey || 'file_name'
1560
+ ] || `Image ${index + 1}`
1561
+ }
1562
+ style={{
1563
+ width: '100%',
1564
+ height: '100%',
1565
+ objectFit: 'cover',
1566
+ }}
1567
+ onError={(e) => {
1568
+ e.target.style.display = 'none';
1569
+ }}
1570
+ />
1571
+ </div>
1572
+ );
1573
+ })}
1574
+ </div>
1575
+
1576
+ {/* Count badge */}
1577
+ <div
1578
+ style={{
1579
+ fontSize: '11px',
1580
+ color: '#666',
1581
+ fontWeight: '500',
1582
+ lineHeight: '1.2',
1583
+ }}
1584
+ >
1585
+ {imagesArray.length}{' '}
1586
+ {imagesArray.length === 1 ? 'image' : 'images'}
1587
+ {remainingCount > 0 && ` (+${remainingCount})`}
1588
+ </div>
1589
+ </div>
1590
+ );
1591
+ },
1592
+ };
1593
+ };
1594
+
1427
1595
  export const renderStageCounterColumn = ({ column, commonProps, navigate }) => {
1428
1596
  return {
1429
1597
  ...commonProps,
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import styles from './styles/ActionButtons.module.scss';
2
+ import styles from '../styles/ActionButtons.module.scss';
3
3
 
4
4
  function ActionButtons({ actions, onActionClick }) {
5
5
  return (
@@ -1,6 +1,6 @@
1
1
  import Swal from 'sweetalert2';
2
- import './styles/SweetAlert.module.css';
3
- import './styles/AlternativeActionModal.css';
2
+ import '../styles/SweetAlert.module.css';
3
+ import '../styles/AlternativeActionModal.css';
4
4
 
5
5
  /**
6
6
  * Show an alternative action modal for choosing between different workflows
@@ -3,7 +3,7 @@ import { useParams } from 'react-router-dom';
3
3
  import dayjs from 'dayjs';
4
4
  import Breadcrumb from '../Breadcrumb';
5
5
  import CustomFetch from '../Fetch';
6
- import styles from './styles/AuditLog.module.scss';
6
+ import styles from '../styles/AuditLog.module.scss';
7
7
 
8
8
  const AuditLog = ({ userProfile }) => {
9
9
  const routeParams = useParams();
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import Table from '../DataGrid';
3
- import styles from './styles/AuditLogs.module.scss';
3
+ import styles from '../styles/AuditLogs.module.scss';
4
4
 
5
5
  const AuditLogs = ({ layout }) => {
6
6
  const setting = {
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { useParams, useNavigate, useLocation } from 'react-router-dom';
3
3
  import Reveal from 'react-reveal/Reveal';
4
4
  import { ToastContainer } from 'react-toastify';
5
- import CmsForm from '../Form';
5
+ import Form from '../Form';
6
6
 
7
7
  function CmsDetail({ setting }) {
8
8
  const { dataId } = useParams();
@@ -14,7 +14,7 @@ function CmsDetail({ setting }) {
14
14
  <div className="grid">
15
15
  <div className="grid__row">
16
16
  <div className="grid__full">
17
- <CmsForm
17
+ <Form
18
18
  dataId={dataId}
19
19
  navigate={navigate}
20
20
  form={form}
@@ -3,7 +3,7 @@ import { useLocation } from 'react-router-dom';
3
3
  import Reveal from 'react-reveal/Reveal';
4
4
  import { arrayMoveImmutable } from 'array-move';
5
5
  import { toast } from 'react-toastify';
6
- import CustomFetch from '../../crm/Fetch';
6
+ import CustomFetch from '../Fetch';
7
7
  import SortableList from '../sorting/List';
8
8
 
9
9
  const ChildSort = ({ item, url }) => {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import Swal from 'sweetalert2';
3
- import './styles/SweetAlert.module.css';
3
+ import '../styles/SweetAlert.module.css';
4
4
 
5
5
  /**
6
6
  * A utility function that uses SweetAlert2 for confirmation dialogs
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
  import Swal from 'sweetalert2';
3
- import './styles/SweetAlert.module.css';
4
- import './styles/ContactSelectorModal.css';
3
+ import '../styles/SweetAlert.module.css';
4
+ import '../styles/ContactSelectorModal.css';
5
5
  import CustomFetch from '../Fetch';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import Swal from 'sweetalert2';
3
- import './styles/SweetAlert.module.css';
4
- import './styles/DatePickerDialog.css';
3
+ import '../styles/SweetAlert.module.css';
4
+ import '../styles/DatePickerDialog.css';
5
5
  import moment from 'moment';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import Swal from 'sweetalert2';
2
2
  import moment from 'moment';
3
- import './styles/SweetAlert.module.css';
4
- import './styles/DateRangeSelectorModal.css';
3
+ import '../styles/SweetAlert.module.css';
4
+ import '../styles/DateRangeSelectorModal.css';
5
5
 
6
6
  /**
7
7
  * Show a date range selector modal for selecting start and end dates
@@ -5,7 +5,7 @@ import { LogOut as SignOut } from 'lucide-react';
5
5
 
6
6
  import CustomFetch from '../Fetch';
7
7
 
8
- import styles from './styles/GenericClientPortal.module.scss';
8
+ import styles from '../styles/GenericClientPortal.module.scss';
9
9
 
10
10
  /**
11
11
  * GenericClientPortal - A wrapper component for client portal content
@@ -1,4 +1,4 @@
1
- import '../../styles/global.css';
1
+ import '../styles/global.css';
2
2
  import React, { useState, useEffect, useRef } from 'react';
3
3
  import { Link, useNavigate } from 'react-router-dom';
4
4
  import { ResponsiveBar } from '@nivo/bar';
@@ -11,10 +11,10 @@ import { createSwapy } from 'swapy';
11
11
  import { X, Minus, Plus, Star, Trash2 } from 'lucide-react';
12
12
  import { confirmDialog } from '../../utils/ConfirmDialog';
13
13
 
14
- import CustomFetch from '../../crm/Fetch';
15
- import MultiSelect from '../../crm/MultiSelect';
14
+ import CustomFetch from '../Fetch';
15
+ import MultiSelect from '../MultiSelect';
16
16
 
17
- import styles from './styles/GenericDashboard.module.scss';
17
+ import styles from '../styles/GenericDashboard.module.scss';
18
18
 
19
19
  const toSnakeCase = (str) => str.replace(/[\s-]+/g, '_').toLowerCase();
20
20