@refinitiv-ui/efx-grid 6.0.16 → 6.0.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. package/lib/grid/index.js +1 -1
  2. package/lib/rt-grid/dist/rt-grid.js +177 -64
  3. package/lib/rt-grid/dist/rt-grid.min.js +1 -1
  4. package/lib/rt-grid/es6/ColumnDefinition.js +2 -1
  5. package/lib/rt-grid/es6/Grid.d.ts +12 -2
  6. package/lib/rt-grid/es6/Grid.js +152 -54
  7. package/lib/rt-grid/es6/RowDefinition.js +4 -0
  8. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.d.ts +4 -4
  9. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +344 -185
  10. package/lib/tr-grid-column-stack/es6/ColumnStack.d.ts +7 -1
  11. package/lib/tr-grid-column-stack/es6/ColumnStack.js +164 -147
  12. package/lib/tr-grid-filter-input/es6/FilterInput.d.ts +1 -0
  13. package/lib/tr-grid-filter-input/es6/FilterInput.js +27 -0
  14. package/lib/tr-grid-in-cell-editing/es6/InCellEditing.d.ts +44 -43
  15. package/lib/tr-grid-in-cell-editing/es6/InCellEditing.js +202 -497
  16. package/lib/tr-grid-row-grouping/es6/RowGrouping.d.ts +40 -40
  17. package/lib/types/es6/ColumnGrouping.d.ts +4 -4
  18. package/lib/types/es6/ColumnStack.d.ts +7 -1
  19. package/lib/types/es6/Core/data/Segment.d.ts +3 -3
  20. package/lib/types/es6/Core/data/SegmentCollection.d.ts +1 -1
  21. package/lib/types/es6/InCellEditing.d.ts +44 -43
  22. package/lib/types/es6/RealtimeGrid/ColumnDefinition.d.ts +10 -0
  23. package/lib/types/es6/RealtimeGrid/FieldDefinition.d.ts +6 -0
  24. package/lib/types/es6/RealtimeGrid/Grid.d.ts +13 -1
  25. package/lib/types/es6/RealtimeGrid/RowDefinition.d.ts +4 -0
  26. package/lib/types/es6/RealtimeGrid/SnapshotFiller.d.ts +1 -0
  27. package/lib/types/es6/RowColoring.d.ts +17 -15
  28. package/lib/types/es6/RowFiltering.d.ts +30 -29
  29. package/lib/types/es6/RowGrouping.d.ts +40 -40
  30. package/lib/versions.json +5 -5
  31. package/package.json +1 -1
@@ -31,6 +31,7 @@ var ColumnGroupingPlugin = function ColumnGroupingPlugin(options) {
31
31
  t._onColumnChanged = t._onColumnChanged.bind(t);
32
32
  t._onColumnAdded = t._onColumnAdded.bind(t);
33
33
  t._onColumnMoved = t._onColumnMoved.bind(t);
34
+ t._onColumnRemoved = t._onColumnRemoved.bind(t);
34
35
  t._requestApplyAddChildGroup = t._requestApplyAddChildGroup.bind(this);
35
36
  t._onPostSectionRender = t._onPostSectionRender.bind(t);
36
37
  t._onBeforeColumnBoundUpdate = t._onBeforeColumnBoundUpdate.bind(t);
@@ -60,6 +61,11 @@ ColumnGroupingPlugin.prototype._groupMap;
60
61
  * @private
61
62
  */
62
63
  ColumnGroupingPlugin.prototype._childToParent;
64
+ /** @type {!Object.<string, ColumnGroupingPlugin~GroupDefinition>}
65
+ * @description A map of visible group id to group defintion
66
+ * @private
67
+ */
68
+ ColumnGroupingPlugin.prototype._visibleGroupMap;
63
69
  /** @type {number}
64
70
  * @private
65
71
  */
@@ -99,20 +105,6 @@ ColumnGroupingPlugin._getTooltip = function (groupingOptions) {
99
105
  }
100
106
  return title;
101
107
  };
102
- /** Prevent built-in config
103
- * @public
104
- * @param {string} optionName
105
- * @param {Object} optionValue
106
- * @return {*}
107
- */
108
- ColumnGroupingPlugin.prototype.beforeProcessOption = function (optionName, optionValue) {
109
- if (optionName === "columnGroups") {
110
- this._legacyColumnGroups = optionValue;
111
- return false; // eslint-disable-line
112
- }
113
-
114
- return; // eslint-disable-line
115
- };
116
108
  /** @public
117
109
  * @return {string}
118
110
  */
