@visns-studio/visns-components 5.14.11 → 5.14.13
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/DataGrid.jsx +51 -0
- package/src/components/Field.jsx +15 -0
- package/src/components/Form.jsx +57 -8
- package/src/components/generic/GenericReport.jsx +1437 -589
- package/src/components/generic/StandardModal.jsx +62 -12
- package/src/components/styles/Field.module.scss +144 -48
package/package.json
CHANGED
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
"dayjs": "^1.11.13",
|
|
25
25
|
"fabric": "^6.7.1",
|
|
26
26
|
"file-saver": "^2.0.5",
|
|
27
|
-
"framer-motion": "^12.23.
|
|
27
|
+
"framer-motion": "^12.23.11",
|
|
28
28
|
"html-react-parser": "^5.2.6",
|
|
29
29
|
"lodash": "^4.17.21",
|
|
30
30
|
"lodash.debounce": "^4.0.8",
|
|
31
|
-
"lucide-react": "^0.
|
|
31
|
+
"lucide-react": "^0.532.0",
|
|
32
32
|
"moment": "^2.30.1",
|
|
33
|
-
"motion": "^12.23.
|
|
33
|
+
"motion": "^12.23.11",
|
|
34
34
|
"numeral": "^2.0.6",
|
|
35
35
|
"pluralize": "^8.0.0",
|
|
36
36
|
"qrcode.react": "^4.2.0",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
90
90
|
},
|
|
91
91
|
"name": "@visns-studio/visns-components",
|
|
92
|
-
"version": "5.14.
|
|
92
|
+
"version": "5.14.13",
|
|
93
93
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
94
94
|
"main": "src/index.js",
|
|
95
95
|
"files": [
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"type": "git",
|
|
105
105
|
"url": "git+https://github.com/visnsstudio/visns-components.git"
|
|
106
106
|
},
|
|
107
|
-
"author": "
|
|
107
|
+
"author": "Omnia Global",
|
|
108
108
|
"license": "ISC",
|
|
109
109
|
"bugs": {
|
|
110
110
|
"url": "https://github.com/visnsstudio/visns-components/issues"
|
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
Archive,
|
|
71
71
|
Volume2,
|
|
72
72
|
AlertTriangle,
|
|
73
|
+
AlertCircle,
|
|
73
74
|
} from 'lucide-react';
|
|
74
75
|
import styles from './styles/DataGrid.module.scss';
|
|
75
76
|
|
|
@@ -3282,6 +3283,39 @@ const DataGrid = forwardRef(
|
|
|
3282
3283
|
groupData?.name ||
|
|
3283
3284
|
'';
|
|
3284
3285
|
|
|
3286
|
+
// Check for important marker
|
|
3287
|
+
const checkGroupImportantMarker = (groupValue, importantMarkerConfig) => {
|
|
3288
|
+
if (!importantMarkerConfig || !dataRef.current?.length || !ajaxSetting?.groupBy) {
|
|
3289
|
+
return false;
|
|
3290
|
+
}
|
|
3291
|
+
|
|
3292
|
+
const { id: fieldId, value: expectedValue } = importantMarkerConfig;
|
|
3293
|
+
const groupField = ajaxSetting.groupBy[0];
|
|
3294
|
+
|
|
3295
|
+
// Get all rows that belong to this group
|
|
3296
|
+
const groupRows = dataRef.current.filter(
|
|
3297
|
+
(row) => row[groupField] === groupValue
|
|
3298
|
+
);
|
|
3299
|
+
|
|
3300
|
+
return groupRows.some(row => {
|
|
3301
|
+
const fieldValue = row[fieldId];
|
|
3302
|
+
|
|
3303
|
+
// Handle different value types
|
|
3304
|
+
if (typeof expectedValue === 'boolean') {
|
|
3305
|
+
return Boolean(fieldValue) === expectedValue;
|
|
3306
|
+
}
|
|
3307
|
+
|
|
3308
|
+
return fieldValue === expectedValue;
|
|
3309
|
+
});
|
|
3310
|
+
};
|
|
3311
|
+
|
|
3312
|
+
const hasImportantMarker = checkGroupImportantMarker(
|
|
3313
|
+
groupValue,
|
|
3314
|
+
ajaxSetting?.groupBySetting?.importantMarker
|
|
3315
|
+
);
|
|
3316
|
+
const importantMarkerColor = ajaxSetting?.groupBySetting?.importantMarker?.colour;
|
|
3317
|
+
const importantMarkerTooltip = ajaxSetting?.groupBySetting?.importantMarker?.tooltip || "This group contains items that require attention";
|
|
3318
|
+
|
|
3285
3319
|
// Use ReactDataGrid's built-in toggle functionality
|
|
3286
3320
|
const collapsed =
|
|
3287
3321
|
collapsedGroups[groupValue] ||
|
|
@@ -3534,6 +3568,23 @@ const DataGrid = forwardRef(
|
|
|
3534
3568
|
}
|
|
3535
3569
|
>
|
|
3536
3570
|
{groupValue}
|
|
3571
|
+
{/* Important marker */}
|
|
3572
|
+
{hasImportantMarker && (
|
|
3573
|
+
<AlertCircle
|
|
3574
|
+
className="important-marker"
|
|
3575
|
+
style={{
|
|
3576
|
+
display: 'inline-block',
|
|
3577
|
+
marginLeft: '8px',
|
|
3578
|
+
color: importantMarkerColor || '#FF6961',
|
|
3579
|
+
position: 'relative',
|
|
3580
|
+
top: '1px'
|
|
3581
|
+
}}
|
|
3582
|
+
size={16}
|
|
3583
|
+
title={importantMarkerTooltip}
|
|
3584
|
+
data-tooltip-id="system-tooltip"
|
|
3585
|
+
data-tooltip-content={importantMarkerTooltip}
|
|
3586
|
+
/>
|
|
3587
|
+
)}
|
|
3537
3588
|
</strong>
|
|
3538
3589
|
{/* Click indicator */}
|
|
3539
3590
|
<span
|
package/src/components/Field.jsx
CHANGED
|
@@ -1006,12 +1006,27 @@ function Field({
|
|
|
1006
1006
|
) {
|
|
1007
1007
|
return (
|
|
1008
1008
|
<div className={styles['file-upload-container']}>
|
|
1009
|
+
<div className={styles['file-upload-button-wrapper']}>
|
|
1010
|
+
<label
|
|
1011
|
+
htmlFor={`file-input-${settings.id}`}
|
|
1012
|
+
className={styles['file-upload-button']}
|
|
1013
|
+
>
|
|
1014
|
+
<span>📁</span>
|
|
1015
|
+
Browse Files...
|
|
1016
|
+
</label>
|
|
1017
|
+
<div className={styles['file-upload-help-text']}>
|
|
1018
|
+
Select multiple files to upload. You can add more files later.
|
|
1019
|
+
</div>
|
|
1020
|
+
</div>
|
|
1021
|
+
|
|
1009
1022
|
<input
|
|
1023
|
+
id={`file-input-${settings.id}`}
|
|
1010
1024
|
type="file"
|
|
1011
1025
|
multiple
|
|
1012
1026
|
data-name={settings.id}
|
|
1013
1027
|
className={inputClass[settings.id]}
|
|
1014
1028
|
onChange={onChange}
|
|
1029
|
+
accept={settings.accept || "*/*"}
|
|
1015
1030
|
/>
|
|
1016
1031
|
|
|
1017
1032
|
{inputValue && inputValue.length > 0 && (
|
package/src/components/Form.jsx
CHANGED
|
@@ -123,14 +123,63 @@ function Form({
|
|
|
123
123
|
_dataset = e.target[e.target.selectedIndex].dataset;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
if (e.target.files) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
126
|
+
if (e.target.files && e.target.files.length > 0) {
|
|
127
|
+
// Find the field settings to check if multiple is enabled
|
|
128
|
+
const fieldSettings = formSettings?.fields?.find(field => field.id === id);
|
|
129
|
+
const isMultiple = fieldSettings?.multiple === true;
|
|
130
|
+
|
|
131
|
+
// Debug logging for development
|
|
132
|
+
if (process.env.NODE_ENV === 'development') {
|
|
133
|
+
console.log('File input change:', {
|
|
134
|
+
id,
|
|
135
|
+
filesCount: e.target.files.length,
|
|
136
|
+
isMultiple,
|
|
137
|
+
fieldSettings
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (isMultiple) {
|
|
142
|
+
// For multiple file inputs, append new files to existing ones
|
|
143
|
+
setFormData((prevState) => {
|
|
144
|
+
const existingFiles = prevState[id] || [];
|
|
145
|
+
const newFiles = Array.from(e.target.files);
|
|
146
|
+
|
|
147
|
+
// Ensure existingFiles is always an array for multiple inputs
|
|
148
|
+
const currentFiles = Array.isArray(existingFiles) ? existingFiles : [];
|
|
149
|
+
|
|
150
|
+
const updatedFiles = [...currentFiles, ...newFiles];
|
|
151
|
+
|
|
152
|
+
// Debug logging for development
|
|
153
|
+
if (process.env.NODE_ENV === 'development') {
|
|
154
|
+
console.log('Multiple file update:', {
|
|
155
|
+
existingCount: currentFiles.length,
|
|
156
|
+
newCount: newFiles.length,
|
|
157
|
+
totalCount: updatedFiles.length
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
...prevState,
|
|
163
|
+
[id]: updatedFiles,
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Clear the input so the same files can be selected again
|
|
168
|
+
setTimeout(() => {
|
|
169
|
+
if (e.target) {
|
|
170
|
+
e.target.value = '';
|
|
171
|
+
}
|
|
172
|
+
}, 100);
|
|
173
|
+
} else {
|
|
174
|
+
// For single file inputs or when not multiple, use original behavior
|
|
175
|
+
setFormData((prevState) => ({
|
|
176
|
+
...prevState,
|
|
177
|
+
[id]:
|
|
178
|
+
e.target.files.length > 1
|
|
179
|
+
? Array.from(e.target.files)
|
|
180
|
+
: e.target.files[0],
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
134
183
|
} else {
|
|
135
184
|
if (parent) {
|
|
136
185
|
setFormData((prevState) => ({
|