@visns-studio/visns-components 5.15.16 → 5.15.18

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
@@ -7,7 +7,7 @@
7
7
  "@fontsource/barlow": "^5.2.6",
8
8
  "@inovua/reactdatagrid-community": "^5.10.2",
9
9
  "@inovua/reactdatagrid-enterprise": "^5.10.2",
10
- "@mapbox/mapbox-gl-geocoder": "^5.1.0",
10
+ "@mapbox/mapbox-gl-geocoder": "^5.1.1",
11
11
  "@nivo/bar": "^0.99.0",
12
12
  "@nivo/core": "^0.99.0",
13
13
  "@nivo/line": "^0.99.0",
@@ -24,7 +24,7 @@
24
24
  "array-move": "^4.0.0",
25
25
  "awesome-debounce-promise": "^2.1.0",
26
26
  "browser-image-compression": "^2.0.2",
27
- "dayjs": "^1.11.13",
27
+ "dayjs": "^1.11.14",
28
28
  "fabric": "^6.7.1",
29
29
  "file-saver": "^2.0.5",
30
30
  "framer-motion": "^12.23.12",
@@ -32,7 +32,7 @@
32
32
  "html2canvas": "^1.4.1",
33
33
  "lodash": "^4.17.21",
34
34
  "lodash.debounce": "^4.0.8",
35
- "lucide-react": "^0.541.0",
35
+ "lucide-react": "^0.542.0",
36
36
  "mapbox-gl": "^3.14.0",
37
37
  "moment": "^2.30.1",
38
38
  "motion": "^12.23.12",
@@ -64,7 +64,7 @@
64
64
  "reactjs-popup": "^2.0.6",
65
65
  "style-loader": "^4.0.0",
66
66
  "swapy": "^1.0.5",
67
- "sweetalert2": "^11.22.4",
67
+ "sweetalert2": "^11.22.5",
68
68
  "tesseract.js": "^6.0.1",
69
69
  "truncate": "^3.0.0",
70
70
  "uuid": "^11.1.0",
@@ -86,7 +86,7 @@
86
86
  "mini-css-extract-plugin": "^2.9.4",
87
87
  "react": "^18.3.1",
88
88
  "react-dom": "^18.3.1",
89
- "sass": "^1.90.0",
89
+ "sass": "^1.91.0",
90
90
  "sass-loader": "^16.0.5"
91
91
  },
92
92
  "peerDependencies": {
@@ -94,7 +94,7 @@
94
94
  "react-dom": "^17.0.0 || ^18.0.0"
95
95
  },
96
96
  "name": "@visns-studio/visns-components",
97
- "version": "5.15.16",
97
+ "version": "5.15.18",
98
98
  "description": "Various packages to assist in the development of our Custom Applications.",
99
99
  "main": "src/index.js",
