cloud-ide-element 1.1.86 → 1.1.88

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.
@@ -9634,7 +9634,9 @@ class CideEleDataGridComponent {
9634
9634
  */
9635
9635
  getItemId(item) {
9636
9636
  if (item && typeof item === 'object') {
9637
- const id = item['_id'];
9637
+ // Use trackBy from config, fallback to '_id' if not specified
9638
+ const trackBy = this.mergedConfig().trackBy || '_id';
9639
+ const id = this.getNestedValue(item, trackBy);
9638
9640
  return id ? String(id) : null;
9639
9641
  }
9640
9642
  return null;
@@ -9768,26 +9770,13 @@ class CideEleDataGridComponent {
9768
9770
  valueA = '';
9769
9771
  if (valueB === null || valueB === undefined)
9770
9772
  valueB = '';
9771
- // Handle objects - extract display text for comparison
9773
+ // Handle objects - convert to string for comparison
9774
+ // The consuming component should normalize data before passing to grid
9772
9775
  if (typeof valueA === 'object' && valueA !== null && !Array.isArray(valueA) && !(valueA instanceof Date)) {
9773
- const objA = valueA;
9774
- const displayProps = ['name', 'title', 'label', 'text', 'display_text', 'user_fullname', 'sygms_title'];
9775
- for (const prop of displayProps) {
9776
- if (objA[prop] !== undefined && objA[prop] !== null) {
9777
- valueA = objA[prop];
9778
- break;
9779
- }
9780
- }
9776
+ valueA = String(valueA);
9781
9777
  }
9782
9778
  if (typeof valueB === 'object' && valueB !== null && !Array.isArray(valueB) && !(valueB instanceof Date)) {
9783
- const objB = valueB;
9784
- const displayProps = ['name', 'title', 'label', 'text', 'display_text', 'user_fullname', 'sygms_title'];
9785
- for (const prop of displayProps) {
9786
- if (objB[prop] !== undefined && objB[prop] !== null) {
9787
- valueB = objB[prop];
9788
- break;
9789
- }
9790
- }
9779
+ valueB = String(valueB);
9791
9780
  }
9792
9781
  // Convert to strings for comparison
9793
9782
  const strA = String(valueA || '').toLowerCase();
@@ -9917,13 +9906,12 @@ class CideEleDataGridComponent {
9917
9906
  const childExists = parentChildren.some(child => String(this.getNestedValue(child, primaryKey) || '') === itemId);
9918
9907
  if (!childExists) {
9919
9908
  // Calculate level based on parent - automatically set level key
9920
- const parentLevel = this.getNestedValue(parent, 'level') || 0;
9909
+ const parentLevel = this.getNestedValue(parent, levelKey) || 0;
9921
9910
  const childLevel = parentLevel + 1;
9922
9911
  // Update child item with correct level
9923
9912
  const updatedTreeItem = {
9924
9913
  ...treeItem,
9925
- [levelKey]: childLevel,
9926
- level: childLevel // Always add 'level' property for consistent access
9914
+ [levelKey]: childLevel
9927
9915
  };
9928
9916
  itemMap.set(itemId, updatedTreeItem);
9929
9917
  // Add updated child to parent's children array
@@ -9947,8 +9935,7 @@ class CideEleDataGridComponent {
9947
9935
  // This is a root item - automatically set level to 0
9948
9936
  const updatedRootItem = {
9949
9937
  ...treeItem,
9950
- [levelKey]: 0,
9951
- level: 0 // Always add 'level' property for consistent access
9938
+ [levelKey]: 0
9952
9939
  };
9953
9940
  itemMap.set(itemId, updatedRootItem);
9954
9941
  if (!rootItems.some(rootItem => String(this.getNestedValue(rootItem, primaryKey) || '') === itemId)) {
@@ -10065,10 +10052,17 @@ class CideEleDataGridComponent {
10065
10052
  if (!treeConfig)
10066
10053
  return treeItems;
10067
10054
  const { childrenKey = 'children' } = treeConfig;
10068
- // Flatten all items (both expanded and collapsed) for grouping
10055
+ // Flatten all items for grouping, but preserve the children structure in each parent
10056
+ // This ensures that when we restore, we can show children when parent is expanded
10069
10057
  const flatten = (items) => {
10070
10058
  items.forEach(item => {
10071
- result.push(item);
10059
+ // Create a copy of the item to add to flat list
10060
+ // But preserve the original children array in the item itself
10061
+ const itemCopy = { ...item };
10062
+ result.push(itemCopy);
10063
+ // Recursively flatten children
10064
+ // Note: The children remain in the original item's children array
10065
+ // They are also added to the flat list for grouping
10072
10066
  const children = this.getNestedValue(item, childrenKey) || [];
10073
10067
  if (children.length > 0) {
10074
10068
  flatten(children);
@@ -10086,78 +10080,75 @@ class CideEleDataGridComponent {
10086
10080
  const treeConfig = this.mergedConfig().tree;
10087
10081
  if (!treeConfig)
10088
10082
  return groupedData;
10089
- const { primaryKey = '_id', foreignKey, childrenKey = 'children' } = treeConfig;
10083
+ const { primaryKey, foreignKey, childrenKey = 'children', expandedKey = 'isExpanded', levelKey = 'level' } = treeConfig;
10090
10084
  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
10085
+ const itemMap = new Map();
10086
+ // First pass: build a map of all items and nest children under parents
10117
10087
  groupedData.forEach(item => {
10118
- // If it's a group header, add it directly
10088
+ // If it's a group header, add it directly to result
10119
10089
  if (item?._isGroupHeader) {
10120
10090
  result.push(item);
10121
10091
  return;
10122
10092
  }
10123
10093
  const itemId = String(this.getNestedValue(item, primaryKey) || '');
10124
- if (!itemId || processedItems.has(itemId)) {
10094
+ if (!itemId) {
10095
+ result.push(item);
10125
10096
  return;
10126
10097
  }
10098
+ // Store item in map
10099
+ itemMap.set(itemId, item);
10100
+ // Get parent ID
10127
10101
  const parentIdValue = this.getNestedValue(item, foreignKey);
10128
- // Extract parent ID generically - handle both string IDs and nested objects
10129
10102
  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
- }
10103
+ if (parentId && itemMap.has(parentId)) {
10104
+ // Item has a parent - add to parent's children
10105
+ const parent = itemMap.get(parentId);
10106
+ let children = this.getNestedValue(parent, childrenKey) || [];
10107
+ if (!Array.isArray(children)) {
10108
+ children = [];
10147
10109
  }
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);
10110
+ // Check if already added
10111
+ const exists = children.some(child => String(this.getNestedValue(child, primaryKey) || '') === itemId);
10112
+ if (!exists) {
10113
+ children.push(item);
10114
+ this.setNestedValue(parent, childrenKey, children);
10115
+ this.setNestedValue(parent, 'hasChildren', true);
10152
10116
  }
10153
10117
  }
10154
10118
  else {
10155
- // No parent - add as root
10119
+ // No parent or parent not found - add as root
10156
10120
  result.push(item);
10157
- processedItems.add(itemId);
10158
10121
  }
10159
10122
  });
10160
- return result;
10123
+ // Second pass: flatten the tree structure for display, showing children when parent is expanded
10124
+ const flattenedResult = [];
10125
+ const processItem = (item, depth = 0) => {
10126
+ // If it's a group header, add it directly
10127
+ if (item?._isGroupHeader) {
10128
+ flattenedResult.push(item);
10129
+ return;
10130
+ }
10131
+ // Add the item with its level
10132
+ const itemWithLevel = {
10133
+ ...item,
10134
+ [levelKey]: depth
10135
+ };
10136
+ flattenedResult.push(itemWithLevel);
10137
+ // Check if item has children and is expanded
10138
+ const children = this.getNestedValue(item, childrenKey) || [];
10139
+ const isExpanded = this.getNestedValue(item, expandedKey) || false;
10140
+ // If item is expanded and has children, recursively process children
10141
+ if (isExpanded && Array.isArray(children) && children.length > 0) {
10142
+ children.forEach(child => {
10143
+ processItem(child, depth + 1);
10144
+ });
10145
+ }
10146
+ };
10147
+ // Process all root items (items that were added directly to result)
10148
+ result.forEach(item => {
10149
+ processItem(item);
10150
+ });
10151
+ return flattenedResult;
10161
10152
  }
10162
10153
  /**
10163
10154
  * Toggle expand/collapse state of a tree item with unlimited nesting support
@@ -10184,13 +10175,15 @@ class CideEleDataGridComponent {
10184
10175
  return updatedItem;
10185
10176
  }
10186
10177
  // Check children recursively
10187
- const children = this.getNestedValue(treeItem, 'children') || [];
10178
+ const { childrenKey = 'children' } = treeConfig;
10179
+ const children = this.getNestedValue(treeItem, childrenKey) || [];
10188
10180
  if (children.length > 0) {
10189
10181
  const updatedChildren = updateItemInTree(children);
10190
- return {
10191
- ...treeItem,
10192
- children: updatedChildren
10182
+ const updatedItem = {
10183
+ ...treeItem
10193
10184
  };
10185
+ this.setNestedValue(updatedItem, childrenKey, updatedChildren);
10186
+ return updatedItem;
10194
10187
  }
10195
10188
  return treeItem;
10196
10189
  });
@@ -10414,20 +10407,14 @@ class CideEleDataGridComponent {
10414
10407
  * Get item level in tree
10415
10408
  */
10416
10409
  getItemLevel(item) {
10417
- // Always try to get level from standard 'level' property first (set by transformToTree)
10418
- let level = this.getNestedValue(item, 'level');
10419
- // If not found, try tree config level key
10420
- if (level === undefined || level === null) {
10421
- const treeConfig = this.getTreeConfig();
10422
- if (treeConfig) {
10423
- const { levelKey = 'level' } = treeConfig;
10424
- level = this.getNestedValue(item, levelKey) || 0;
10425
- }
10426
- else {
10427
- level = 0;
10428
- }
10410
+ // Get level from tree config level key
10411
+ const treeConfig = this.getTreeConfig();
10412
+ if (treeConfig) {
10413
+ const { levelKey = 'level' } = treeConfig;
10414
+ const itemLevel = this.getNestedValue(item, levelKey);
10415
+ return itemLevel !== undefined && itemLevel !== null ? itemLevel : 0;
10429
10416
  }
10430
- return level;
10417
+ return 0;
10431
10418
  }
10432
10419
  /**
10433
10420
  * Check if item is expanded
@@ -10630,10 +10617,11 @@ class CideEleDataGridComponent {
10630
10617
  return actualOrder;
10631
10618
  }
10632
10619
  // Final fallback to index-based calculation
10620
+ const trackBy = this.mergedConfig().trackBy || '_id';
10633
10621
  const currentIndex = this.displayedData.findIndex(currentItem => {
10634
10622
  if (item && currentItem && typeof item === 'object' && typeof currentItem === 'object') {
10635
- const itemId = item['_id'];
10636
- const currentItemId = currentItem['_id'];
10623
+ const itemId = this.getNestedValue(item, trackBy);
10624
+ const currentItemId = this.getNestedValue(currentItem, trackBy);
10637
10625
  return itemId && currentItemId && itemId === currentItemId;
10638
10626
  }
10639
10627
  return item === currentItem;
@@ -11204,30 +11192,15 @@ class CideEleDataGridComponent {
11204
11192
  * Tries common field patterns based on column key
11205
11193
  */
11206
11194
  extractValueFromRowForTemplateColumn(row, column) {
11207
- // Try common patterns based on column key
11208
11195
  const rowData = row;
11209
- // If column key is 'details', try common detail/display fields
11210
- if (column.key === 'details' || column.key.includes('detail')) {
11211
- // Try display_text, name, title fields
11212
- if (rowData['fdlds_display_text'])
11213
- return rowData['fdlds_display_text'];
11214
- if (rowData['display_text'])
11215
- return rowData['display_text'];
11216
- if (rowData['name'])
11217
- return rowData['name'];
11218
- if (rowData['title'])
11219
- return rowData['title'];
11220
- }
11221
11196
  // Try to find a field that matches the column key pattern
11222
- // For example, if key is 'details', try 'detail', 'detail_text', etc.
11197
+ // Try variations like: key, key_text, key_name, key_title, key_display
11223
11198
  const keyVariations = [
11224
11199
  column.key,
11225
11200
  `${column.key}_text`,
11226
11201
  `${column.key}_name`,
11227
11202
  `${column.key}_title`,
11228
- `${column.key}_display`,
11229
- `fdlds_${column.key}`,
11230
- `${column.key.replace('details', 'display_text')}`
11203
+ `${column.key}_display`
11231
11204
  ];
11232
11205
  for (const variation of keyVariations) {
11233
11206
  if (rowData[variation] !== undefined && rowData[variation] !== null) {
@@ -11235,12 +11208,14 @@ class CideEleDataGridComponent {
11235
11208
  }
11236
11209
  }
11237
11210
  // Try to find any string field in the row that might be a display value
11211
+ // Skip ID fields using trackBy from config
11212
+ const trackBy = this.mergedConfig().trackBy || '_id';
11238
11213
  for (const key in rowData) {
11239
11214
  if (rowData.hasOwnProperty(key)) {
11240
11215
  const value = rowData[key];
11241
11216
  if (value !== null && value !== undefined && typeof value === 'string' && value.trim() !== '') {
11242
- // Skip common ID fields
11243
- if (!key.includes('_id') && !key.includes('id_')) {
11217
+ // Skip ID fields - use trackBy from config
11218
+ if (key !== trackBy && !key.toLowerCase().includes('id')) {
11244
11219
  return value;
11245
11220
  }
11246
11221
  }
@@ -11250,16 +11225,19 @@ class CideEleDataGridComponent {
11250
11225
  }
11251
11226
  /**
11252
11227
  * Get a stable key for filter value comparison
11253
- * Handles objects by using _id or JSON stringification
11228
+ * Handles objects by using trackBy/primaryKey or JSON stringification
11254
11229
  */
11255
11230
  getFilterValueKey(value) {
11256
11231
  if (value === null || value === undefined)
11257
11232
  return 'null';
11258
11233
  if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
11259
11234
  const obj = value;
11260
- // Use _id if available for object comparison
11261
- if ('_id' in obj && obj['_id'] !== undefined) {
11262
- return `obj_${String(obj['_id'])}`;
11235
+ // Use trackBy or primaryKey from config for object comparison
11236
+ const trackBy = this.mergedConfig().trackBy;
11237
+ const treeConfig = this.mergedConfig().tree;
11238
+ const primaryKey = treeConfig?.primaryKey || trackBy;
11239
+ if (primaryKey && primaryKey in obj && obj[primaryKey] !== undefined) {
11240
+ return `obj_${String(obj[primaryKey])}`;
11263
11241
  }
11264
11242
  // Otherwise use JSON string for comparison
11265
11243
  try {
@@ -11278,34 +11256,21 @@ class CideEleDataGridComponent {
11278
11256
  return value ? 'Yes' : 'No';
11279
11257
  if (value instanceof Date)
11280
11258
  return value.toLocaleDateString();
11281
- // Handle objects - try to extract display text
11259
+ // Handle objects - convert to string generically
11260
+ // The consuming component should normalize data before passing to grid
11282
11261
  if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
11262
+ // Try to get first string property (excluding ID fields)
11283
11263
  const obj = value;
11284
- // Try common display property names in order of preference
11285
- const displayProperties = [
11286
- 'name', 'title', 'label', 'text', 'display_text',
11287
- 'user_fullname', 'fullname', 'full_name',
11288
- 'sygms_title', 'sygmt_title',
11289
- 'user_name', 'username',
11290
- 'email', 'description'
11291
- ];
11292
- for (const prop of displayProperties) {
11293
- if (obj[prop] !== undefined && obj[prop] !== null && typeof obj[prop] !== 'object') {
11294
- return String(obj[prop]);
11295
- }
11296
- }
11297
- // If no display property found, try to get first string property
11298
11264
  for (const key in obj) {
11299
11265
  if (obj.hasOwnProperty(key) && typeof obj[key] === 'string' && obj[key] !== '') {
11300
- return String(obj[key]);
11266
+ // Skip ID fields
11267
+ if (!key.toLowerCase().includes('id') && !key.toLowerCase().includes('_id')) {
11268
+ return String(obj[key]);
11269
+ }
11301
11270
  }
11302
11271
  }
11303
- // Last resort: use _id if available
11304
- if ('_id' in obj && obj['_id'] !== undefined) {
11305
- return String(obj['_id']);
11306
- }
11307
- // If still no value, return a generic label
11308
- return '(Object)';
11272
+ // If no suitable string property found, convert to string
11273
+ return String(value);
11309
11274
  }
11310
11275
  // Handle arrays
11311
11276
  if (Array.isArray(value)) {
@@ -11456,10 +11421,15 @@ class CideEleDataGridComponent {
11456
11421
  * Extract ID from foreign key value generically
11457
11422
  * Handles both string IDs and nested objects (e.g., { _id: "...", name: "..." })
11458
11423
  * @param foreignKeyValue - The foreign key value (can be string, object, or null/undefined)
11459
- * @param primaryKey - The primary key field name (defaults to '_id')
11424
+ * @param primaryKey - The primary key field name (from tree config or defaults to trackBy or '_id')
11460
11425
  * @returns The extracted ID as a string, or empty string if not found
11461
11426
  */
11462
- extractIdFromForeignKey(foreignKeyValue, primaryKey = '_id') {
11427
+ extractIdFromForeignKey(foreignKeyValue, primaryKey) {
11428
+ // Get primary key from tree config or trackBy, fallback to '_id'
11429
+ if (!primaryKey) {
11430
+ const treeConfig = this.mergedConfig().tree;
11431
+ primaryKey = treeConfig?.primaryKey || this.mergedConfig().trackBy || '_id';
11432
+ }
11463
11433
  if (foreignKeyValue === null || foreignKeyValue === undefined) {
11464
11434
  return '';
11465
11435
  }
@@ -11697,12 +11667,12 @@ class CideEleDataGridComponent {
11697
11667
  // If tree is enabled, we need to flatten tree first for grouping, then preserve structure
11698
11668
  const treeConfig = this.mergedConfig().tree;
11699
11669
  if (treeConfig?.enabled) {
11700
- // Flatten tree structure for grouping, but preserve parent-child relationships
11670
+ // Flatten tree structure completely for grouping (all items including children)
11701
11671
  data = this.flattenTreeForGrouping(data);
11702
11672
  }
11703
11673
  // Apply grouping
11704
11674
  data = this.getGroupedData(data, grouped);
11705
- // If tree is enabled, restore tree structure within groups
11675
+ // If tree is enabled, restore tree structure within groups and show children when expanded
11706
11676
  if (treeConfig?.enabled) {
11707
11677
  data = this.restoreTreeStructureInGroups(data);
11708
11678
  }
@@ -11773,36 +11743,10 @@ class CideEleDataGridComponent {
11773
11743
  if (column.formatter) {
11774
11744
  displayValue = this.formatValue(displayValue, column);
11775
11745
  }
11776
- // If display value is still an object, try to extract a meaningful value
11746
+ // If display value is still an object, convert to string
11747
+ // The consuming component should normalize data before passing to grid
11777
11748
  if (typeof displayValue === 'object' && displayValue !== null && !Array.isArray(displayValue) && !(displayValue instanceof Date)) {
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';
11749
+ displayValue = String(displayValue);
11806
11750
  }
11807
11751
  const groupKey = `${groupColumnKey}:${this.getFilterValueKey(rawValue)}`;
11808
11752
  const existing = groups.get(groupKey);
@@ -12088,32 +12032,18 @@ class CideEleDataGridComponent {
12088
12032
  // Handle objects - extract display text
12089
12033
  if (typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)) {
12090
12034
  const obj = value;
12091
- // Try common display properties
12092
- const displayProperties = [
12093
- 'name', 'title', 'label', 'text', 'display_text',
12094
- 'user_fullname', 'fullname', 'full_name',
12095
- 'sygms_title', 'sygmt_title',
12096
- 'user_name', 'username',
12097
- 'email', 'description'
12098
- ];
12099
- for (const prop of displayProperties) {
12100
- if (obj[prop] !== undefined && obj[prop] !== null && typeof obj[prop] !== 'object') {
12101
- return String(obj[prop]);
12102
- }
12103
- }
12104
- // Try first string property
12035
+ // Try to get first string property (excluding ID fields)
12036
+ // The consuming component should normalize data before passing to grid
12105
12037
  for (const key in obj) {
12106
12038
  if (obj.hasOwnProperty(key) && typeof obj[key] === 'string' && obj[key] !== '') {
12107
- if (!key.includes('_id') && !key.includes('id_')) {
12039
+ // Skip ID fields
12040
+ if (!key.toLowerCase().includes('id') && !key.toLowerCase().includes('_id')) {
12108
12041
  return String(obj[key]);
12109
12042
  }
12110
12043
  }
12111
12044
  }
12112
- // Use _id as fallback
12113
- if ('_id' in obj && obj['_id'] !== undefined) {
12114
- return String(obj['_id']);
12115
- }
12116
- return '';
12045
+ // If no suitable string property found, convert to string
12046
+ return String(value);
12117
12047
  }
12118
12048
  // Handle arrays
12119
12049
  if (Array.isArray(value)) {