cloud-ide-element 1.1.84 → 1.1.86

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.
@@ -9390,6 +9390,7 @@ class CideEleDataGridComponent {
9390
9390
  showManageColumnsModal = signal(false, ...(ngDevMode ? [{ debugName: "showManageColumnsModal" }] : [])); // Show manage columns modal
9391
9391
  groupedColumns = signal([], ...(ngDevMode ? [{ debugName: "groupedColumns" }] : [])); // Columns to group by
9392
9392
  expandedGroups = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedGroups" }] : [])); // Expanded group keys
9393
+ hasAutoExpandedGroups = false; // Track if we've auto-expanded groups on initial load
9393
9394
  // Export menu state
9394
9395
  showExportMenu = signal(false, ...(ngDevMode ? [{ debugName: "showExportMenu" }] : [])); // Show/hide export format dropdown
9395
9396
  showFilterDropdown = signal(false, ...(ngDevMode ? [{ debugName: "showFilterDropdown" }] : [])); // Show/hide filter dropdown
@@ -9600,16 +9601,34 @@ class CideEleDataGridComponent {
9600
9601
  if (groupableColumns.length > 0) {
9601
9602
  console.log('🔍 Auto-applying grouping for columns:', groupableColumns);
9602
9603
  this.groupedColumns.set(groupableColumns);
9603
- // Expand all groups by default for each grouped column
9604
- groupableColumns.forEach(columnKey => {
9605
- const column = columns.find(c => c.key === columnKey);
9606
- if (column) {
9607
- this.expandAllGroupsForColumn(columnKey);
9608
- }
9609
- });
9604
+ // Reset auto-expand flag so groups will be expanded on first render
9605
+ this.hasAutoExpandedGroups = false;
9610
9606
  }
9611
9607
  }
9612
9608
  }
9609
+ /**
9610
+ * Check if groups should be auto-expanded (only on initial load)
9611
+ */
9612
+ shouldAutoExpandGroups() {
9613
+ // Auto-expand only once on initial load when default grouping is applied
9614
+ if (this.groupedColumns().length > 0) {
9615
+ // Check if this is default grouping (all groupable columns are grouped)
9616
+ const columns = this.mergedConfig().columns || [];
9617
+ const groupableColumns = columns
9618
+ .filter(col => col.groupable === true)
9619
+ .map(col => col.key);
9620
+ const grouped = this.groupedColumns();
9621
+ // If all groupable columns are grouped, this is likely default grouping
9622
+ const isDefaultGrouping = groupableColumns.length > 0 &&
9623
+ groupableColumns.every(key => grouped.includes(key));
9624
+ // Only auto-expand if it's default grouping and we haven't marked it as done yet
9625
+ if (isDefaultGrouping && !this.hasAutoExpandedGroups) {
9626
+ // Mark as done after first check, but allow all groups in this grouping pass to be expanded
9627
+ return true;
9628
+ }
9629
+ }
9630
+ return false;
9631
+ }
9613
9632
  /**
9614
9633
  * Get the unique identifier for an item
9615
9634
  */