@@ -142,7 +134,7 @@ ColumnGroupingPlugin.prototype.initialize = function (host, options) {
142
134
  if (this._hosts.length === 1) {
143
135
  host.listen("columnAdded", this._onColumnAdded);
144
136
  host.listen("columnMoved", this._onColumnMoved);
145
- host.listen("columnRemoved", this._onColumnChanged);
137
+ host.listen("columnRemoved", this._onColumnRemoved);
146
138
  host.listen("columnVisibilityChanged", this._onColumnChanged);
147
139
  host.listen("postSectionRender", this._onPostSectionRender);
148
140
  host.listen("beforeColumnBoundUpdate", this._onBeforeColumnBoundUpdate);
@@ -162,6 +154,20 @@ ColumnGroupingPlugin.prototype.initialize = function (host, options) {
162
154
  }
163
155
  // TODO: wrong render group in hide/show column
164
156
  };
157
+ /** Prevent built-in config
158
+ * @public
159
+ * @param {string} optionName
160
+ * @param {Object} optionValue
161
+ * @return {*}
162
+ */
163
+ ColumnGroupingPlugin.prototype.beforeProcessOption = function (optionName, optionValue) {
164
+ if (optionName === "columnGroups") {
165
+ this._legacyColumnGroups = optionValue;
166
+ return false; // eslint-disable-line
167
+ }
168
+
169
+ return; // eslint-disable-line
170
+ };
165
171
  /**
166
172
  * @protected
167
173
  * @ignore
@@ -180,7 +186,7 @@ ColumnGroupingPlugin.prototype.unload = function (host) {
180
186
  this._hosts.splice(at, 1);
181
187
  host.unlisten("columnAdded", this._onColumnChanged);
182
188
  host.unlisten("columnMoved", this._onColumnMoved);
183
- host.unlisten("columnRemoved", this._onColumnChanged);
189
+ host.unlisten("columnRemoved", this._onColumnRemoved);
184
190
  host.unlisten("postSectionRender", this._onPostSectionRender);
185
191
  host.unlisten("beforeColumnBoundUpdate", this._onBeforeColumnBoundUpdate);
186
192
  if (!this._hosts.length) {
@@ -205,8 +211,20 @@ ColumnGroupingPlugin.prototype.config = function (options) {
205
211
  }
206
212
  var extOptions = options["columnGrouping"];
207
213
  if (Array.isArray(extOptions)) {
208
- this._groupDefs = extOptions.filter(ColumnGroupingPlugin._isValidGroup).map(ColumnGroupingPlugin._cloneObject);
214
+ var groupDefs = extOptions.map(ColumnGroupingPlugin._cloneObject);
215
+ this._groupDefs = groupDefs.filter(ColumnGroupingPlugin._isValidGroup);
209
216
  }
217
+ var columns = options["columns"];
218
+ if (!columns) {
219
+ return;
220
+ }
221
+ var len = columns.length;
222
+ for (var i = 0; i < len; ++i) {
223
+ this._setColumnGrouping(i, {
224
+ id: columns[i].id
225
+ }); // used for columnRemoved event
226
+ }
227
+
210
228
  this._migrateLegacyStructure(options["columns"]);
211
229
  };
212
230
  /** @public
@@ -218,13 +236,26 @@ ColumnGroupingPlugin.prototype.getConfigObject = function (gridOptions) {
218
236
 
219
237
  // TODO: Handle legacyRender method that has been migrated
220
238
  var columnGroupingDefs = this.getGroupDefinitions();
221
- for (var i = 0; i < columnGroupingDefs.length; i++) {
222
- columnGroupingDefs[i] = this._groupMap[columnGroupingDefs[i].id];
223
- }
224
239
  obj.columnGrouping = columnGroupingDefs;
225
240
  return obj;
226
241
  };
227
242
 
243
+ /** @private
244
+ * @param {number} colIndex
245
+ * @param {Object} data
246
+ */
247
+ ColumnGroupingPlugin.prototype._setColumnGrouping = function (colIndex, data) {
248
+ var colData = this._newColumnData(colIndex);
249
+ colData["columnGrouping"] = data;
250
+ };
251
+ /** @private
252
+ * @param {number} colIndex
253
+ * @return {Object}
254
+ */
255
+ ColumnGroupingPlugin.prototype._getColumnGrouping = function (colIndex) {
256
+ return this._getColumnOption(colIndex, "columnGrouping");
257
+ };
258
+
228
259
  /** Legacy group structure from composite grid will be converted to the new structure
229
260
  * @private
230
261
  * @param {Object.<string, Array>} objMap
@@ -274,7 +305,7 @@ ColumnGroupingPlugin.prototype._migrateLegacyStructure = function (colModels) {
274
305
 
275
306
  // Add new definitions and structure to the given legacy objects
276
307
  for (i = 0; i < groupCount; ++i) {
277
- groupDef = legacyColumnGroups[i];
308
+ groupDef = ColumnGroupingPlugin._cloneObject(legacyColumnGroups[i]);
278
309
  if (groupDef && groupDef.id) {
279
310
  // WARNING: Modify user's object
280
311
  var childAry = groupMap[groupDef.id];
@@ -286,6 +317,7 @@ ColumnGroupingPlugin.prototype._migrateLegacyStructure = function (colModels) {
286
317
  this._groupDefs.push(groupDef);
287
318
  }
288
319
  }
320
+ this._groupDefs = this._groupDefs.filter(ColumnGroupingPlugin._isValidGroup);
289
321
  };
290
322
 
291
323
  /** Consolidate and process configuration. Force rerendering on column adding, removing, moving, initializaing, and run-time API execution.
@@ -313,6 +345,7 @@ ColumnGroupingPlugin.prototype._applyGrouping = function () {
313
345
  for (r = 0; r < rowCount; r++) {
314
346
  cell = section.getCell(c, r, false);
315
347
  if (cell) {
348
+ cell.reset();
316
349
  cell.removeClass("no-sort");
317
350
  cell.removeAttribute("group-id");
318
351
  }
@@ -333,6 +366,173 @@ ColumnGroupingPlugin.prototype._applyGrouping = function () {
333
366
  }
334
367
  }
335
368
  };
369
+ /** @private
370
+ */
371
+ ColumnGroupingPlugin.prototype._evaluateGroupStructure = function () {
372
+ // Clear existing group structure
373
+ var groupMap = this._groupMap = {};
374
+ var childToParent = this._childToParent = {};
375
+ var visibleGroupMap = this._visibleGroupMap = {};
376
+ this._maxDepth = -1;
377
+
378
+ // Flatten tree structure to simple dictionary
379
+ var groupDefs = this._groupDefs;
380
+ var len = groupDefs.length;
381
+ var i;
382
+ for (i = 0; i < len; i++) {
383
+ this._flattenGroupDefs(groupDefs[i], groupDefs);
384
+ }
385
+
386
+ // Create group map
387
+ var groupDef;
388
+ len = groupDefs.length; // length can be changed after flattening
389
+ for (i = 0; i < len; i++) {
390
+ groupDef = groupDefs[i];
391
+ groupMap[groupDef.id] = groupDef;
392
+
393
+ // Clone group definitions for rendering
394
+ visibleGroupMap[groupDef.id] = ColumnGroupingPlugin._cloneObject(groupDef);
395
+ visibleGroupMap[groupDef.id].children = groupDef.children.slice();
396
+ }
397
+
398
+ // Create child to parent map
399
+ var gid, children, member;
400
+ for (gid in groupMap) {
401
+ groupDef = groupMap[gid];
402
+ children = groupDef.children;
403
+ for (i = 0; i < children.length; i++) {
404
+ member = children[i];
405
+ childToParent[member] = gid;
406
+ }
407
+ }
408
+
409
+ // Apply a parent id to group definition to make it easier to find depth
410
+ var parentId;
411
+ for (gid in visibleGroupMap) {
412
+ parentId = childToParent[gid];
413
+ if (parentId) {
414
+ visibleGroupMap[gid].parent = parentId;
415
+ groupMap[gid].parent = parentId;
416
+ }
417
+ }
418
+
419
+ // Filter invisible groups out
420
+ var rootGroup = [];
421
+ for (gid in visibleGroupMap) {
422
+ groupDef = visibleGroupMap[gid];
423
+ if (this._findGroupTreeDepth(groupDef, 1) === 1) {
424
+ rootGroup.push(groupDef);
425
+ }
426
+ }
427
+ len = rootGroup.length;
428
+ for (i = 0; i < len; i++) {
429
+ this._verifySingleChild(rootGroup[i]);
430
+ }
431
+
432
+ // Determine the depth of each group
433
+ var depth;
434
+ for (gid in visibleGroupMap) {
435
+ groupDef = visibleGroupMap[gid];
436
+ depth = this._findGroupTreeDepth(groupDef, 1);
437
+ groupDef["onRow"] = depth - 1;
438
+ }
439
+
440
+ // Calculate the maximum depth
441
+ var maxDepth = -1;
442
+ for (gid in visibleGroupMap) {
443
+ groupDef = visibleGroupMap[gid];
444
+ depth = groupDef["onRow"];
445
+ if (depth > maxDepth) {
446
+ maxDepth = depth;
447
+ }
448
+ }
449
+ this._maxDepth = maxDepth + 1; // Column header depth = maximum group depth + 1
450
+ };
451
+
452
+ /** Flatten group definition structure by using group ID instead of nested group definitions.
453
+ * @private
454
+ * @param {Object} groupDef
455
+ * @param {Array} groupDefs
456
+ */
457
+ ColumnGroupingPlugin.prototype._flattenGroupDefs = function (groupDef, groupDefs) {
458
+ if (groupDef && groupDef.children) {
459
+ var children = groupDef.children;
460
+ var member, groupId;
461
+ for (var i = 0; i < children.length; i++) {
462
+ member = children[i];
463
+ if (typeof member !== "string") {
464
+ // member is nested group definition
465
+ groupId = member.id;
466
+ if (groupId) {
467
+ children[i] = groupId; // Use group ID instead of nested group definition
468
+ if (groupDefs.indexOf(member) < 0) {
469
+ groupDefs.push(member);
470
+ }
471
+ this._flattenGroupDefs(member, groupDefs);
472
+ }
473
+ }
474
+ }
475
+ }
476
+ };
477
+
478
+ /** @private
479
+ * @param {Object} groupDef
480
+ * @param {number} currentDepth
481
+ * @return {number}
482
+ */
483
+ ColumnGroupingPlugin.prototype._findGroupTreeDepth = function (groupDef, currentDepth) {
484
+ var parentId = groupDef["parent"];
485
+ var parentNode = this._visibleGroupMap[parentId];
486
+ if (parentNode) {
487
+ return this._findGroupTreeDepth(parentNode, currentDepth + 1);
488
+ } else {
489
+ return currentDepth;
490
+ }
491
+ };
492
+
493
+ /** @private
494
+ * @param {Object} groupDef
495
+ * @return {boolean}
496
+ */
497
+ ColumnGroupingPlugin.prototype._verifySingleChild = function (groupDef) {
498
+ var children = groupDef.children;
499
+ var visibleChildCount = 0;
500
+ var visibleChildGroupCount = 0;
501
+ var invisibleMembers = [];
502
+ var i, member;
503
+ for (i = 0; i < children.length; i++) {
504
+ member = children[i];
505
+ if (this._visibleGroupMap[member]) {
506
+ if (this._verifySingleChild(this._visibleGroupMap[member])) {
507
+ ++visibleChildCount;
508
+ ++visibleChildGroupCount;
509
+ } else {
510
+ invisibleMembers.push(member);
511
+ }
512
+ } else {
513
+ if (this._getColumnIndexById(member) > -1) {
514
+ ++visibleChildCount;
515
+ } else {
516
+ invisibleMembers.push(member);
517
+ }
518
+ }
519
+ }
520
+
521
+ // Remove invisible members, keep only visible members
522
+ if (invisibleMembers.length) {
523
+ for (i = 0; i < invisibleMembers.length; i++) {
524
+ member = invisibleMembers[i];
525
+ groupDef.children.splice(children.indexOf(member), 1);
526
+ }
527
+ }
528
+ if (visibleChildCount > 1 || visibleChildGroupCount > 1) {
529
+ return true;
530
+ } else {
531
+ delete this._visibleGroupMap[groupDef.id];
532
+ return false;
533
+ }
534
+ };
535
+
336
536
  /** Set a timer to call applyGrouping only once to avoid performance issue
337
537
  * @private
338
538
  */
@@ -354,7 +554,14 @@ ColumnGroupingPlugin.prototype._applyNearestGrouping = function (colIndex) {
354
554
  var groupLeftIds = this.getGroupIds(colIndexLeft);
355
555
  var groupRightIds = this.getGroupIds(colIndexRight);
356
556
  if (groupLeftIds && groupRightIds) {
357
- var i, j, groupLeftId, groupRightId, field;
557
+ var colId = this.getColumnId(colIndex);
558
+ var groupId = this._childToParent[colId];
559
+ if (groupId) {
560
+ if (groupLeftIds.indexOf(groupId) > -1 || groupRightIds.indexOf(groupId) > -1) {
561
+ return;
562
+ }
563
+ }
564
+ var i, j, groupLeftId, groupRightId;
358
565
  var found = false;
359
566
  for (i = 0; i < groupLeftIds.length; i++) {
360
567
  groupLeftId = groupLeftIds[i];
@@ -362,12 +569,15 @@ ColumnGroupingPlugin.prototype._applyNearestGrouping = function (colIndex) {
362
569
  groupRightId = groupRightIds[j];
363
570
  if (groupLeftId === groupRightId) {
364
571
  // found same Id between group
365
- field = this.getColumnId(colIndex);
366
- this._addGroupChild(field, groupRightId);
572
+
573
+ // This method modifies the group definition and outdates the group structure.
574
+ // It is necessary to recalculate group structure manually.
575
+ this._addGroupChild(colId, groupRightId);
367
576
  found = true;
368
577
  }
369
578
  }
370
579
  if (found) {
580
+ this._evaluateGroupStructure();
371
581
  break;
372
582
  }
373
583
  }
@@ -404,7 +614,7 @@ ColumnGroupingPlugin.prototype._spanGroupVertically = function (titleSection) {
404
614
  */
405
615
  ColumnGroupingPlugin.prototype._spanGroupHorizontally = function (titleSection) {
406
616
  var section = titleSection;
407
- var groupTable = this._groupMap;
617
+ var groupTable = this._visibleGroupMap;
408
618
 
409
619
  // Span column of column group
410
620
  for (var id in groupTable) {
@@ -427,7 +637,7 @@ ColumnGroupingPlugin.prototype._spanGroupHorizontally = function (titleSection)
427
637
  */
428
638
  ColumnGroupingPlugin.prototype._renderGroups = function () {
429
639
  var hostCount = this._hosts.length;
430
- var groupMap = this._groupMap;
640
+ var groupMap = this._visibleGroupMap;
431
641
  for (var i = 0; i < hostCount; ++i) {
432
642
  var section = this._hosts[i].getSection("title");
433
643
  if (!section) {
@@ -515,12 +725,20 @@ ColumnGroupingPlugin.prototype._applyTimeSeries = function (e) {
515
725
  var parentName = tsParentDef.getName();
516
726
  var parentId = tsParentDef.getId();
517
727
  var groupId = "timeSerieGroup_" + parentId;
518
- var getGroupDefintion = this.getGroupDefinition(groupId);
519
- if (getGroupDefintion) {
728
+ var groupDef = this._groupMap[groupId];
729
+ if (groupDef) {
520
730
  // add children time series field to parent
731
+ var dirty = false;
732
+ var child;
521
733
  for (i = 0; i < children.length; i++) {
522
- var child = children[i];
523
- this._addGroupChild(child, groupId);
734
+ child = children[i];
735
+
736
+ // This method modifies the group definition and outdates the group structure.
737
+ // It is necessary to recalculate group structure manually.
738
+ dirty |= this._addGroupChild(child, groupId);
739
+ }
740
+ if (dirty) {
741
+ this._evaluateGroupStructure();
524
742
  }
525
743
  } else {
526
744
  // create new group
@@ -558,29 +776,52 @@ ColumnGroupingPlugin.prototype._onColumnMoved = function (e) {
558
776
  var toColIndex = e.toColIndex;
559
777
  var colId = this.getColumnId(toColIndex);
560
778
  var groupId = this._childToParent[colId];
561
- var colIndexLeft = toColIndex - 1;
562
- var colIndexRight = toColIndex + 1;
563
- var colIdLeft = this.getColumnId(colIndexLeft);
564
- var colIdRight = this.getColumnId(colIndexRight);
565
- var groupIdLeft = this._childToParent[colIdLeft];
566
- var groupIdRight = this._childToParent[colIdRight];
567
- if (groupId != groupIdLeft && groupId != groupIdRight) {
568
- // remove column from previous group
569
- if (groupId) {
570
- var groupChild = this.getGroupChildren(groupId);
571
- var removeIndex = groupChild.indexOf(colId);
779
+ if (groupId) {
780
+ var colIdLeft = this.getColumnId(toColIndex - 1);
781
+ var colIdRight = this.getColumnId(toColIndex + 1);
782
+ var groupIdLeft = this._childToParent[colIdLeft];
783
+ var groupIdRight = this._childToParent[colIdRight];
784
+ if (groupId != groupIdLeft && groupId != groupIdRight) {
785
+ // Remove column from previous group
786
+ var children = this.getGroupChildren(groupId);
787
+ var removeIndex = children.indexOf(colId);
572
788
  if (removeIndex > -1) {
573
- groupChild.splice(removeIndex, 1);
789
+ children.splice(removeIndex, 1);
574
790
  }
575
- this.setGroupChildren(groupId, groupChild);
791
+ this.setGroupChildren(groupId, children);
576
792
  }
577
- this._applyNearestGrouping(toColIndex);
578
793
  }
794
+ this._applyNearestGrouping(toColIndex);
579
795
  this._requestApplyGrouping();
580
796
  };
581
797
  /** @private
582
798
  * @param {Object} e
583
799
  */
800
+ ColumnGroupingPlugin.prototype._onColumnRemoved = function (e) {
801
+ var colData = e.columnData;
802
+ if (colData && colData.columnGrouping) {
803
+ var colId = colData.columnGrouping.id;
804
+ var groupId = this._childToParent[colId];
805
+ if (groupId) {
806
+ var groupDef = this._groupMap[groupId];
807
+ if (groupDef) {
808
+ var children = groupDef.children;
809
+ var index = children.indexOf(colId);
810
+ if (index > -1) {
811
+ if (children.length < 3) {
812
+ this._groupDefs.splice(this._groupDefs.indexOf(groupDef), 1);
813
+ } else {
814
+ children.splice(index, 1);
815
+ }
816
+ this._requestApplyGrouping();
817
+ }
818
+ }
819
+ }
820
+ }
821
+ };
822
+ /** @private
823
+ * @param {Object} e
824
+ */
584
825
  ColumnGroupingPlugin.prototype._onBeforeColumnBoundUpdate = function (e) {
585
826
  var selectedColumns = e.selectedColumns;
586
827
  var parentMap = this._childToParent;
@@ -668,7 +909,13 @@ ColumnGroupingPlugin.prototype._onBeforeColumnBoundUpdate = function (e) {
668
909
  ColumnGroupingPlugin.prototype.addColumnToGroup = function (column, groupId, colIndex) {
669
910
  if (!column || !groupId) return;
670
911
  var columnIndex = colIndex || this.getColumnCount();
671
- this._addGroupChild(column.id, groupId);
912
+
913
+ // This method modifies the group definition and outdates the group structure.
914
+ // It is necessary to recalculate group structure manually.
915
+ if (this._addGroupChild(column.id, groupId)) {
916
+ this._evaluateGroupStructure(); // To prevent event handler from using outdated group structure
917
+ }
918
+
672
919
  if (this._realTimeGrid) {
673
920
  this._realTimeGrid.insertColumn(column, columnIndex);
674
921
  } else if (this._compositeGrid) {
@@ -685,7 +932,7 @@ ColumnGroupingPlugin.prototype.addGroup = function (groupDef) {
685
932
  if (groupDef && groupDef.id) {
686
933
  var curDef = this.getGroupDefinition(groupDef.id);
687
934
  if (!curDef) {
688
- var newGroupDef = cloneObject(groupDef);
935
+ var newGroupDef = ColumnGroupingPlugin._cloneObject(groupDef);
689
936
  this._groupDefs.push(newGroupDef);
690
937
  this._applyGrouping();
691
938
  return true;
@@ -721,6 +968,7 @@ ColumnGroupingPlugin.prototype.removeGroup = function (groupId) {
721
968
  */
722
969
  ColumnGroupingPlugin.prototype.setGroupDefinitions = function (groupDefs) {
723
970
  if (Array.isArray(groupDefs)) {
971
+ groupDefs = groupDefs.map(ColumnGroupingPlugin._cloneObject);
724
972
  groupDefs = groupDefs.filter(ColumnGroupingPlugin._isValidGroup);
725
973
  if (!groupDefs.length) {
726
974
  groupDefs = null;
@@ -744,10 +992,6 @@ ColumnGroupingPlugin.prototype.setGroupDefinitions = function (groupDefs) {
744
992
  ColumnGroupingPlugin._isValidGroup = function (groupDef) {
745
993
  if (groupDef) {
746
994
  if (groupDef.id) {
747
- if (!groupDef.children) {
748
- groupDef.children = []; // WARNING: Modify user's object
749
- }
750
-
751
995
  return true;
752
996
  }
753
997
  }
@@ -759,7 +1003,13 @@ ColumnGroupingPlugin._isValidGroup = function (groupDef) {
759
1003
  * @return {boolean}
760
1004
  */
761
1005
  ColumnGroupingPlugin._cloneObject = function (obj) {
762
- return cloneObject(obj);
1006
+ var newObj = cloneObject(obj);
1007
+ if (Array.isArray(newObj.children)) {
1008
+ newObj.children = newObj.children;
1009
+ } else {
1010
+ newObj.children = [];
1011
+ }
1012
+ return newObj;
763
1013
  };
764
1014
  /** Get a shallow copy of all existing group definitions
765
1015
  * @public
@@ -777,6 +1027,7 @@ ColumnGroupingPlugin.prototype.setGroupDefinition = function (groupId, newDef) {
777
1027
  var curDef = this.getGroupDefinition(groupId);
778
1028
  if (curDef) {
779
1029
  var at = this._groupDefs.indexOf(curDef);
1030
+ newDef = ColumnGroupingPlugin._cloneObject(newDef);
780
1031
  newDef.id = groupId;
781
1032
  this._groupDefs[at] = newDef;
782
1033
  this._applyGrouping();
@@ -801,6 +1052,7 @@ ColumnGroupingPlugin.prototype.setGroupChildren = function (groupId, newChildLis
801
1052
  var groupDef = this.getGroupDefinition(groupId);
802
1053
  if (groupDef) {
803
1054
  if (Array.isArray(newChildList)) {
1055
+ groupDef.aaa = 0; // TODO: for testing, need to be removed
804
1056
  groupDef.children = newChildList.slice();
805
1057
  this._applyGrouping();
806
1058
  } else if (!newChildList && groupDef.children.length) {
@@ -816,9 +1068,8 @@ ColumnGroupingPlugin.prototype.setGroupChildren = function (groupId, newChildLis
816
1068
  ColumnGroupingPlugin.prototype.getGroupChildren = function (groupId) {
817
1069
  var groupDef = this.getGroupDefinition(groupId);
818
1070
  if (groupDef) {
819
- return groupDef.children.slice(); // Shallow copy
1071
+ return groupDef.children;
820
1072
  }
821
-
822
1073
  return null;
823
1074
  };
824
1075
 
@@ -832,11 +1083,11 @@ ColumnGroupingPlugin.prototype.getChildColumnIndices = function (groupId) {
832
1083
  if (group) {
833
1084
  var colIds = this._getGroupMembers(group);
834
1085
  var colIndices = [];
835
- var id;
1086
+ var index;
836
1087
  for (var i = 0; i < colIds.length; i++) {
837
- id = this._getColumnIndexById(colIds[i]);
838
- if (id > -1) {
839
- colIndices.push(id);
1088
+ index = this.getColumnIndex(colIds[i]);
1089
+ if (index > -1) {
1090
+ colIndices.push(index);
840
1091
  }
841
1092
  }
842
1093
  return colIndices.sort();
@@ -860,7 +1111,7 @@ ColumnGroupingPlugin.prototype.getGroupIds = function (colRef) {
860
1111
  var groupIds = [groupId];
861
1112
  var group = this._groupMap[groupId];
862
1113
  while (group && group.parent) {
863
- group = this.getGroupDefinition(group.parent);
1114
+ group = this._groupMap[group.parent];
864
1115
  if (group) {
865
1116
  groupIds.push(group.id);
866
1117
  }
@@ -886,7 +1137,7 @@ ColumnGroupingPlugin.prototype.getMaxGroupLevel = function () {
886
1137
  * @return {number}
887
1138
  */
888
1139
  ColumnGroupingPlugin.prototype.getGroupLevel = function (groupId) {
889
- var group = this._groupMap[groupId];
1140
+ var group = this._visibleGroupMap[groupId];
890
1141
  if (group) {
891
1142
  return group.onRow;
892
1143
  }
@@ -927,106 +1178,11 @@ ColumnGroupingPlugin.prototype._getRootGroup = function (groupId) {
927
1178
  }
928
1179
  var group = this._groupMap[groupId];
929
1180
  while (group.parent) {
930
- group = this.getGroupDefinition(group.parent);
1181
+ group = this._groupMap[group.parent];
931
1182
  }
932
1183
  return group;
933
1184
  };
934
1185
 
935
- /** @private
936
- */
937
- ColumnGroupingPlugin.prototype._evaluateGroupStructure = function () {
938
- // Clear existing group structure
939
- this._groupMap = {};
940
- this._childToParent = {};
941
- this._maxDepth = -1;
942
-
943
- // Flatten tree to dictionary
944
- var columnGroups = this._groupDefs;
945
- var inUsedGroup = {};
946
- var node;
947
- for (var cg = 0; cg < columnGroups.length; cg++) {
948
- // node can be a root or child
949
- node = columnGroups[cg];
950
- // skip tree that don't have a child
951
- if (node.children && node.children.length) {
952
- this._flattenTree(node, inUsedGroup);
953
- }
954
- }
955
- var id;
956
- // Apply parent id to columnGroup for easy to find depth
957
- for (id in this._groupMap) {
958
- node = this._groupMap[id];
959
- if (this._childToParent[node.id]) {
960
- var parentId = this._childToParent[node.id];
961
- node["parent"] = parentId;
962
- }
963
- }
964
-
965
- // find depth of each group
966
- for (id in this._groupMap) {
967
- node = this._groupMap[id];
968
- var depth = this._findGroupTreeDepth(node, 1);
969
- node["onRow"] = depth - 1; // Modify user's object
970
- }
971
-
972
- // Calculate max depth
973
- var maxDepth = 0;
974
- for (id in this._groupMap) {
975
- node = this._groupMap[id];
976
- depth = node["onRow"] + 1;
977
- if (depth > maxDepth) {
978
- maxDepth = depth;
979
- }
980
- }
981
- this._maxDepth = maxDepth;
982
- };
983
- /** @private
984
- * @param {Object} node
985
- * @param {boolean} inUsedGroup
986
- */
987
- ColumnGroupingPlugin.prototype._flattenTree = function (node, inUsedGroup) {
988
- var childrens = node.children;
989
- if (childrens && childrens.length > 0) {
990
- var childId;
991
- for (var c = 0; c < childrens.length; c++) {
992
- var child = childrens[c];
993
- if (child.id) {
994
- // child is group object
995
- childId = child.id;
996
- this._flattenTree(child, inUsedGroup);
997
- } else {
998
- // child can be column id or group id
999
- childId = child;
1000
- if (inUsedGroup[childId] || this._getColumnIndexById(childId) !== -1) {
1001
- inUsedGroup[node.id] = true;
1002
- }
1003
- }
1004
- if (!this._childToParent[childId] && childId != node.id) {
1005
- this._childToParent[childId] = node.id;
1006
- }
1007
- }
1008
-
1009
- // Create Tree node for only in-used group
1010
- if (!this._groupMap[node.id] && inUsedGroup[node.id]) {
1011
- this._groupMap[node.id] = cloneObject(node); // clone node
1012
- }
1013
- }
1014
- };
1015
- /** @private
1016
- * @param {Object} node
1017
- * @param {number} currentDepth
1018
- * @return {number}
1019
- */
1020
- ColumnGroupingPlugin.prototype._findGroupTreeDepth = function (node, currentDepth) {
1021
- var parentId = node["parent"];
1022
- var parentNode = this._groupMap[parentId];
1023
- if (parentNode) {
1024
- return this._findGroupTreeDepth(parentNode, currentDepth + 1);
1025
- } else {
1026
- return currentDepth;
1027
- }
1028
- };
1029
-
1030
1186
  /** This version exclude invisible column unlike the one in GridPlugin
1031
1187
  * @private
1032
1188
  * @param {string} id
@@ -1056,20 +1212,20 @@ ColumnGroupingPlugin.prototype._findColumnIndexArr = function (node, cluster) {
1056
1212
  for (var i = 0; i < childrens.length; i++) {
1057
1213
  var child = childrens[i];
1058
1214
  if (!child.id) {
1059
- if (!this._groupMap[child]) {
1215
+ if (!this._visibleGroupMap[child]) {
1060
1216
  var colIndex = this._getColumnIndexById(child);
1061
1217
  if (colIndex !== -1) {
1062
1218
  cluster.push(colIndex);
1063
1219
  }
1064
1220
  } else {
1065
- this._findColumnIndexArr(this._groupMap[child], cluster);
1221
+ this._findColumnIndexArr(this._visibleGroupMap[child], cluster);
1066
1222
  }
1067
1223
  } else {
1068
1224
  // skip children that has same id as parent
1069
1225
  if (child.id === node.id) {
1070
1226
  return;
1071
1227
  }
1072
- this._findColumnIndexArr(this._groupMap[child.id], cluster);
1228
+ this._findColumnIndexArr(this._visibleGroupMap[child.id], cluster);
1073
1229
  }
1074
1230
  }
1075
1231
  }
@@ -1118,26 +1274,29 @@ ColumnGroupingPlugin._groupConsecutiveArr = function (arr) {
1118
1274
  }
1119
1275
  return result;
1120
1276
  };
1121
- /** @private
1277
+ /** This method modifies the group definition and outdates the group structure. It is necessary to recalculate group structure manually.
1278
+ * @private
1122
1279
  * @param {string} childId
1123
1280
  * @param {string} groupId
1281
+ * @return {boolean}
1124
1282
  */
1125
1283
  ColumnGroupingPlugin.prototype._addGroupChild = function (childId, groupId) {
1126
- var groupDef = this.getGroupDefinition(groupId);
1284
+ var groupDef = this._groupMap[groupId];
1127
1285
  if (childId && groupDef) {
1128
1286
  var chdr = groupDef.children;
1129
1287
  if (chdr && chdr.indexOf(childId) < 0) {
1130
- this._childToParent[childId] = groupId;
1131
1288
  chdr.push(childId);
1289
+ return true;
1132
1290
  }
1133
1291
  }
1292
+ return false;
1134
1293
  };
1135
1294
  /** @private
1136
1295
  * @param {string} childId
1137
1296
  * @return {ColumnGroupingPlugin~GroupDefinition}
1138
1297
  */
1139
1298
  ColumnGroupingPlugin.prototype._getParentGroup = function (childId) {
1140
- return this.getGroupDefinition(this._childToParent[childId]);
1299
+ return this._visibleGroupMap[this._childToParent[childId]];
1141
1300
  };
1142
1301
  /** @private
1143
1302
  * @param {string} colId
@@ -1195,16 +1354,16 @@ ColumnGroupingPlugin.prototype.getCellInfo = function (e) {
1195
1354
  return cellInfo;
1196
1355
  };
1197
1356
  /** @public
1198
- * @param {number|string} from //Column index or id that should be moved
1357
+ * @param {number|string} colRef //Column index or id that should be moved
1199
1358
  * @param {number} to
1200
1359
  * @param {string} groupId
1201
1360
  */
1202
- ColumnGroupingPlugin.prototype.moveColumnIntoGroup = function (from, to, groupId) {
1361
+ ColumnGroupingPlugin.prototype.moveColumnIntoGroup = function (colRef, to, groupId) {
1203
1362
  var fromIndex = -1;
1204
- if (typeof from == "string") {
1205
- fromIndex = this._getColumnIndexById(from);
1363
+ if (typeof colRef == "string") {
1364
+ fromIndex = this._getColumnIndexById(colRef);
1206
1365
  } else {
1207
- fromIndex = from;
1366
+ fromIndex = colRef;
1208
1367
  }
1209
1368
  if (fromIndex == -1) {
1210
1369
  return;
@@ -1255,42 +1414,42 @@ ColumnGroupingPlugin.prototype.moveColumnIntoGroup = function (from, to, groupId
1255
1414
  }
1256
1415
  }
1257
1416
  }
1417
+
1418
+ // Get column id before start moving
1419
+ var colId = this.getColumnId(fromIndex);
1258
1420
  for (var gridIndex = this._hosts.length; --gridIndex >= 0;) {
1259
1421
  var host = this._hosts[gridIndex];
1260
1422
  host.moveColumn(fromIndex, to);
1261
1423
  }
1424
+ if (colId) {
1425
+ // Remove from current group
1426
+ var previousGroup = this._childToParent[colId];
1427
+ if (previousGroup) {
1428
+ var previousGroupChild = this.getGroupChildren(previousGroup);
1429
+ previousGroupChild.splice(previousGroupChild.indexOf(colId), 1);
1430
+ this.setGroupChildren(previousGroup, previousGroupChild);
1431
+ }
1262
1432
 
1263
- //remove previous group apply to column
1264
- var colId = this.getColumnId(to);
1265
- var previousGroup = this._childToParent[colId];
1266
- if (previousGroup) {
1267
- var previousGroupChild = this.getGroupChildren(previousGroup);
1268
- previousGroupChild.splice(previousGroupChild.indexOf(colId), 1);
1269
- this.setGroupChildren(previousGroup, previousGroupChild);
1270
- }
1271
-
1272
- //apply new group
1273
- var children = this.getGroupChildren(groupId);
1274
- if (children.indexOf(colId) == -1) {
1275
- if (colId) {
1433
+ // Add to new group
1434
+ var children = this.getGroupChildren(groupId);
1435
+ if (children.indexOf(colId) < 0) {
1276
1436
  children.push(colId);
1437
+ this.setGroupChildren(groupId, children);
1277
1438
  }
1278
1439
  }
1279
- this.setGroupChildren(groupId, children);
1280
- this._requestApplyGrouping();
1281
1440
  };
1282
1441
  /** @public
1283
- * @param {number|string} columnIndex //Column index or id that should be moved
1442
+ * @param {number|string} colRef //Column index or id that should be moved
1284
1443
  * @param {string} groupId
1285
1444
  */
1286
- ColumnGroupingPlugin.prototype.setColumnParent = function (columnIndex, groupId) {
1445
+ ColumnGroupingPlugin.prototype.setColumnParent = function (colRef, groupId) {
1287
1446
  var api = this.getGridApi();
1288
1447
  if (!api) {
1289
1448
  return;
1290
1449
  }
1291
1450
  var grid = this._hosts[0];
1292
1451
  var colCount = grid.getColumnCount();
1293
- this.moveColumnIntoGroup(columnIndex, colCount, groupId);
1452
+ this.moveColumnIntoGroup(colRef, colCount, groupId);
1294
1453
  };
1295
1454
  export default ColumnGroupingPlugin;
1296
1455
  export { ColumnGroupingPlugin, ColumnGroupingPlugin as ColumnGrouping, ColumnGroupingPlugin as ColumnGroupingExtension };