@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 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.6",
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.525.0",
31
+ "lucide-react": "^0.532.0",
32
32
  "moment": "^2.30.1",
33
- "motion": "^12.23.6",
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.11",
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": "Visns Studio",
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
@@ -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 && (
@@ -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
- setFormData((prevState) => ({
128
- ...prevState,
129
- [id]:
130
- e.target.files.length > 1
131
- ? Array.from(e.target.files)
132
- : e.target.files[0],
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) => ({