@visns-studio/visns-components 5.11.21 → 5.12.0
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.
- package/package.json +5 -5
- package/src/components/{crm/Autocomplete.jsx → Autocomplete.jsx} +1 -1
- package/src/components/{crm/BusinessCardOcr.jsx → BusinessCardOcr.jsx} +1 -1
- package/src/components/{crm/DataGrid.jsx → DataGrid.jsx} +57 -9
- package/src/components/{crm/Download.jsx → Download.jsx} +1 -1
- package/src/components/{cms/DropZone.jsx → DropZone.jsx} +1 -1
- package/src/components/{crm/Field.jsx → Field.jsx} +2 -2
- package/src/components/{crm/Form.jsx → Form.jsx} +65 -30
- package/src/components/{crm/auth → auth}/ClientLogin.jsx +2 -2
- package/src/components/{crm/auth → auth}/ClientOTPVerify.jsx +2 -2
- package/src/components/{crm/auth → auth}/Login.jsx +2 -2
- package/src/components/{crm/auth → auth}/Profile.jsx +3 -3
- package/src/components/{crm/auth → auth}/Reset.jsx +2 -2
- package/src/components/{crm/auth → auth}/TwoFactorAuth.jsx +2 -2
- package/src/components/{crm/auth → auth}/Verify.jsx +2 -2
- package/src/components/{crm/client → client}/ClientDashboard.jsx +1 -1
- package/src/components/{crm/client → client}/ClientPortal.jsx +1 -1
- package/src/components/{crm/columns → columns}/ColumnRenderers.jsx +31 -20
- package/src/components/{crm/generic → generic}/ActionButtons.jsx +1 -1
- package/src/components/{crm/generic → generic}/AlternativeActionModal.jsx +2 -2
- package/src/components/{crm/generic → generic}/AuditLog.jsx +1 -1
- package/src/components/{crm/generic → generic}/AuditLogs.jsx +1 -1
- package/src/components/{cms/generic → generic}/CmsDetail.jsx +2 -2
- package/src/components/{cms/generic → generic}/CmsSort.jsx +1 -1
- package/src/components/{crm/generic → generic}/ConfirmationDialog.jsx +1 -1
- package/src/components/{crm/generic → generic}/ContactSelectorModal.jsx +2 -2
- package/src/components/{crm/generic → generic}/DatePickerDialog.jsx +2 -2
- package/src/components/{crm/generic → generic}/DateRangeSelectorModal.jsx +2 -2
- package/src/components/{crm/generic → generic}/GenericClientPortal.jsx +1 -1
- package/src/components/{crm/generic → generic}/GenericDashboard.jsx +4 -4
- package/src/components/{crm/generic → generic}/GenericDetail.jsx +5 -5
- package/src/components/{crm/generic → generic}/GenericDynamic.jsx +1 -1
- package/src/components/{crm/generic → generic}/GenericEditableTable.jsx +1 -1
- package/src/components/{crm/generic → generic}/GenericFormBuilder.jsx +2 -2
- package/src/components/{crm/generic → generic}/GenericGrid.jsx +2 -2
- package/src/components/{crm/generic → generic}/GenericIndex.jsx +2 -2
- package/src/components/{crm/generic → generic}/GenericMain.jsx +2 -2
- package/src/components/{crm/generic → generic}/GenericQuote.jsx +4 -4
- package/src/components/{crm/generic → generic}/GenericReport.jsx +2 -2
- package/src/components/{crm/generic → generic}/GenericReportForm.jsx +1 -1
- package/src/components/{crm/generic → generic}/GenericSort.jsx +2 -2
- package/src/components/{crm/generic → generic}/NotificationList.jsx +1 -1
- package/src/components/{crm/generic → generic}/ReasonCollectorModal.jsx +2 -2
- package/src/components/{crm/generic → generic}/SortableQuoteItems.jsx +1 -1
- package/src/components/proposal/SectionEditor.jsx +1 -1
- package/src/components/{crm/sorting → sorting}/Item.jsx +1 -1
- package/src/components/{crm/sorting → sorting}/List.jsx +1 -1
- package/src/index.js +57 -59
- package/src/utils/{ConfirmDialog.js → ConfirmDialog.jsx} +1 -1
- package/src/components/cms/DataGrid.jsx +0 -1652
- package/src/components/cms/Field.jsx +0 -802
- package/src/components/cms/Form.jsx +0 -475
- package/src/components/cms/sorting/Item.jsx +0 -121
- package/src/components/cms/sorting/List.jsx +0 -32
- package/src/components/cms/sorting/styles/Item.module.scss +0 -38
- package/src/components/crm/sorting/styles/List.module.scss +0 -74
- /package/src/components/{crm/AssociationManager.jsx → AssociationManager.jsx} +0 -0
- /package/src/components/{crm/AsyncSelect.jsx → AsyncSelect.jsx} +0 -0
- /package/src/components/{crm/Breadcrumb.jsx → Breadcrumb.jsx} +0 -0
- /package/src/components/{crm/Call.jsx → Call.jsx} +0 -0
- /package/src/components/{crm/ClientAssociationManager.jsx → ClientAssociationManager.jsx} +0 -0
- /package/src/components/{crm/Fetch.jsx → Fetch.jsx} +0 -0
- /package/src/components/{cms/Gallery.jsx → Gallery.jsx} +0 -0
- /package/src/components/{crm/Loader.jsx → Loader.jsx} +0 -0
- /package/src/components/{crm/MergeEntity.jsx → MergeEntity.jsx} +0 -0
- /package/src/components/{crm/MultiSelect.jsx → MultiSelect.jsx} +0 -0
- /package/src/components/{crm/Navigation.jsx → Navigation.jsx} +0 -0
- /package/src/components/{crm/Notification.jsx → Notification.jsx} +0 -0
- /package/src/components/{crm/QrCode.jsx → QrCode.jsx} +0 -0
- /package/src/components/{crm/QuickAction.jsx → QuickAction.jsx} +0 -0
- /package/src/components/{crm/SectionHeader.jsx → SectionHeader.jsx} +0 -0
- /package/src/components/{crm/Select.jsx → Select.jsx} +0 -0
- /package/src/components/{crm/SelectList.jsx → SelectList.jsx} +0 -0
- /package/src/components/{crm/SwitchAccount.jsx → SwitchAccount.jsx} +0 -0
- /package/src/components/{crm/TableFilter.jsx → TableFilter.jsx} +0 -0
- /package/src/components/{crm/cells → cells}/CellWithTooltip.jsx +0 -0
- /package/src/components/{crm/controls → controls}/AudioPlayer.jsx +0 -0
- /package/src/components/{crm/controls → controls}/AutoRefreshControls.jsx +0 -0
- /package/src/components/{crm/controls → controls}/DataGridSearch.jsx +0 -0
- /package/src/components/{crm/examples → examples}/FilterExample.jsx +0 -0
- /package/src/components/{crm/examples → examples}/FormStylingGuide.md +0 -0
- /package/src/components/{crm/examples → examples}/FormWithSectionHeaders.jsx +0 -0
- /package/src/components/{crm/examples → examples}/README.md +0 -0
- /package/src/components/{cms/generic → generic}/CmsIndex.jsx +0 -0
- /package/src/components/{crm/generic → generic}/GenericAuth.jsx +0 -0
- /package/src/components/{crm/generic → generic}/shared/formatters.js +0 -0
- /package/src/components/{crm/generic → generic}/shared/gridUtils.js +0 -0
- /package/src/components/{crm/generic → generic}/utils/formatters.js +0 -0
- /package/src/components/{crm/modals → modals}/GalleryModal.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/SketchField.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/arrow.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/circle.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/default-tool.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/fabrictool.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/history.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/json/config.json +0 -0
- /package/src/components/{crm/sketch → sketch}/line.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/pan.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/pencil.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/rectangle-label-object.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/rectangle-label.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/rectangle.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/select.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/tools.jsx +0 -0
- /package/src/components/{crm/sketch → sketch}/utils.jsx +0 -0
- /package/src/components/{crm/generic/styles → styles}/ActionButtons.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/AlternativeActionModal.css +0 -0
- /package/src/components/{crm/styles → styles}/AssociationManager.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/AsyncSelect.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/AuditLog.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/AuditLogs.module.scss +0 -0
- /package/src/components/{crm/auth/styles → styles}/AuthForm.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/Autocomplete.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/BusinessCardOcr.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/ClientAssociationManager.module.scss +0 -0
- /package/src/components/{crm/auth/styles → styles}/ClientAuth.module.scss +0 -0
- /package/src/components/{crm/client/styles → styles}/ClientDashboard.module.scss +0 -0
- /package/src/components/{crm/client/styles → styles}/ClientPortal.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/ContactSelectorModal.css +0 -0
- /package/src/components/{crm/styles → styles}/DataGrid.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/DatePickerDialog.css +0 -0
- /package/src/components/{crm/generic/styles → styles}/DateRangeSelectorModal.css +0 -0
- /package/src/components/{cms/styles → styles}/DropZone.module.css +0 -0
- /package/src/components/{crm/styles → styles}/Field.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/Form.module.scss +0 -0
- /package/src/components/{cms/styles → styles}/Gallery.module.css +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericClientPortal.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericDashboard.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericDetail.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericDynamic.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericEditableTable.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericFormBuilder.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericIndex.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericMain.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericQuote.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericReport.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/GenericSort.module.scss +0 -0
- /package/src/components/{crm/sorting/styles → styles}/Item.module.scss +0 -0
- /package/src/components/{cms/sorting/styles → styles}/List.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/Loader.module.scss +0 -0
- /package/src/components/{crm/auth/styles → styles}/Login.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/MergeEntity.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/MultiSelect.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/Navigation.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/Notification.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/NotificationList.module.scss +0 -0
- /package/src/components/{crm/auth/styles → styles}/Profile.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/QrCode.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/QuickAction.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/ReasonCollectorModal.css +0 -0
- /package/src/components/{crm/generic/styles → styles}/ReportForm.module.scss +0 -0
- /package/src/components/{crm/auth/styles → styles}/Reset.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/SortableQuoteItems.module.scss +0 -0
- /package/src/components/{crm/generic/styles → styles}/SweetAlert.module.css +0 -0
- /package/src/components/{crm/styles → styles}/SwitchAccount.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/TableFilter.module.scss +0 -0
- /package/src/components/{crm/auth/styles → styles}/TwoFactorAuth.module.scss +0 -0
- /package/src/components/{crm/auth/styles → styles}/Verify.module.scss +0 -0
- /package/src/components/{crm/styles → styles}/global-datagrid.css +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.
|
|
18
|
-
"@visns-studio/visns-datagrid-enterprise": "^1.0.
|
|
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.
|
|
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.
|
|
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.
|
|
90
|
+
"version": "5.12.0",
|
|
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 '
|
|
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 '
|
|
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 '
|
|
42
|
+
import fetchUtil from '../utils/fetchUtil';
|
|
43
43
|
import { confirmDialog } from '../utils/ConfirmDialog';
|
|
44
|
-
import { DEFAULT_INTELLIGENT_SORTING_CONFIG } from '
|
|
45
|
-
import { extractColumnsMetadata, isColumnSortable } from '
|
|
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,
|
|
@@ -275,6 +275,8 @@ const DataGrid = forwardRef(
|
|
|
275
275
|
const [formType, setFormType] = useState('');
|
|
276
276
|
const [formId, setFormId] = useState(0);
|
|
277
277
|
const [modalShow, setModalShow] = useState(false);
|
|
278
|
+
const [bulkEditMode, setBulkEditMode] = useState(false);
|
|
279
|
+
const [bulkEditGroupData, setBulkEditGroupData] = useState(null);
|
|
278
280
|
|
|
279
281
|
/** Modal Functions */
|
|
280
282
|
const modalOpen = (formType, formId) => {
|
|
@@ -285,6 +287,8 @@ const DataGrid = forwardRef(
|
|
|
285
287
|
|
|
286
288
|
const modalClose = () => {
|
|
287
289
|
setModalShow(false);
|
|
290
|
+
setBulkEditMode(false);
|
|
291
|
+
setBulkEditGroupData(null);
|
|
288
292
|
};
|
|
289
293
|
|
|
290
294
|
useEffect(() => {
|
|
@@ -1209,7 +1213,13 @@ const DataGrid = forwardRef(
|
|
|
1209
1213
|
// Get all rows for this group
|
|
1210
1214
|
const groupRows = getGroupRows(groupValue);
|
|
1211
1215
|
|
|
1212
|
-
//
|
|
1216
|
+
// Skip confirmation dialog for edit actions - open modal directly
|
|
1217
|
+
if (iconConfig.id === 'edit' && iconConfig.formModal) {
|
|
1218
|
+
executeGroupAction(groupValue, iconConfig);
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
// Show confirmation dialog for other actions to prevent accidental clicks
|
|
1213
1223
|
const confirmMessage = `Are you sure you want to perform "${iconConfig.label}" action on group "${groupValue}" (${groupRows.length} rows)?`;
|
|
1214
1224
|
|
|
1215
1225
|
confirmDialog({
|
|
@@ -1310,7 +1320,10 @@ const DataGrid = forwardRef(
|
|
|
1310
1320
|
}
|
|
1311
1321
|
} else {
|
|
1312
1322
|
// Fallback to existing switch logic if no fetch config
|
|
1313
|
-
toast
|
|
1323
|
+
// Skip toast notification for edit actions
|
|
1324
|
+
if (iconConfig.id !== 'edit') {
|
|
1325
|
+
toast.info(`${iconConfig.label} - Group: ${groupValue}`);
|
|
1326
|
+
}
|
|
1314
1327
|
|
|
1315
1328
|
switch (iconConfig.id) {
|
|
1316
1329
|
case 'clock':
|
|
@@ -1329,9 +1342,28 @@ const DataGrid = forwardRef(
|
|
|
1329
1342
|
);
|
|
1330
1343
|
break;
|
|
1331
1344
|
case 'edit':
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1345
|
+
// Handle bulk edit action
|
|
1346
|
+
if (iconConfig.formModal) {
|
|
1347
|
+
// Get all rows in the group for bulk editing
|
|
1348
|
+
const groupRows = getGroupRows(groupValue);
|
|
1349
|
+
const groupRowIds = groupRows.map(row => row[form?.primaryKey || 'id']);
|
|
1350
|
+
|
|
1351
|
+
// Set bulk edit data
|
|
1352
|
+
setBulkEditMode(true);
|
|
1353
|
+
setBulkEditGroupData({
|
|
1354
|
+
groupValue: groupValue,
|
|
1355
|
+
groupRows: groupRows,
|
|
1356
|
+
groupRowIds: groupRowIds,
|
|
1357
|
+
iconConfig: iconConfig
|
|
1358
|
+
});
|
|
1359
|
+
|
|
1360
|
+
// Open modal for bulk editing
|
|
1361
|
+
modalOpen('update', null);
|
|
1362
|
+
} else {
|
|
1363
|
+
console.log(
|
|
1364
|
+
`Bulk edit action for group: ${groupValue}`
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1335
1367
|
break;
|
|
1336
1368
|
case 'envelope':
|
|
1337
1369
|
console.log(
|
|
@@ -2449,7 +2481,21 @@ const DataGrid = forwardRef(
|
|
|
2449
2481
|
? column.filter.placeholder
|
|
2450
2482
|
: 'All Options',
|
|
2451
2483
|
dataSource: selectedDataSource,
|
|
2484
|
+
searchable: column.filter.searchable !== false,
|
|
2485
|
+
// Enable clear functionality even when searchable is false
|
|
2486
|
+
allowClearWhenNotSearchable: column.filter.searchable === false,
|
|
2487
|
+
// Explicitly enable clear icon
|
|
2488
|
+
clearIcon: true,
|
|
2452
2489
|
};
|
|
2490
|
+
|
|
2491
|
+
// Debug: Check if fix is applied
|
|
2492
|
+
if (column.filter.searchable === false) {
|
|
2493
|
+
console.log('Filter Debug - searchable=false:', {
|
|
2494
|
+
columnName: column.name || 'unknown',
|
|
2495
|
+
props: filterEditorProps,
|
|
2496
|
+
visnsDataGridVersion: 'v1.0.18'
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2453
2499
|
break;
|
|
2454
2500
|
default:
|
|
2455
2501
|
filterEditor = null;
|
|
@@ -3607,6 +3653,8 @@ const DataGrid = forwardRef(
|
|
|
3607
3653
|
style={style}
|
|
3608
3654
|
updateForm={setFormData}
|
|
3609
3655
|
userProfile={userProfile}
|
|
3656
|
+
bulkEditMode={bulkEditMode}
|
|
3657
|
+
bulkEditGroupData={bulkEditGroupData}
|
|
3610
3658
|
/>
|
|
3611
3659
|
</div>
|
|
3612
3660
|
</div>
|
|
@@ -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 '
|
|
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 '
|
|
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 '
|
|
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 '
|
|
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 '
|
|
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';
|
|
@@ -80,6 +80,8 @@ function Form({
|
|
|
80
80
|
type,
|
|
81
81
|
updateForm,
|
|
82
82
|
userProfile,
|
|
83
|
+
bulkEditMode = false,
|
|
84
|
+
bulkEditGroupData = null,
|
|
83
85
|
}) {
|
|
84
86
|
const navigate = useNavigate();
|
|
85
87
|
const [fetchTrigger, setFetchTrigger] = useState(false);
|
|
@@ -888,34 +890,42 @@ function Form({
|
|
|
888
890
|
}
|
|
889
891
|
method = formSettings.customMethod;
|
|
890
892
|
} else {
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
893
|
+
// Check if this is bulk edit mode
|
|
894
|
+
if (bulkEditMode && bulkEditGroupData?.iconConfig?.formModal) {
|
|
895
|
+
// Use bulk edit endpoint configuration
|
|
896
|
+
const formModalConfig = bulkEditGroupData.iconConfig.formModal;
|
|
897
|
+
url = formModalConfig.url || url;
|
|
898
|
+
method = formModalConfig.method || 'POST';
|
|
899
|
+
} else {
|
|
900
|
+
switch (formType) {
|
|
901
|
+
case 'create':
|
|
902
|
+
if (formSettings.json) {
|
|
903
|
+
url += '/json/store';
|
|
904
|
+
}
|
|
905
|
+
break;
|
|
906
|
+
case 'update':
|
|
907
|
+
case 'delete':
|
|
908
|
+
if (formSettings.json) {
|
|
909
|
+
url +=
|
|
910
|
+
formType === 'update'
|
|
911
|
+
? '/json/update'
|
|
912
|
+
: `/json/delete/${
|
|
913
|
+
formData[
|
|
914
|
+
formSettings
|
|
915
|
+
.primaryKey
|
|
916
|
+
]
|
|
917
|
+
}`;
|
|
918
|
+
} else {
|
|
919
|
+
url += `/${
|
|
920
|
+
formData[formSettings.primaryKey]
|
|
921
|
+
}`;
|
|
922
|
+
}
|
|
923
|
+
method =
|
|
901
924
|
formType === 'update'
|
|
902
|
-
? '
|
|
903
|
-
:
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
.primaryKey
|
|
907
|
-
]
|
|
908
|
-
}`;
|
|
909
|
-
} else {
|
|
910
|
-
url += `/${
|
|
911
|
-
formData[formSettings.primaryKey]
|
|
912
|
-
}`;
|
|
913
|
-
}
|
|
914
|
-
method =
|
|
915
|
-
formType === 'update'
|
|
916
|
-
? 'PUT'
|
|
917
|
-
: 'DELETE';
|
|
918
|
-
break;
|
|
925
|
+
? 'PUT'
|
|
926
|
+
: 'DELETE';
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
919
929
|
}
|
|
920
930
|
}
|
|
921
931
|
|
|
@@ -1046,7 +1056,7 @@ function Form({
|
|
|
1046
1056
|
}
|
|
1047
1057
|
|
|
1048
1058
|
// Transform keys with dots into nested objects
|
|
1049
|
-
|
|
1059
|
+
let payload = Object.keys(updatedFormData).reduce(
|
|
1050
1060
|
(acc, key) => {
|
|
1051
1061
|
if (key.includes('.')) {
|
|
1052
1062
|
const [root, sub] = key.split('.');
|
|
@@ -1060,6 +1070,18 @@ function Form({
|
|
|
1060
1070
|
{}
|
|
1061
1071
|
);
|
|
1062
1072
|
|
|
1073
|
+
// Add bulk edit data to payload if in bulk edit mode
|
|
1074
|
+
if (bulkEditMode && bulkEditGroupData) {
|
|
1075
|
+
payload = {
|
|
1076
|
+
...payload,
|
|
1077
|
+
bulkEdit: true,
|
|
1078
|
+
groupValue: bulkEditGroupData.groupValue,
|
|
1079
|
+
groupKey: bulkEditGroupData.iconConfig.formModal?.groupKey || ajaxSetting?.groupBy?.[0],
|
|
1080
|
+
rowIds: bulkEditGroupData.groupRowIds,
|
|
1081
|
+
...bulkEditGroupData.iconConfig.formModal?.data
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1063
1085
|
const res = await CustomFetch(url, method, payload);
|
|
1064
1086
|
|
|
1065
1087
|
if (res.data.error === '') {
|
|
@@ -2233,7 +2255,12 @@ function Form({
|
|
|
2233
2255
|
<div className={styles.modalwrap}>
|
|
2234
2256
|
<div className={styles.modal}>
|
|
2235
2257
|
<div className={styles.modal__header}>
|
|
2236
|
-
<h1>
|
|
2258
|
+
<h1>
|
|
2259
|
+
{bulkEditMode && bulkEditGroupData
|
|
2260
|
+
? `${bulkEditGroupData.iconConfig.formModal?.title || 'Bulk Edit'} - ${bulkEditGroupData.groupValue} (${bulkEditGroupData.groupRows.length} items)`
|
|
2261
|
+
: formSettings[formType]?.title
|
|
2262
|
+
}
|
|
2263
|
+
</h1>
|
|
2237
2264
|
<button
|
|
2238
2265
|
className={styles.modal__close}
|
|
2239
2266
|
onClick={closeModal}
|
|
@@ -2265,6 +2292,14 @@ function Form({
|
|
|
2265
2292
|
) {
|
|
2266
2293
|
return null;
|
|
2267
2294
|
}
|
|
2295
|
+
// In bulk edit mode, only show fields specified in the formModal configuration
|
|
2296
|
+
if (
|
|
2297
|
+
bulkEditMode &&
|
|
2298
|
+
bulkEditGroupData?.iconConfig?.formModal?.fields &&
|
|
2299
|
+
!bulkEditGroupData.iconConfig.formModal.fields.includes(item.id)
|
|
2300
|
+
) {
|
|
2301
|
+
return null;
|
|
2302
|
+
}
|
|
2268
2303
|
|
|
2269
2304
|
return (
|
|
2270
2305
|
<Field
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import '
|
|
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 '
|
|
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 '
|
|
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 '
|
|
10
|
+
import styles from '../styles/ClientAuth.module.scss';
|
|
11
11
|
|
|
12
12
|
const ClientOTPVerify = ({
|
|
13
13
|
logo,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import '
|
|
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 '
|
|
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/
|
|
2
|
-
import '
|
|
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 '
|
|
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 '
|
|
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 '
|
|
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 '
|
|
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 '
|
|
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 '
|
|
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 '
|
|
12
|
+
import styles from '../styles/Verify.module.scss';
|
|
13
13
|
|
|
14
14
|
const Verify = ({ logo }) => {
|
|
15
15
|
const navigate = useNavigate();
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isRelationshipColumnSortable,
|
|
9
9
|
getRelationshipPath,
|
|
10
10
|
DEFAULT_INTELLIGENT_SORTING_CONFIG,
|
|
11
|
-
} from '
|
|
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 === '-') {
|
|
@@ -1453,16 +1453,22 @@ export const renderGalleryColumn = ({
|
|
|
1453
1453
|
: data[column.id];
|
|
1454
1454
|
|
|
1455
1455
|
// Check if we have valid image data
|
|
1456
|
-
if (
|
|
1456
|
+
if (
|
|
1457
|
+
!imagesArray ||
|
|
1458
|
+
!Array.isArray(imagesArray) ||
|
|
1459
|
+
imagesArray.length === 0
|
|
1460
|
+
) {
|
|
1457
1461
|
return (
|
|
1458
|
-
<div
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1462
|
+
<div
|
|
1463
|
+
style={{
|
|
1464
|
+
display: 'flex',
|
|
1465
|
+
alignItems: 'center',
|
|
1466
|
+
justifyContent: 'center',
|
|
1467
|
+
height: '40px',
|
|
1468
|
+
color: '#999',
|
|
1469
|
+
fontSize: '12px',
|
|
1470
|
+
}}
|
|
1471
|
+
>
|
|
1466
1472
|
No images
|
|
1467
1473
|
</div>
|
|
1468
1474
|
);
|
|
@@ -1486,13 +1492,13 @@ export const renderGalleryColumn = ({
|
|
|
1486
1492
|
|
|
1487
1493
|
// Set gallery data and current item
|
|
1488
1494
|
setGalleryData(galleryData);
|
|
1489
|
-
setCurrentItem({
|
|
1490
|
-
data: data,
|
|
1495
|
+
setCurrentItem({
|
|
1496
|
+
data: data,
|
|
1491
1497
|
settings: {
|
|
1492
1498
|
relation: column.relation,
|
|
1493
1499
|
key: column.key,
|
|
1494
|
-
captionKey: column.captionKey || 'file_name'
|
|
1495
|
-
}
|
|
1500
|
+
captionKey: column.captionKey || 'file_name',
|
|
1501
|
+
},
|
|
1496
1502
|
});
|
|
1497
1503
|
|
|
1498
1504
|
// Open the gallery modal
|
|
@@ -1533,7 +1539,7 @@ export const renderGalleryColumn = ({
|
|
|
1533
1539
|
{displayImages.map((image, index) => {
|
|
1534
1540
|
const imageUrl = image[column.key];
|
|
1535
1541
|
if (!imageUrl) return null;
|
|
1536
|
-
|
|
1542
|
+
|
|
1537
1543
|
return (
|
|
1538
1544
|
<div
|
|
1539
1545
|
key={index}
|
|
@@ -1548,7 +1554,11 @@ export const renderGalleryColumn = ({
|
|
|
1548
1554
|
>
|
|
1549
1555
|
<img
|
|
1550
1556
|
src={imageUrl}
|
|
1551
|
-
alt={
|
|
1557
|
+
alt={
|
|
1558
|
+
image[
|
|
1559
|
+
column.captionKey || 'file_name'
|
|
1560
|
+
] || `Image ${index + 1}`
|
|
1561
|
+
}
|
|
1552
1562
|
style={{
|
|
1553
1563
|
width: '100%',
|
|
1554
1564
|
height: '100%',
|
|
@@ -1562,7 +1572,7 @@ export const renderGalleryColumn = ({
|
|
|
1562
1572
|
);
|
|
1563
1573
|
})}
|
|
1564
1574
|
</div>
|
|
1565
|
-
|
|
1575
|
+
|
|
1566
1576
|
{/* Count badge */}
|
|
1567
1577
|
<div
|
|
1568
1578
|
style={{
|
|
@@ -1572,7 +1582,8 @@ export const renderGalleryColumn = ({
|
|
|
1572
1582
|
lineHeight: '1.2',
|
|
1573
1583
|
}}
|
|
1574
1584
|
>
|
|
1575
|
-
{imagesArray.length}
|
|
1585
|
+
{imagesArray.length}{' '}
|
|
1586
|
+
{imagesArray.length === 1 ? 'image' : 'images'}
|
|
1576
1587
|
{remainingCount > 0 && ` (+${remainingCount})`}
|
|
1577
1588
|
</div>
|
|
1578
1589
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Swal from 'sweetalert2';
|
|
2
|
-
import '
|
|
3
|
-
import '
|
|
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 '
|
|
6
|
+
import styles from '../styles/AuditLog.module.scss';
|
|
7
7
|
|
|
8
8
|
const AuditLog = ({ userProfile }) => {
|
|
9
9
|
const routeParams = useParams();
|