@visns-studio/visns-components 5.15.10 → 5.15.12

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.
@@ -204,10 +204,11 @@ function Form({
204
204
  if (!_.isEmpty(_dataset)) {
205
205
  Object.keys(_dataset).forEach((c) => {
206
206
  if (formData.hasOwnProperty(c)) {
207
- setFormData((prevState) => ({
208
- ...prevState,
209
- [c]: _dataset[c],
210
- }));
207
+ if (c !== 'name' && c !== 'label')
208
+ setFormData((prevState) => ({
209
+ ...prevState,
210
+ [c]: _dataset[c],
211
+ }));
211
212
  }
212
213
  });
213
214
  }
@@ -323,7 +324,12 @@ function Form({
323
324
  updateFormData({ [id]: inputValue });
324
325
 
325
326
  // Batch update version
326
- const excludedKeys = new Set(['id', 'label', 'description']);
327
+ const excludedKeys = new Set([
328
+ 'id',
329
+ 'label',
330
+ 'description',
331
+ 'name',
332
+ ]);
327
333
  const updates = {};
328
334
 
329
335
  for (const key in inputValue) {
@@ -402,6 +408,7 @@ function Form({
402
408
  switch (action.action) {
403
409
  case 'select-option':
404
410
  case 'create-option': // New case to handle create-option
411
+ case 'deselect-option': // Handle unchecking tags
405
412
  handleSelectOption();
406
413
  break;
407
414
  case 'clear':
@@ -571,7 +578,7 @@ function Form({
571
578
  const handleChangeJsonTable = (event, rowIndex, columnId, fieldType) => {
572
579
  const fieldId = event.target.getAttribute('data-id');
573
580
  let value = event.target.value;
574
-
581
+
575
582
  // Handle different field types
576
583
  if (fieldType === 'checkbox' || fieldType === 'toggle') {
577
584
  value = event.target.checked;
@@ -579,9 +586,9 @@ function Form({
579
586
  value = parseFloat(value) || 0;
580
587
  }
581
588
 
582
- setFormData(prevData => {
589
+ setFormData((prevData) => {
583
590
  const newData = { ...prevData };
584
-
591
+
585
592
  // Get the current JSON value for this field
586
593
  let currentValue = newData[fieldId];
587
594
  if (typeof currentValue === 'string') {
@@ -595,13 +602,17 @@ function Form({
595
602
  // Find field configuration from form settings
596
603
  let fieldConfig = null;
597
604
  if (formSettings && formSettings.fields) {
598
- fieldConfig = formSettings.fields.find(f => f.id === fieldId);
605
+ fieldConfig = formSettings.fields.find((f) => f.id === fieldId);
599
606
  }
600
607
 
601
608
  // Handle nested JSON path (e.g., intervals within galvanizing_intervals)
602
609
  let tableData;
603
-
604
- if (fieldConfig && fieldConfig.jsonPath && currentValue[fieldConfig.jsonPath]) {
610
+
611
+ if (
612
+ fieldConfig &&
613
+ fieldConfig.jsonPath &&
614
+ currentValue[fieldConfig.jsonPath]
615
+ ) {
605
616
  tableData = [...currentValue[fieldConfig.jsonPath]];
606
617
  } else if (Array.isArray(currentValue)) {
607
618
  tableData = [...currentValue];
@@ -613,7 +624,7 @@ function Form({
613
624
  if (tableData[rowIndex]) {
614
625
  tableData[rowIndex] = {
615
626
  ...tableData[rowIndex],
616
- [columnId]: value
627
+ [columnId]: value,
617
628
  };
618
629
  }
619
630
 
@@ -621,7 +632,7 @@ function Form({
621
632
  if (fieldConfig && fieldConfig.jsonPath) {
622
633
  newData[fieldId] = {
623
634
  ...currentValue,
624
- [fieldConfig.jsonPath]: tableData
635
+ [fieldConfig.jsonPath]: tableData,
625
636
  };
626
637
  } else {
627
638
  newData[fieldId] = tableData;
@@ -632,10 +643,10 @@ function Form({
632
643
  };
633
644
 
634
645
  const handleAddJsonTableRow = (fieldId, defaultRow = {}) => {
635
- setFormData(prevData => {
646
+ setFormData((prevData) => {
636
647
  const newData = { ...prevData };
637
648
  let currentValue = newData[fieldId];
638
-
649
+
639
650
  if (typeof currentValue === 'string') {
640
651
  try {
641
652
  currentValue = JSON.parse(currentValue);
@@ -647,12 +658,16 @@ function Form({
647
658
  // Find field configuration from form settings
648
659
  let fieldConfig = null;
649
660
  if (formSettings && formSettings.fields) {
650
- fieldConfig = formSettings.fields.find(f => f.id === fieldId);
661
+ fieldConfig = formSettings.fields.find((f) => f.id === fieldId);
651
662
  }
652
663
 
653
664
  let tableData;
654
-
655
- if (fieldConfig && fieldConfig.jsonPath && currentValue[fieldConfig.jsonPath]) {
665
+
666
+ if (
667
+ fieldConfig &&
668
+ fieldConfig.jsonPath &&
669
+ currentValue[fieldConfig.jsonPath]
670
+ ) {
656
671
  tableData = [...currentValue[fieldConfig.jsonPath]];
657
672
  } else if (Array.isArray(currentValue)) {
658
673
  tableData = [...currentValue];
@@ -663,7 +678,7 @@ function Form({
663
678
  // Add new row with auto-generated number
664
679
  const newRow = {
665
680
  ...defaultRow,
666
- number: tableData.length + 1
681
+ number: tableData.length + 1,
667
682
  };
668
683
  tableData.push(newRow);
669
684
 
@@ -671,7 +686,7 @@ function Form({
671
686
  if (fieldConfig && fieldConfig.jsonPath) {
672
687
  newData[fieldId] = {
673
688
  ...currentValue,
674
- [fieldConfig.jsonPath]: tableData
689
+ [fieldConfig.jsonPath]: tableData,
675
690
  };
676
691
  } else {
677
692
  newData[fieldId] = tableData;
@@ -689,10 +704,10 @@ function Form({
689
704
  {
690
705
  label: 'Yes',
691
706
  onClick: () => {
692
- setFormData(prevData => {
707
+ setFormData((prevData) => {
693
708
  const newData = { ...prevData };
694
709
  let currentValue = newData[fieldId];
695
-
710
+
696
711
  if (typeof currentValue === 'string') {
697
712
  try {
698
713
  currentValue = JSON.parse(currentValue);
@@ -704,13 +719,21 @@ function Form({
704
719
  // Find field configuration from form settings
705
720
  let fieldConfig = null;
706
721
  if (formSettings && formSettings.fields) {
707
- fieldConfig = formSettings.fields.find(f => f.id === fieldId);
722
+ fieldConfig = formSettings.fields.find(
723
+ (f) => f.id === fieldId
724
+ );
708
725
  }
709
726
 
710
727
  let tableData;
711
-
712
- if (fieldConfig && fieldConfig.jsonPath && currentValue[fieldConfig.jsonPath]) {
713
- tableData = [...currentValue[fieldConfig.jsonPath]];
728
+
729
+ if (
730
+ fieldConfig &&
731
+ fieldConfig.jsonPath &&
732
+ currentValue[fieldConfig.jsonPath]
733
+ ) {
734
+ tableData = [
735
+ ...currentValue[fieldConfig.jsonPath],
736
+ ];
714
737
  } else if (Array.isArray(currentValue)) {
715
738
  tableData = [...currentValue];
716
739
  } else {
@@ -729,7 +752,7 @@ function Form({
729
752
  if (fieldConfig && fieldConfig.jsonPath) {
730
753
  newData[fieldId] = {
731
754
  ...currentValue,
732
- [fieldConfig.jsonPath]: tableData
755
+ [fieldConfig.jsonPath]: tableData,
733
756
  };
734
757
  } else {
735
758
  newData[fieldId] = tableData;
@@ -737,15 +760,15 @@ function Form({
737
760
 
738
761
  return newData;
739
762
  });
740
- }
763
+ },
741
764
  },
742
765
  {
743
766
  label: 'No',
744
767
  onClick: () => {
745
768
  // User cancelled - do nothing
746
- }
747
- }
748
- ]
769
+ },
770
+ },
771
+ ],
749
772
  });
750
773
  };
751
774
 
@@ -1179,121 +1202,233 @@ function Form({
1179
1202
 
1180
1203
  // Custom validation for json-table fields
1181
1204
  fields.forEach((item) => {
1182
- if (item.type === 'json-table' && item.validation?.customValidation) {
1205
+ if (
1206
+ item.type === 'json-table' &&
1207
+ item.validation?.customValidation
1208
+ ) {
1183
1209
  try {
1184
1210
  let jsonTableData = [];
1185
1211
  const fieldValue = formData[item.id];
1186
-
1187
- if (fieldValue && fieldValue !== 'null' && fieldValue !== '') {
1188
- const parsedValue = typeof fieldValue === 'string' ? JSON.parse(fieldValue) : fieldValue;
1189
-
1212
+
1213
+ if (
1214
+ fieldValue &&
1215
+ fieldValue !== 'null' &&
1216
+ fieldValue !== ''
1217
+ ) {
1218
+ const parsedValue =
1219
+ typeof fieldValue === 'string'
1220
+ ? JSON.parse(fieldValue)
1221
+ : fieldValue;
1222
+
1190
1223
  // Handle jsonPath setting to extract nested data
1191
- if (item.jsonPath && parsedValue[item.jsonPath]) {
1192
- jsonTableData = Array.isArray(parsedValue[item.jsonPath])
1193
- ? parsedValue[item.jsonPath]
1224
+ if (
1225
+ item.jsonPath &&
1226
+ parsedValue[item.jsonPath]
1227
+ ) {
1228
+ jsonTableData = Array.isArray(
1229
+ parsedValue[item.jsonPath]
1230
+ )
1231
+ ? parsedValue[item.jsonPath]
1194
1232
  : [];
1195
1233
  } else if (Array.isArray(parsedValue)) {
1196
1234
  jsonTableData = parsedValue;
1197
- } else if (typeof parsedValue === 'object' && parsedValue !== null) {
1235
+ } else if (
1236
+ typeof parsedValue === 'object' &&
1237
+ parsedValue !== null
1238
+ ) {
1198
1239
  jsonTableData = [parsedValue];
1199
1240
  }
1200
1241
  }
1201
-
1242
+
1202
1243
  // Perform validation using the same logic as in Field.jsx
1203
- const validateJsonTable = (data, validationConfig) => {
1204
- if (!validationConfig || !validationConfig.customValidation) {
1244
+ const validateJsonTable = (
1245
+ data,
1246
+ validationConfig
1247
+ ) => {
1248
+ if (
1249
+ !validationConfig ||
1250
+ !validationConfig.customValidation
1251
+ ) {
1205
1252
  return { isValid: true, errors: [] };
1206
1253
  }
1207
- const { type, startTimeField, endTimeField, message } = validationConfig.customValidation;
1254
+ const {
1255
+ type,
1256
+ startTimeField,
1257
+ endTimeField,
1258
+ message,
1259
+ } = validationConfig.customValidation;
1208
1260
  const errors = [];
1209
-
1261
+
1210
1262
  if (type === '24hour_coverage') {
1211
1263
  // Convert time strings to minutes for easier calculation
1212
1264
  const timeToMinutes = (timeStr) => {
1213
1265
  if (!timeStr) return null;
1214
- const [hours, minutes] = timeStr.split(':').map(Number);
1266
+ const [hours, minutes] = timeStr
1267
+ .split(':')
1268
+ .map(Number);
1215
1269
  return hours * 60 + minutes;
1216
1270
  };
1217
-
1271
+
1218
1272
  // Sort intervals by start time
1219
- const sortedIntervals = [...data].sort((a, b) => {
1220
- const aStart = timeToMinutes(a[startTimeField]);
1221
- const bStart = timeToMinutes(b[startTimeField]);
1222
- return aStart - bStart;
1223
- });
1224
-
1273
+ const sortedIntervals = [...data].sort(
1274
+ (a, b) => {
1275
+ const aStart = timeToMinutes(
1276
+ a[startTimeField]
1277
+ );
1278
+ const bStart = timeToMinutes(
1279
+ b[startTimeField]
1280
+ );
1281
+ return aStart - bStart;
1282
+ }
1283
+ );
1284
+
1225
1285
  let totalCoverage = 0;
1226
1286
  let previousEnd = null;
1227
-
1228
- for (let i = 0; i < sortedIntervals.length; i++) {
1287
+
1288
+ for (
1289
+ let i = 0;
1290
+ i < sortedIntervals.length;
1291
+ i++
1292
+ ) {
1229
1293
  const interval = sortedIntervals[i];
1230
- const startMinutes = timeToMinutes(interval[startTimeField]);
1231
- const endMinutes = timeToMinutes(interval[endTimeField]);
1232
-
1233
- if (startMinutes === null || endMinutes === null) {
1234
- errors.push(`Interval ${i + 1}: Missing start or end time`);
1294
+ const startMinutes = timeToMinutes(
1295
+ interval[startTimeField]
1296
+ );
1297
+ const endMinutes = timeToMinutes(
1298
+ interval[endTimeField]
1299
+ );
1300
+
1301
+ if (
1302
+ startMinutes === null ||
1303
+ endMinutes === null
1304
+ ) {
1305
+ errors.push(
1306
+ `Interval ${
1307
+ i + 1
1308
+ }: Missing start or end time`
1309
+ );
1235
1310
  continue;
1236
1311
  }
1237
-
1312
+
1238
1313
  // Handle cross-midnight intervals (e.g., 18:00 to 06:00)
1239
1314
  let duration;
1240
1315
  if (endMinutes <= startMinutes) {
1241
- duration = (endMinutes + 1440) - startMinutes;
1316
+ duration =
1317
+ endMinutes +
1318
+ 1440 -
1319
+ startMinutes;
1242
1320
  } else {
1243
- duration = endMinutes - startMinutes;
1321
+ duration =
1322
+ endMinutes - startMinutes;
1244
1323
  }
1245
-
1324
+
1246
1325
  totalCoverage += duration;
1247
-
1326
+
1248
1327
  // Check for gaps (except for the first interval)
1249
- if (previousEnd !== null && startMinutes !== previousEnd) {
1250
- const gapSize = startMinutes > previousEnd
1251
- ? startMinutes - previousEnd
1252
- : (startMinutes + 1440) - previousEnd;
1253
-
1328
+ if (
1329
+ previousEnd !== null &&
1330
+ startMinutes !== previousEnd
1331
+ ) {
1332
+ const gapSize =
1333
+ startMinutes > previousEnd
1334
+ ? startMinutes - previousEnd
1335
+ : startMinutes +
1336
+ 1440 -
1337
+ previousEnd;
1338
+
1254
1339
  if (gapSize > 0 && gapSize < 1440) {
1255
- errors.push(`Gap detected between intervals: ${Math.floor(gapSize / 60)}h ${gapSize % 60}m`);
1340
+ errors.push(
1341
+ `Gap detected between intervals: ${Math.floor(
1342
+ gapSize / 60
1343
+ )}h ${gapSize % 60}m`
1344
+ );
1256
1345
  }
1257
1346
  }
1258
-
1347
+
1259
1348
  // Update previousEnd, handling cross-midnight
1260
- previousEnd = endMinutes <= startMinutes ? endMinutes + 1440 : endMinutes;
1261
- if (previousEnd >= 1440) previousEnd -= 1440;
1349
+ previousEnd =
1350
+ endMinutes <= startMinutes
1351
+ ? endMinutes + 1440
1352
+ : endMinutes;
1353
+ if (previousEnd >= 1440)
1354
+ previousEnd -= 1440;
1262
1355
  }
1263
-
1356
+
1264
1357
  // Check if total coverage equals 24 hours (1440 minutes)
1265
1358
  if (Math.abs(totalCoverage - 1440) > 1) {
1266
- errors.push(`Total coverage is ${Math.floor(totalCoverage / 60)}h ${totalCoverage % 60}m. Required: 24h 0m`);
1359
+ errors.push(
1360
+ `Total coverage is ${Math.floor(
1361
+ totalCoverage / 60
1362
+ )}h ${
1363
+ totalCoverage % 60
1364
+ }m. Required: 24h 0m`
1365
+ );
1267
1366
  }
1268
-
1367
+
1269
1368
  // Check for overlaps
1270
- for (let i = 0; i < sortedIntervals.length - 1; i++) {
1369
+ for (
1370
+ let i = 0;
1371
+ i < sortedIntervals.length - 1;
1372
+ i++
1373
+ ) {
1271
1374
  const current = sortedIntervals[i];
1272
1375
  const next = sortedIntervals[i + 1];
1273
-
1274
- const currentStart = timeToMinutes(current[startTimeField]);
1275
- const currentEnd = timeToMinutes(current[endTimeField]);
1276
- const nextStart = timeToMinutes(next[startTimeField]);
1277
-
1278
- const currentActualEnd = currentEnd <= currentStart ? currentEnd + 1440 : currentEnd;
1376
+
1377
+ const currentStart = timeToMinutes(
1378
+ current[startTimeField]
1379
+ );
1380
+ const currentEnd = timeToMinutes(
1381
+ current[endTimeField]
1382
+ );
1383
+ const nextStart = timeToMinutes(
1384
+ next[startTimeField]
1385
+ );
1386
+
1387
+ const currentActualEnd =
1388
+ currentEnd <= currentStart
1389
+ ? currentEnd + 1440
1390
+ : currentEnd;
1279
1391
  const nextActualStart = nextStart;
1280
-
1281
- if (currentActualEnd > nextActualStart && currentActualEnd < nextActualStart + 1440) {
1282
- const overlapMinutes = currentActualEnd - nextActualStart;
1283
- errors.push(`Overlap detected: ${Math.floor(overlapMinutes / 60)}h ${overlapMinutes % 60}m between intervals ${i + 1} and ${i + 2}`);
1392
+
1393
+ if (
1394
+ currentActualEnd >
1395
+ nextActualStart &&
1396
+ currentActualEnd <
1397
+ nextActualStart + 1440
1398
+ ) {
1399
+ const overlapMinutes =
1400
+ currentActualEnd -
1401
+ nextActualStart;
1402
+ errors.push(
1403
+ `Overlap detected: ${Math.floor(
1404
+ overlapMinutes / 60
1405
+ )}h ${
1406
+ overlapMinutes % 60
1407
+ }m between intervals ${
1408
+ i + 1
1409
+ } and ${i + 2}`
1410
+ );
1284
1411
  }
1285
1412
  }
1286
1413
  }
1287
-
1414
+
1288
1415
  return {
1289
1416
  isValid: errors.length === 0,
1290
- errors: errors.length > 0 ? [message, ...errors] : []
1417
+ errors:
1418
+ errors.length > 0
1419
+ ? [message, ...errors]
1420
+ : [],
1291
1421
  };
1292
1422
  };
1293
-
1294
- const validationResult = validateJsonTable(jsonTableData, item.validation);
1423
+
1424
+ const validationResult = validateJsonTable(
1425
+ jsonTableData,
1426
+ item.validation
1427
+ );
1295
1428
  if (!validationResult.isValid) {
1296
- validation += `${item.label}: ${validationResult.errors.join(', ')}<br/>`;
1429
+ validation += `${
1430
+ item.label
1431
+ }: ${validationResult.errors.join(', ')}<br/>`;
1297
1432
  _inputClass[item.id] = styles.inputError;
1298
1433
  }
1299
1434
  } catch (e) {
@@ -1526,7 +1661,17 @@ function Form({
1526
1661
 
1527
1662
  const res = await CustomFetch(url, method, payload);
1528
1663
 
1664
+
1529
1665
  if (res.data.error === '') {
1666
+ // Update form data with fresh response data after successful submission
1667
+ if (res.data.data && typeof res.data.data === 'object') {
1668
+
1669
+ setFormData(prevFormData => ({
1670
+ ...prevFormData,
1671
+ ...res.data.data
1672
+ }));
1673
+ }
1674
+
1530
1675
  if (formSettings?.save?.pageReload) {
1531
1676
  setTimeout(() => {
1532
1677
  location.reload();
@@ -1762,7 +1907,12 @@ function Form({
1762
1907
  method = 'GET';
1763
1908
  }
1764
1909
 
1765
- const url = `${formSettings.url}${urlSuffix}`;
1910
+ // Add cache-busting parameter for GET requests to ensure fresh data
1911
+ let url = `${formSettings.url}${urlSuffix}`;
1912
+ if (method === 'GET' && formType === 'update') {
1913
+ url += `?_t=${Date.now()}`;
1914
+ }
1915
+
1766
1916
  const result = await CustomFetch(url, method, payload);
1767
1917
 
1768
1918
  const data = result.hasOwnProperty('data')
@@ -2008,7 +2158,7 @@ function Form({
2008
2158
 
2009
2159
  useEffect(() => {
2010
2160
  fetchData();
2011
- }, []);
2161
+ }, [columnId, formType]); // Re-fetch data whenever columnId or formType changes
2012
2162
 
2013
2163
  // Update dataRef when tableData changes
2014
2164
  useEffect(() => {
@@ -2164,9 +2314,15 @@ function Form({
2164
2314
  handleChangeSignature
2165
2315
  }
2166
2316
  onChangeToggle={handleChangeToggle}
2167
- onChangeJsonTable={handleChangeJsonTable}
2168
- onAddJsonTableRow={handleAddJsonTableRow}
2169
- onDeleteJsonTableRow={handleDeleteJsonTableRow}
2317
+ onChangeJsonTable={
2318
+ handleChangeJsonTable
2319
+ }
2320
+ onAddJsonTableRow={
2321
+ handleAddJsonTableRow
2322
+ }
2323
+ onDeleteJsonTableRow={
2324
+ handleDeleteJsonTableRow
2325
+ }
2170
2326
  onFileDownload={handleFileDownload}
2171
2327
  settings={item}
2172
2328
  setFormData={setFormData}
@@ -2809,9 +2965,15 @@ function Form({
2809
2965
  }
2810
2966
  onChangeSelect={handleChangeSelect}
2811
2967
  onChangeToggle={handleChangeToggle}
2812
- onChangeJsonTable={handleChangeJsonTable}
2813
- onAddJsonTableRow={handleAddJsonTableRow}
2814
- onDeleteJsonTableRow={handleDeleteJsonTableRow}
2968
+ onChangeJsonTable={
2969
+ handleChangeJsonTable
2970
+ }
2971
+ onAddJsonTableRow={
2972
+ handleAddJsonTableRow
2973
+ }
2974
+ onDeleteJsonTableRow={
2975
+ handleDeleteJsonTableRow
2976
+ }
2815
2977
  onFileDownload={handleFileDownload}
2816
2978
  settings={item}
2817
2979
  setFormData={setFormData}