@visns-studio/visns-components 5.10.3 → 5.10.5
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
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"@tinymce/tinymce-react": "^6.2.1",
|
|
16
16
|
"@visns-studio/visns-datagrid-community": "^1.0.14",
|
|
17
17
|
"@visns-studio/visns-datagrid-enterprise": "^1.0.14",
|
|
18
|
-
"@vitejs/plugin-react": "^4.5.
|
|
18
|
+
"@vitejs/plugin-react": "^4.5.2",
|
|
19
19
|
"add": "^2.0.6",
|
|
20
20
|
"akar-icons": "^1.9.31",
|
|
21
21
|
"array-move": "^4.0.0",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"mini-css-extract-plugin": "^2.9.2",
|
|
80
80
|
"react": "^18.3.1",
|
|
81
81
|
"react-dom": "^18.3.1",
|
|
82
|
-
"sass": "^1.89.
|
|
82
|
+
"sass": "^1.89.2",
|
|
83
83
|
"sass-loader": "^16.0.5"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
@@ -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.10.
|
|
90
|
+
"version": "5.10.5",
|
|
91
91
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
92
92
|
"main": "src/index.js",
|
|
93
93
|
"files": [
|
|
@@ -1220,7 +1220,7 @@ const DataGrid = forwardRef(
|
|
|
1220
1220
|
const handleGroupAction = async (groupValue, iconConfig) => {
|
|
1221
1221
|
// Get all rows for this group
|
|
1222
1222
|
const groupRows = getGroupRows(groupValue);
|
|
1223
|
-
|
|
1223
|
+
|
|
1224
1224
|
// Show confirmation dialog to prevent accidental clicks
|
|
1225
1225
|
const confirmMessage = `Are you sure you want to perform "${iconConfig.label}" action on group "${groupValue}" (${groupRows.length} rows)?`;
|
|
1226
1226
|
|
|
@@ -1232,15 +1232,15 @@ const DataGrid = forwardRef(
|
|
|
1232
1232
|
label: 'Yes',
|
|
1233
1233
|
onClick: () => {
|
|
1234
1234
|
executeGroupAction(groupValue, iconConfig);
|
|
1235
|
-
}
|
|
1235
|
+
},
|
|
1236
1236
|
},
|
|
1237
1237
|
{
|
|
1238
1238
|
label: 'No',
|
|
1239
1239
|
onClick: () => {
|
|
1240
1240
|
// User cancelled
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
]
|
|
1241
|
+
},
|
|
1242
|
+
},
|
|
1243
|
+
],
|
|
1244
1244
|
});
|
|
1245
1245
|
};
|
|
1246
1246
|
|
|
@@ -1248,9 +1248,11 @@ const DataGrid = forwardRef(
|
|
|
1248
1248
|
if (!dataRef.current || !ajaxSetting?.groupBy) {
|
|
1249
1249
|
return [];
|
|
1250
1250
|
}
|
|
1251
|
-
|
|
1251
|
+
|
|
1252
1252
|
const groupField = ajaxSetting.groupBy[0];
|
|
1253
|
-
return dataRef.current.filter(
|
|
1253
|
+
return dataRef.current.filter(
|
|
1254
|
+
(row) => row[groupField] === groupValue
|
|
1255
|
+
);
|
|
1254
1256
|
};
|
|
1255
1257
|
|
|
1256
1258
|
const shouldShowGroupAction = (iconConfig, groupValue) => {
|
|
@@ -1261,20 +1263,24 @@ const DataGrid = forwardRef(
|
|
|
1261
1263
|
|
|
1262
1264
|
// Get all rows for this group
|
|
1263
1265
|
const groupRows = getGroupRows(groupValue);
|
|
1264
|
-
|
|
1266
|
+
|
|
1265
1267
|
// Check if all show conditions are met
|
|
1266
|
-
return iconConfig.show.every(condition => {
|
|
1268
|
+
return iconConfig.show.every((condition) => {
|
|
1267
1269
|
const { id, value } = condition;
|
|
1268
|
-
|
|
1270
|
+
|
|
1269
1271
|
// Check if any row in the group matches the condition
|
|
1270
|
-
return groupRows.some(row => {
|
|
1272
|
+
return groupRows.some((row) => {
|
|
1271
1273
|
const rowValue = row[id];
|
|
1272
|
-
|
|
1274
|
+
|
|
1273
1275
|
// Handle null value condition
|
|
1274
1276
|
if (value === null) {
|
|
1275
|
-
return
|
|
1277
|
+
return (
|
|
1278
|
+
rowValue === null ||
|
|
1279
|
+
rowValue === undefined ||
|
|
1280
|
+
rowValue === ''
|
|
1281
|
+
);
|
|
1276
1282
|
}
|
|
1277
|
-
|
|
1283
|
+
|
|
1278
1284
|
// Handle other value conditions
|
|
1279
1285
|
return rowValue === value;
|
|
1280
1286
|
});
|
|
@@ -1287,7 +1293,7 @@ const DataGrid = forwardRef(
|
|
|
1287
1293
|
try {
|
|
1288
1294
|
const payload = {
|
|
1289
1295
|
...iconConfig.fetch.data,
|
|
1290
|
-
groupLabel: groupValue
|
|
1296
|
+
groupLabel: groupValue,
|
|
1291
1297
|
};
|
|
1292
1298
|
|
|
1293
1299
|
const result = await CustomFetch(
|
|
@@ -2644,6 +2650,10 @@ const DataGrid = forwardRef(
|
|
|
2644
2650
|
name: columnId,
|
|
2645
2651
|
filterEditor: filterEditor,
|
|
2646
2652
|
filterEditorProps: filterEditorProps,
|
|
2653
|
+
className:
|
|
2654
|
+
column.wordWrap === true
|
|
2655
|
+
? 'cell-word-wrap'
|
|
2656
|
+
: '',
|
|
2647
2657
|
render: ({ data }) => {
|
|
2648
2658
|
if (
|
|
2649
2659
|
data &&
|
|
@@ -2654,6 +2664,25 @@ const DataGrid = forwardRef(
|
|
|
2654
2664
|
data[column.id]
|
|
2655
2665
|
);
|
|
2656
2666
|
|
|
2667
|
+
// Debug logging for wordWrap cell rendering
|
|
2668
|
+
if (column.wordWrap === true) {
|
|
2669
|
+
console.log(
|
|
2670
|
+
'DataGrid DEBUG - Rendering WordWrap Cell:',
|
|
2671
|
+
{
|
|
2672
|
+
columnId,
|
|
2673
|
+
contentLength:
|
|
2674
|
+
content.length,
|
|
2675
|
+
contentPreview:
|
|
2676
|
+
content.substring(
|
|
2677
|
+
0,
|
|
2678
|
+
50
|
|
2679
|
+
) + '...',
|
|
2680
|
+
wordWrapProp:
|
|
2681
|
+
column.wordWrap,
|
|
2682
|
+
}
|
|
2683
|
+
);
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2657
2686
|
// If removeFormat is true, strip HTML tags
|
|
2658
2687
|
if (column.removeFormat) {
|
|
2659
2688
|
content = content.replace(
|
|
@@ -2688,6 +2717,9 @@ const DataGrid = forwardRef(
|
|
|
2688
2717
|
<CellWithTooltip
|
|
2689
2718
|
value={data[column.id]}
|
|
2690
2719
|
columnType="text"
|
|
2720
|
+
wordWrap={
|
|
2721
|
+
column.wordWrap === true
|
|
2722
|
+
}
|
|
2691
2723
|
>
|
|
2692
2724
|
<span>
|
|
2693
2725
|
{parse(content)}
|
|
@@ -2995,11 +3027,18 @@ const DataGrid = forwardRef(
|
|
|
2995
3027
|
<>
|
|
2996
3028
|
{/* Top container with search, action buttons, and auto-refresh */}
|
|
2997
3029
|
{/* Only show top container if there are controls to display */}
|
|
2998
|
-
{(
|
|
2999
|
-
!form.
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3030
|
+
{(() => {
|
|
3031
|
+
const hasSearchOrCreate = !form.searchDisable || !form.createDisable;
|
|
3032
|
+
const hasAutoRefresh = !shouldRelocateAutoRefresh() && ajaxSetting && ajaxSetting.autoRefresh !== undefined;
|
|
3033
|
+
|
|
3034
|
+
// If DataGridSearch would return null (both search and create disabled),
|
|
3035
|
+
// only show container if there are other controls besides auto-refresh
|
|
3036
|
+
if (form.searchDisable === true && form.createDisable === true) {
|
|
3037
|
+
return false; // Hide AutoRefreshControls when it would be the only control
|
|
3038
|
+
}
|
|
3039
|
+
|
|
3040
|
+
return hasSearchOrCreate || hasAutoRefresh;
|
|
3041
|
+
})() && (
|
|
3003
3042
|
<div className={styles.dataGridTopContainer}>
|
|
3004
3043
|
<div className={styles.dataGridTopLeftContainer}>
|
|
3005
3044
|
<DataGridSearch
|
|
@@ -3242,7 +3281,12 @@ const DataGrid = forwardRef(
|
|
|
3242
3281
|
};
|
|
3243
3282
|
|
|
3244
3283
|
// Check if this icon should be shown based on show conditions
|
|
3245
|
-
if (
|
|
3284
|
+
if (
|
|
3285
|
+
!shouldShowGroupAction(
|
|
3286
|
+
iconConfig,
|
|
3287
|
+
groupValue
|
|
3288
|
+
)
|
|
3289
|
+
) {
|
|
3246
3290
|
return null;
|
|
3247
3291
|
}
|
|
3248
3292
|
|
|
@@ -819,11 +819,12 @@ function Form({
|
|
|
819
819
|
: null;
|
|
820
820
|
|
|
821
821
|
// Check if formData[item.id] is null, undefined, or an empty string AND there's no auto value
|
|
822
|
-
|
|
822
|
+
// Note: 0 is considered a valid value for dropdowns/options
|
|
823
|
+
if ((formData[item.id] === null || formData[item.id] === undefined || formData[item.id] === '') && !autoValue) {
|
|
823
824
|
// Check for required_check dependency
|
|
824
825
|
if (
|
|
825
826
|
item.required_check &&
|
|
826
|
-
|
|
827
|
+
(formData[item.required_check] === null || formData[item.required_check] === undefined || formData[item.required_check] === '')
|
|
827
828
|
) {
|
|
828
829
|
validation += `${item.label} is a required field.<br/>`;
|
|
829
830
|
_inputClass[item.id] = styles.inputError;
|
|
@@ -837,7 +838,7 @@ function Form({
|
|
|
837
838
|
} else if (
|
|
838
839
|
item.required_rely &&
|
|
839
840
|
formData[item.required_rely] &&
|
|
840
|
-
|
|
841
|
+
(formData[item.id] === null || formData[item.id] === undefined || formData[item.id] === '')
|
|
841
842
|
) {
|
|
842
843
|
// Check if the dependent required field is empty when it should be filled
|
|
843
844
|
validation += `${item.label} is a required field.<br/>`;
|
|
@@ -50,6 +50,7 @@ const CellWithTooltip = ({
|
|
|
50
50
|
value,
|
|
51
51
|
columnType = 'text',
|
|
52
52
|
className = '',
|
|
53
|
+
wordWrap = false,
|
|
53
54
|
}) => {
|
|
54
55
|
const cellRef = useRef(null);
|
|
55
56
|
const [showTooltip, setShowTooltip] = useState(false);
|
|
@@ -79,20 +80,34 @@ const CellWithTooltip = ({
|
|
|
79
80
|
|
|
80
81
|
const tooltipContent = formatCellValueForTooltip(value, columnType);
|
|
81
82
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
// For wordWrap columns, only show tooltip if explicitly requested (content is still truncated due to height limits)
|
|
84
|
+
// For non-wordWrap columns, show tooltip when content is truncated
|
|
85
|
+
const shouldShowTooltip =
|
|
86
|
+
wordWrap
|
|
87
|
+
? false // Disable tooltip for wordWrap columns since content is visible
|
|
88
|
+
: showTooltip && tooltipContent && tooltipContent.trim() !== '';
|
|
89
|
+
|
|
90
|
+
// Dynamic styles based on wordWrap setting
|
|
91
|
+
const cellStyles = wordWrap
|
|
92
|
+
? {
|
|
93
|
+
width: '100%',
|
|
94
|
+
whiteSpace: 'normal',
|
|
95
|
+
wordWrap: 'break-word',
|
|
96
|
+
overflowWrap: 'break-word',
|
|
97
|
+
overflow: 'visible',
|
|
98
|
+
}
|
|
99
|
+
: {
|
|
100
|
+
overflow: 'hidden',
|
|
101
|
+
textOverflow: 'ellipsis',
|
|
102
|
+
whiteSpace: 'nowrap',
|
|
103
|
+
width: '100%',
|
|
104
|
+
};
|
|
85
105
|
|
|
86
106
|
return (
|
|
87
107
|
<div
|
|
88
108
|
ref={cellRef}
|
|
89
109
|
className={className}
|
|
90
|
-
style={
|
|
91
|
-
overflow: 'hidden',
|
|
92
|
-
textOverflow: 'ellipsis',
|
|
93
|
-
whiteSpace: 'nowrap',
|
|
94
|
-
width: '100%',
|
|
95
|
-
}}
|
|
110
|
+
style={cellStyles}
|
|
96
111
|
{...(shouldShowTooltip && {
|
|
97
112
|
'data-tooltip-id': tooltipId,
|
|
98
113
|
'data-tooltip-html': tooltipContent,
|
|
@@ -26,6 +26,27 @@
|
|
|
26
26
|
padding: 6px 8px !important; /* Reduced from default padding */
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/* Word wrap enabled cells - specific class for columns with wordWrap: true */
|
|
30
|
+
.InovuaReactDataGrid__cell.cell-word-wrap,
|
|
31
|
+
.InovuaReactDataGrid__cell.cell-word-wrap > *,
|
|
32
|
+
.InovuaReactDataGrid__cell.cell-word-wrap div,
|
|
33
|
+
.InovuaReactDataGrid__cell.cell-word-wrap span {
|
|
34
|
+
white-space: normal !important; /* Allow text wrapping */
|
|
35
|
+
word-wrap: break-word !important; /* Break long words */
|
|
36
|
+
overflow-wrap: break-word !important; /* Modern alternative to word-wrap */
|
|
37
|
+
text-overflow: unset !important; /* Disable text truncation */
|
|
38
|
+
overflow: visible !important; /* Show wrapped content */
|
|
39
|
+
height: auto !important; /* Allow cell to expand vertically */
|
|
40
|
+
min-height: 32px !important; /* Maintain minimum height */
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Default cell behavior - no word wrap */
|
|
44
|
+
.InovuaReactDataGrid__cell:not(.cell-word-wrap) {
|
|
45
|
+
white-space: nowrap !important;
|
|
46
|
+
text-overflow: ellipsis !important;
|
|
47
|
+
overflow: hidden !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
29
50
|
/* Reduce header cell padding as well */
|
|
30
51
|
.InovuaReactDataGrid__header-cell {
|
|
31
52
|
padding: 6px 8px !important;
|