100
100
  "files": [
@@ -287,6 +287,45 @@ const formatName = (name) => {
287
287
  .join(' ');
288
288
  };
289
289
 
290
+ // Enhanced function to format pivot field names with context from end table
291
+ const formatPivotFieldName = (fieldName, pivotTableName, joins, definition = null) => {
292
+ if (!fieldName || !pivotTableName) return formatName(fieldName);
293
+
294
+ // Find if this pivot table has an associated end table through joins
295
+ const pivotJoin = joins.find(join =>
296
+ join.targetTable === pivotTableName && join.autoIncludeEndTable
297
+ );
298
+
299
+ if (pivotJoin && pivotJoin.endTable) {
300
+ // Get a user-friendly name for the end table
301
+ const endTableDisplay = getTableDisplayName(pivotJoin.endTable, definition);
302
+
303
+ // Create contextual field names for common pivot fields
304
+ const contextualMappings = {
305
+ 'area': `${endTableDisplay} Area`,
306
+ 'duration': `${endTableDisplay} Duration`,
307
+ 'qty': `${endTableDisplay} Quantity`,
308
+ 'quantity': `${endTableDisplay} Quantity`,
309
+ 'start_date': `${endTableDisplay} Start Date`,
310
+ 'end_date': `${endTableDisplay} End Date`,
311
+ 'detail': `${endTableDisplay} Details`,
312
+ 'notes': `${endTableDisplay} Notes`,
313
+ 'status': `${endTableDisplay} Status`,
314
+ };
315
+
316
+ const lowercaseField = fieldName.toLowerCase();
317
+ if (contextualMappings[lowercaseField]) {
318
+ return contextualMappings[lowercaseField];
319
+ }
320
+
321
+ // For other fields, just prefix with end table name
322
+ return `${endTableDisplay} ${formatName(fieldName)}`;
323
+ }
324
+
325
+ // Fallback to regular formatting
326
+ return formatName(fieldName);
327
+ };
328
+
290
329
  // User-friendly terminology mapping
291
330
  const friendlyTerms = {
292
331
  // Database terms
@@ -1513,10 +1552,49 @@ const GenericReportImproved = ({
1513
1552
 
1514
1553
  // Start again function to reset wizard to home
1515
1554
  const startAgain = () => {
1516
- // Reset all state
1555
+ console.log('🔄 [DEBUG] StartAgain called - BEFORE reset:', {
1556
+ selectedTemplate: selectedTemplate?.id,
1557
+ customUrls: customUrls,
1558
+ groupingConfig: groupingConfig,
1559
+ });
1560
+
1561
+ // Reset wizard state
1562
+ setCurrentWizardStep(0);
1563
+ setShowTemplates(true);
1564
+ setShowBusinessTemplates(false);
1565
+
1566
+ // CRITICAL FIX: Reset template selection
1567
+ setSelectedTemplate(null);
1568
+
1569
+ // Reset database schema state
1517
1570
  setSelectedTable(null);
1571
+ setTableColumns([]);
1572
+ setAvailableTables([]);
1573
+ setDetectedJoins({});
1574
+ setIsLoadingDetectedJoins({});
1575
+
1576
+ // Reset report configuration
1518
1577
  setSelectedColumns([]);
1519
1578
  setJoins([]);
1579
+ setReportName('');
1580
+ setIsPublic(false);
1581
+ setLoadedReportId(null);
1582
+
1583
+ // Reset manual relationship state
1584
+ setShowManualJoinForm(false);
1585
+ setManualJoin({
1586
+ sourceTable: '',
1587
+ targetTable: '',
1588
+ sourceColumn: '',
1589
+ targetColumn: '',
1590
+ joinType: 'INNER JOIN',
1591
+ });
1592
+ setManualJoinColumns({
1593
+ source: [],
1594
+ target: [],
1595
+ });
1596
+
1597
+ // Reset sorting and filtering
1520
1598
  setFilterCriteria({
1521
1599
  operator: 'AND',
1522
1600
  groups: [
@@ -1529,16 +1607,68 @@ const GenericReportImproved = ({
1529
1607
  setSortCriteria([]);
1530
1608
  setShowSortingSection(false);
1531
1609
  setShowFilteringSection(false);
1610
+ setShowSelectedFields(false);
1611
+
1612
+ // CRITICAL FIX: Reset grouping configuration
1613
+ setGroupingConfig({
1614
+ enabled: false,
1615
+ groupByField: '',
1616
+ groupDisplayName: '',
1617
+ sortBy: '',
1618
+ sortDirection: 'asc',
1619
+ rowsPerGroup: 10,
1620
+ showEmptyRows: false,
1621
+ showGroupTotals: false,
1622
+ expandable: true,
1623
+ groupHeaderStyle: 'primary',
1624
+ emptyRowStyle: 'light',
1625
+ });
1626
+
1627
+ // CRITICAL FIX: Reset custom URLs
1628
+ setCustomUrls({
1629
+ executeUrl: '',
1630
+ exportUrl: '',
1631
+ });
1632
+
1633
+ // Reset report execution and preview
1532
1634
  setPreviewData([]);
1635
+ setGroupedData(null);
1533
1636
  setGridColumns([]);
1534
- setReportName('');
1535
- setIsPublic(false);
1536
- setLoadedReportId(null); // Reset loaded report ID
1537
- setCurrentWizardStep(0);
1538
- setShowTemplates(true);
1539
- setTableColumns([]);
1540
- setAvailableTables([]);
1541
- setHasAutoExecuted(false); // Reset auto-execute flag
1637
+ setTotalResults(0);
1638
+ setHasAutoExecuted(false);
1639
+
1640
+ // Reset pagination
1641
+ setCurrentPage(1);
1642
+ setPageSize(10);
1643
+ setTotalPages(0);
1644
+ setTotalCount(0);
1645
+
1646
+ // Reset calculated fields
1647
+ setCustomCalculatedFields([]);
1648
+ setCalculatedFieldForm({
1649
+ displayName: '',
1650
+ formula: '',
1651
+ type: 'decimal',
1652
+ });
1653
+ setShowCalculatedFieldModal(false);
1654
+
1655
+ // Reset unique fields and exclusions
1656
+ setUniqueFieldConfig({
1657
+ enabled: false,
1658
+ selectedField: '',
1659
+ });
1660
+ setExcludedRows(new Set());
1661
+ setShowRowExclusionModal(false);
1662
+ setExportType('regular');
1663
+
1664
+ // Reset UI state
1665
+ setShowHiddenFields(false);
1666
+
1667
+ console.log('✅ [DEBUG] StartAgain completed - AFTER reset:', {
1668
+ selectedTemplate: null,
1669
+ customUrls: { executeUrl: '', exportUrl: '' },
1670
+ groupingConfig: { enabled: false },
1671
+ });
1542
1672
 
1543
1673
  toast.info(
1544
1674
  'Report builder reset. You can start creating a new report.'
@@ -1851,11 +1981,32 @@ const GenericReportImproved = ({
1851
1981
  // Add join relationship
1852
1982
  const addJoin = (joinData) => {
1853
1983
  const newJoin = { ...joinData, availableColumns: [] };
1854
- setJoins([...joins, newJoin]);
1984
+ const joinsToAdd = [newJoin];
1985
+
1986
+ // If this is a pivot relationship with auto-include end table, add both joins automatically
1987
+ if (joinData.autoIncludeEndTable && joinData.secondJoin) {
1988
+ const endTableJoin = {
1989
+ ...joinData.secondJoin,
1990
+ availableColumns: [],
1991
+ isAutoIncludedEndTable: true
1992
+ };
1993
+ joinsToAdd.push(endTableJoin);
1994
+
1995
+ // Add end table to available tables list
1996
+ if (!availableTables.includes(joinData.secondJoin.targetTable)) {
1997
+ setAvailableTables(prev => [...prev, joinData.secondJoin.targetTable]);
1998
+ // Fetch columns for the end table as well
1999
+ setTimeout(() => {
2000
+ fetchJoinColumns(joinData.secondJoin.targetTable, joins.length + 1);
2001
+ }, 100);
2002
+ }
2003
+ }
2004
+
2005
+ setJoins([...joins, ...joinsToAdd]);
1855
2006
 
1856
- // Fetch columns for the joined table if not already available
2007
+ // Fetch columns for the pivot table if not already available
1857
2008
  if (!availableTables.includes(joinData.targetTable)) {
1858
- setAvailableTables([...availableTables, joinData.targetTable]);
2009
+ setAvailableTables(prev => [...prev, joinData.targetTable]);
1859
2010
  fetchJoinColumns(joinData.targetTable, joins.length); // Use current joins.length as index
1860
2011
  }
1861
2012
  };
@@ -2336,6 +2487,13 @@ const GenericReportImproved = ({
2336
2487
  }
2337
2488
  } else {
2338
2489
  // For predefined templates, use the existing approach
2490
+ console.log('🚨 [DEBUG] Using predefined template approach:', {
2491
+ selectedTemplate: selectedTemplate,
2492
+ selectedTemplateId: selectedTemplate?.id,
2493
+ fallbackId: 'utilization_planning',
2494
+ finalTemplateId: selectedTemplate?.id || 'utilization_planning',
2495
+ });
2496
+
2339
2497
  payload = {
2340
2498
  template_id:
2341
2499
  selectedTemplate?.id || 'utilization_planning',
@@ -2756,7 +2914,7 @@ const GenericReportImproved = ({
2756
2914
  lowerKey.includes('disabled')
2757
2915
  ) {
2758
2916
  // Check if values look like boolean/status values
2759
- const sampleValues = firstPageResult.data
2917
+ const sampleValues = dataToProcess
2760
2918
  .slice(0, 5)
2761
2919
  .map((row) => row[key]);
2762
2920
  const hasStatusValues = sampleValues.some(
@@ -2814,7 +2972,15 @@ const GenericReportImproved = ({
2814
2972
  setGridColumns(dynamicColumns);
2815
2973
  } else {
2816
2974
  // Fallback to selected columns if no data
2817
- const columns = selectedColumns.map((col) => {
2975
+ console.log('🔧 [DEBUG] Creating fallback columns from selectedColumns:', selectedColumns);
2976
+ if (!Array.isArray(selectedColumns) || selectedColumns.length === 0) {
2977
+ console.warn('⚠️ selectedColumns is not a valid array:', selectedColumns);
2978
+ setGridColumns([]);
2979
+ return;
2980
+ }
2981
+
2982
+ const columns = selectedColumns.map((col, index) => {
2983
+ try {
2818
2984
  // Find column type from table columns with enhanced detection
2819
2985
  let columnType = 'varchar';
2820
2986
  const tableColumn = tableColumns.find(
@@ -2852,37 +3018,52 @@ const GenericReportImproved = ({
2852
3018
 
2853
3019
  return {
2854
3020
  name:
2855
- col.displayName || `${col.table}.${col.column}`,
2856
- header: col.displayName || formatName(col.column),
3021
+ col.displayName || `${col.table || 'unknown'}.${col.column}`,
3022
+ header: col.displayName || formatName(col.column || 'Unknown Column'),
2857
3023
  defaultFlex: 1,
2858
3024
  minWidth: 100,
2859
3025
  render: ({ value }) => {
2860
- const formattedValue = formatSmartValue(
2861
- value,
2862
- col.column,
2863
- columnType
2864
- );
2865
-
2866
- // For JSON content, wrap in a container that allows full height expansion
2867
- if (isJsonValue(value)) {
2868
- return (
2869
- <div
2870
- style={{
2871
- whiteSpace: 'normal',
2872
- wordWrap: 'break-word',
2873
- lineHeight: '1.4',
2874
- padding: '4px 0',
2875
- width: '100%',
2876
- }}
2877
- >
2878
- {formattedValue}
2879
- </div>
3026
+ try {
3027
+ const formattedValue = formatSmartValue(
3028
+ value,
3029
+ col.column,
3030
+ columnType
2880
3031
  );
2881
- }
2882
3032
 
2883
- return formattedValue;
3033
+ // For JSON content, wrap in a container that allows full height expansion
3034
+ if (isJsonValue(value)) {
3035
+ return (
3036
+ <div
3037
+ style={{
3038
+ whiteSpace: 'normal',
3039
+ wordWrap: 'break-word',
3040
+ lineHeight: '1.4',
3041
+ padding: '4px 0',
3042
+ width: '100%',
3043
+ }}
3044
+ >
3045
+ {formattedValue}
3046
+ </div>
3047
+ );
3048
+ }
3049
+
3050
+ return formattedValue;
3051
+ } catch (renderError) {
3052
+ console.warn('🚨 Cell render error:', renderError, 'for value:', value);
3053
+ return String(value || '');
3054
+ }
2884
3055
  },
2885
3056
  };
3057
+ } catch (colError) {
3058
+ console.warn('🚨 Column mapping error:', colError, 'for column:', col);
3059
+ return {
3060
+ name: `error_col_${index}`,
3061
+ header: 'Error Column',
3062
+ defaultFlex: 1,
3063
+ minWidth: 100,
3064
+ render: () => 'Error',
3065
+ };
3066
+ }
2886
3067
  });
2887
3068
  setGridColumns(columns);
2888
3069
  }
@@ -2899,8 +3080,24 @@ const GenericReportImproved = ({
2899
3080
  typeof fetchedDataCount
2900
3081
  );
2901
3082
  } catch (error) {
2902
- toast.error('Failed to execute report');
3083
+ console.group('🚨 [ERROR] executeReport failed');
2903
3084
  console.error('Error executing report:', error);
3085
+ console.log('Error name:', error.name);
3086
+ console.log('Error message:', error.message);
3087
+ console.log('Error stack:', error.stack);
3088
+ console.log('Current state at error:', {
3089
+ selectedTable,
3090
+ selectedColumns: selectedColumns.length,
3091
+ hasGrouping: selectedTemplate?.grouping?.enabled || groupingConfig.enabled,
3092
+ currentPage,
3093
+ pageSize,
3094
+ });
3095
+ console.groupEnd();
3096
+
3097
+ // Only show toast error for actual failures, not for successful pagination
3098
+ if (!error.message?.includes('successful')) {
3099
+ toast.error(`Failed to execute report: ${error.message || 'Unknown error'}`);
3100
+ }
2904
3101
  } finally {
2905
3102
  setIsLoading(false);
2906
3103
  }
@@ -5142,6 +5339,11 @@ const GenericReportImproved = ({
5142
5339
  joins.forEach((join) => {
5143
5340
  if (join.availableColumns) {
5144
5341
  join.availableColumns.forEach((col) => {
5342
+ // Use enhanced pivot field naming for pivot tables
5343
+ const columnName = join.isPivotRelationship
5344
+ ? formatPivotFieldName(col.name, join.targetTable, joins, definition)
5345
+ : formatName(col.name);
5346
+
5145
5347
  allColumns.push({
5146
5348
  table: join.targetTable,
5147
5349
  tableName: getTableDisplayName(
@@ -5149,7 +5351,7 @@ const GenericReportImproved = ({
5149
5351
  definition
5150
5352
  ),
5151
5353
  column: col.name,
5152
- columnName: formatName(col.name),
5354
+ columnName: columnName,
5153
5355
  type: col.type,
5154
5356
  });
5155
5357
  });
@@ -5204,6 +5406,11 @@ const GenericReportImproved = ({
5204
5406
  if (join.availableColumns) {
5205
5407
  join.availableColumns.forEach((col) => {
5206
5408
  if (!shouldHideField(col.name, col.type)) {
5409
+ // Use enhanced pivot field naming for pivot tables
5410
+ const columnName = join.isPivotRelationship
5411
+ ? formatPivotFieldName(col.name, join.targetTable, joins, definition)
5412
+ : formatName(col.name);
5413
+
5207
5414
  allColumns.push({
5208
5415
  table: join.targetTable,
5209
5416
  tableName: getTableDisplayName(
@@ -5211,7 +5418,7 @@ const GenericReportImproved = ({
5211
5418
  definition
5212
5419
  ),
5213
5420
  column: col.name,
5214
- columnName: formatName(col.name),
5421
+ columnName: columnName,
5215
5422
  type: col.type,
5216
5423
  });
5217
5424
  }