@@ -9878,7 +9897,8 @@ class CideEleDataGridComponent {
9878
9897
  itemsToProcess.forEach(item => {
9879
9898
  const itemId = String(this.getNestedValue(item, primaryKey) || '');
9880
9899
  const parentIdValue = this.getNestedValue(item, foreignKey);
9881
- const parentId = parentIdValue !== null && parentIdValue !== undefined ? String(parentIdValue) : '';
9900
+ // Extract parent ID generically - handle both string IDs and nested objects
9901
+ const parentId = this.extractIdFromForeignKey(parentIdValue, primaryKey);
9882
9902
  const treeItem = itemMap.get(itemId);
9883
9903
  // Skip if already processed
9884
9904
  if (processedItems.has(itemId)) {
@@ -9887,7 +9907,8 @@ class CideEleDataGridComponent {
9887
9907
  if (treeItem && parentId && itemMap.has(parentId)) {
9888
9908
  // This is a child item - check if parent is processed or is a root
9889
9909
  const parent = itemMap.get(parentId);
9890
- const parentParentId = this.getNestedValue(parent, foreignKey);
9910
+ const parentParentIdValue = this.getNestedValue(parent, foreignKey);
9911
+ const parentParentId = this.extractIdFromForeignKey(parentParentIdValue, primaryKey);
9891
9912
  const isParentRoot = !parentParentId || parentParentId === null || parentParentId === undefined;
9892
9913
  if (isParentRoot || processedItems.has(parentId)) {
9893
9914
  // Parent is processed or is root, we can process this child
@@ -9994,7 +10015,8 @@ class CideEleDataGridComponent {
9994
10015
  // Get parent information
9995
10016
  const itemId = String(this.getNestedValue(item, primaryKey) || '');
9996
10017
  const parentIdValue = this.getNestedValue(item, foreignKey);
9997
- const parentId = parentIdValue !== null && parentIdValue !== undefined ? String(parentIdValue) : '';
10018
+ // Extract parent ID generically - handle both string IDs and nested objects
10019
+ const parentId = this.extractIdFromForeignKey(parentIdValue, primaryKey);
9998
10020
  // If no parent, this is a root item (level 0)
9999
10021
  if (!parentId || !itemMap.has(parentId)) {
10000
10022
  return 0;
@@ -10034,6 +10056,109 @@ class CideEleDataGridComponent {
10034
10056
  console.log('flattenTreeForDisplay - result:', result.length, 'items');
10035
10057
  return result;
10036
10058
  }
10059
+ /**
10060
+ * Flatten tree structure for grouping while preserving parent-child relationships
10061
+ */
10062
+ flattenTreeForGrouping(treeItems) {
10063
+ const result = [];
10064
+ const treeConfig = this.mergedConfig().tree;
10065
+ if (!treeConfig)
10066
+ return treeItems;
10067
+ const { childrenKey = 'children' } = treeConfig;
10068
+ // Flatten all items (both expanded and collapsed) for grouping
10069
+ const flatten = (items) => {
10070
+ items.forEach(item => {
10071
+ result.push(item);
10072
+ const children = this.getNestedValue(item, childrenKey) || [];
10073
+ if (children.length > 0) {
10074
+ flatten(children);
10075
+ }
10076
+ });
10077
+ };
10078
+ flatten(treeItems);
10079
+ return result;
10080
+ }
10081
+ /**
10082
+ * Restore tree structure within grouped data
10083
+ * This method processes grouped data and restores parent-child relationships
10084
+ */
10085
+ restoreTreeStructureInGroups(groupedData) {
10086
+ const treeConfig = this.mergedConfig().tree;
10087
+ if (!treeConfig)
10088
+ return groupedData;
10089
+ const { primaryKey = '_id', foreignKey, childrenKey = 'children' } = treeConfig;
10090
+ const result = [];
10091
+ const processedItems = new Set();
10092
+ // Helper to find parent in result array (including nested in group headers)
10093
+ const findParentInResult = (parentId) => {
10094
+ const searchInArray = (items) => {
10095
+ for (const item of items) {
10096
+ // Skip group headers for parent search
10097
+ if (item?._isGroupHeader) {
10098
+ continue;
10099
+ }
10100
+ const itemId = String(this.getNestedValue(item, primaryKey) || '');
10101
+ if (itemId === parentId) {
10102
+ return item;
10103
+ }
10104
+ // Check children recursively
10105
+ const children = this.getNestedValue(item, childrenKey) || [];
10106
+ if (children.length > 0) {
10107
+ const found = searchInArray(children);
10108
+ if (found)
10109
+ return found;
10110
+ }
10111
+ }
10112
+ return null;
10113
+ };
10114
+ return searchInArray(result);
10115
+ };
10116
+ // Process each item in grouped data
10117
+ groupedData.forEach(item => {
10118
+ // If it's a group header, add it directly
10119
+ if (item?._isGroupHeader) {
10120
+ result.push(item);
10121
+ return;
10122
+ }
10123
+ const itemId = String(this.getNestedValue(item, primaryKey) || '');
10124
+ if (!itemId || processedItems.has(itemId)) {
10125
+ return;
10126
+ }
10127
+ const parentIdValue = this.getNestedValue(item, foreignKey);
10128
+ // Extract parent ID generically - handle both string IDs and nested objects
10129
+ const parentId = this.extractIdFromForeignKey(parentIdValue, primaryKey);
10130
+ if (parentId) {
10131
+ // Item has a parent - try to find parent
10132
+ const parent = findParentInResult(parentId);
10133
+ if (parent) {
10134
+ // Parent found - add as child
10135
+ let children = this.getNestedValue(parent, childrenKey) || [];
10136
+ if (!Array.isArray(children)) {
10137
+ children = [];
10138
+ }
10139
+ // Check if already added
10140
+ const exists = children.some(child => String(this.getNestedValue(child, primaryKey) || '') === itemId);
10141
+ if (!exists) {
10142
+ children.push(item);
10143
+ this.setNestedValue(parent, childrenKey, children);
10144
+ this.setNestedValue(parent, 'hasChildren', true);
10145
+ processedItems.add(itemId);
10146
+ }
10147
+ }
10148
+ else {
10149
+ // Parent not found yet - add as root for now (will be moved if parent appears later)
10150
+ result.push(item);
10151
+ processedItems.add(itemId);
10152
+ }
10153
+ }
10154
+ else {
10155
+ // No parent - add as root
10156
+ result.push(item);
10157
+ processedItems.add(itemId);
10158
+ }
10159
+ });
10160
+ return result;
10161
+ }
10037
10162
  /**
10038
10163
  * Toggle expand/collapse state of a tree item with unlimited nesting support
10039
10164
  */
@@ -11327,6 +11452,30 @@ class CideEleDataGridComponent {
11327
11452
  return current && typeof current === 'object' ? current[key] : undefined;
11328
11453
  }, obj);
11329
11454
  }
11455
+ /**
11456
+ * Extract ID from foreign key value generically
11457
+ * Handles both string IDs and nested objects (e.g., { _id: "...", name: "..." })
11458
+ * @param foreignKeyValue - The foreign key value (can be string, object, or null/undefined)
11459
+ * @param primaryKey - The primary key field name (defaults to '_id')
11460
+ * @returns The extracted ID as a string, or empty string if not found
11461
+ */
11462
+ extractIdFromForeignKey(foreignKeyValue, primaryKey = '_id') {
11463
+ if (foreignKeyValue === null || foreignKeyValue === undefined) {
11464
+ return '';
11465
+ }
11466
+ // If it's already a string, return it
11467
+ if (typeof foreignKeyValue === 'string') {
11468
+ return foreignKeyValue.trim();
11469
+ }
11470
+ // If it's an object, extract the ID using the primary key
11471
+ if (typeof foreignKeyValue === 'object' && foreignKeyValue !== null) {
11472
+ const id = foreignKeyValue[primaryKey];
11473
+ if (id !== null && id !== undefined) {
11474
+ return String(id);
11475
+ }
11476
+ }
11477
+ return '';
11478
+ }
11330
11479
  /**
11331
11480
  * Set a nested value in an object using dot notation
11332
11481
  * @param obj The object to modify
@@ -11541,11 +11690,23 @@ class CideEleDataGridComponent {
11541
11690
  console.log('🔍 Using local reordered data for display:', this.localReorderedData.length, 'items');
11542
11691
  return this.localReorderedData;
11543
11692
  }
11544
- const data = this.filteredData();
11693
+ let data = this.filteredData();
11545
11694
  // Apply grouping if any columns are grouped
11546
11695
  const grouped = this.groupedColumns();
11547
11696
  if (grouped.length > 0 && !this.serverSidePagination) {
11548
- return this.getGroupedData(data, grouped);
11697
+ // If tree is enabled, we need to flatten tree first for grouping, then preserve structure
11698
+ const treeConfig = this.mergedConfig().tree;
11699
+ if (treeConfig?.enabled) {
11700
+ // Flatten tree structure for grouping, but preserve parent-child relationships
11701
+ data = this.flattenTreeForGrouping(data);
11702
+ }
11703
+ // Apply grouping
11704
+ data = this.getGroupedData(data, grouped);
11705
+ // If tree is enabled, restore tree structure within groups
11706
+ if (treeConfig?.enabled) {
11707
+ data = this.restoreTreeStructureInGroups(data);
11708
+ }
11709
+ return data;
11549
11710
  }
11550
11711
  // For server-side pagination, the server already provides the correct page of data
11551
11712
  // For client-side pagination, we need to slice the data
@@ -11587,6 +11748,9 @@ class CideEleDataGridComponent {
11587
11748
  const displayValueGetter = column.valueGetter || column.key;
11588
11749
  const groupKeyGetter = column.dataValueGetter || column.valueGetter || column.key;
11589
11750
  const groups = new Map();
11751
+ // Check if tree structure is enabled
11752
+ const treeConfig = this.mergedConfig().tree;
11753
+ const childrenKey = treeConfig?.childrenKey || 'children';
11590
11754
  // Group the data by current column
11591
11755
  data.forEach(row => {
11592
11756
  // Get raw value for grouping key
@@ -11609,9 +11773,36 @@ class CideEleDataGridComponent {
11609
11773
  if (column.formatter) {
11610
11774
  displayValue = this.formatValue(displayValue, column);
11611
11775
  }
11612
- // If display value is still an object, convert to string
11776
+ // If display value is still an object, try to extract a meaningful value
11613
11777
  if (typeof displayValue === 'object' && displayValue !== null && !Array.isArray(displayValue) && !(displayValue instanceof Date)) {
11614
- displayValue = String(displayValue);
11778
+ // Try to get a name/title property from the object
11779
+ const obj = displayValue;
11780
+ if (obj['name']) {
11781
+ displayValue = obj['name'];
11782
+ }
11783
+ else if (obj['title']) {
11784
+ displayValue = obj['title'];
11785
+ }
11786
+ else if (obj['acabrn_name']) {
11787
+ displayValue = obj['acabrn_name'];
11788
+ }
11789
+ else if (obj['acacpm_alise_title']) {
11790
+ displayValue = obj['acacpm_alise_title'];
11791
+ }
11792
+ else if (obj['acacpm_name']) {
11793
+ displayValue = obj['acacpm_name'];
11794
+ }
11795
+ else {
11796
+ displayValue = String(displayValue);
11797
+ }
11798
+ }
11799
+ // Handle null/undefined/empty values for optional fields (e.g., optional specialization)
11800
+ // Use a consistent label for null/undefined values to group them together
11801
+ if (displayValue === null || displayValue === undefined || displayValue === '') {
11802
+ displayValue = 'No Specialization';
11803
+ }
11804
+ if (rawValue === null || rawValue === undefined || rawValue === '') {
11805
+ rawValue = 'No Specialization';
11615
11806
  }
11616
11807
  const groupKey = `${groupColumnKey}:${this.getFilterValueKey(rawValue)}`;
11617
11808
  const existing = groups.get(groupKey);
@@ -11624,6 +11815,9 @@ class CideEleDataGridComponent {
11624
11815
  });
11625
11816
  // Flatten groups into display array
11626
11817
  const result = [];
11818
+ const expanded = this.expandedGroups();
11819
+ const newExpanded = new Set(expanded);
11820
+ const shouldAutoExpand = this.shouldAutoExpandGroups();
11627
11821
  groups.forEach((group, groupKey) => {
11628
11822
  // Add group header row
11629
11823
  const groupHeader = {
@@ -11637,19 +11831,58 @@ class CideEleDataGridComponent {
11637
11831
  _groupPath: level > 0 ? this.buildGroupPath(group.rows[0], groupColumns, level) : []
11638
11832
  };
11639
11833
  result.push(groupHeader);
11640
- // Add group rows if expanded
11641
- if (this.isGroupExpanded(groupKey)) {
11642
- // If there are more grouping levels, recursively group the rows
11834
+ // Auto-expand groups by default if they're not explicitly collapsed
11835
+ // This ensures groups are expanded on initial load
11836
+ const isExpanded = expanded.has(groupKey);
11837
+ if (shouldAutoExpand && !isExpanded) {
11838
+ // Add to expanded set if auto-expanding
11839
+ newExpanded.add(groupKey);
11840
+ }
11841
+ // Show group rows if expanded or should be auto-expanded
11842
+ if (isExpanded || (shouldAutoExpand && !isExpanded)) {
11843
+ // Process rows while preserving tree structure
11844
+ const processedRows = [];
11845
+ group.rows.forEach(row => {
11846
+ // Check if this row has children (tree structure)
11847
+ const children = treeConfig?.enabled ? this.getNestedValue(row, childrenKey) : undefined;
11848
+ if (children && Array.isArray(children) && children.length > 0) {
11849
+ // This row has children - preserve tree structure
11850
+ const processedRow = { ...row };
11851
+ // Recursively process children if there are more grouping levels
11852
+ if (level + 1 < groupColumns.length) {
11853
+ // Apply grouping to children
11854
+ const groupedChildren = this.groupDataRecursive(children, groupColumns, level + 1);
11855
+ // Update the row with grouped children
11856
+ this.setNestedValue(processedRow, childrenKey, groupedChildren);
11857
+ }
11858
+ else {
11859
+ // No more grouping levels, but preserve children structure
11860
+ this.setNestedValue(processedRow, childrenKey, children);
11861
+ }
11862
+ processedRows.push(processedRow);
11863
+ }
11864
+ else {
11865
+ // Regular row without children
11866
+ processedRows.push(row);
11867
+ }
11868
+ });
11869
+ // If there are more grouping levels, recursively group the processed rows
11643
11870
  if (level + 1 < groupColumns.length) {
11644
- const nestedGroups = this.groupDataRecursive(group.rows, groupColumns, level + 1);
11871
+ const nestedGroups = this.groupDataRecursive(processedRows, groupColumns, level + 1);
11645
11872
  result.push(...nestedGroups);
11646
11873
  }
11647
11874
  else {
11648
- // Last level, just add the rows
11649
- result.push(...group.rows);
11875
+ // Last level, add the processed rows (with preserved tree structure)
11876
+ result.push(...processedRows);
11650
11877
  }
11651
11878
  }
11652
11879
  });
11880
+ // Update expanded groups set if we auto-expanded any
11881
+ if (shouldAutoExpand && newExpanded.size > expanded.size) {
11882
+ this.expandedGroups.set(newExpanded);
11883
+ // Mark that we've auto-expanded groups so we don't do it again on subsequent renders
11884
+ this.hasAutoExpandedGroups = true;
11885
+ }
11653
11886
  return result;
11654
11887
  }
11655
11888
  /**