@refinitiv-ui/efx-grid 6.0.53 → 6.0.54

Sign up to get free protection for your applications and to get access to all the features.
@@ -10079,6 +10079,12 @@ Segment.prototype.getChildIds = function() {
10079
10079
  return this._childCount ? Object.keys(this._children) : [];
10080
10080
  };
10081
10081
  /** @public
10082
+ * @return {!Object}
10083
+ */
10084
+ Segment.prototype.getChildren = function() {
10085
+ return this._children;
10086
+ };
10087
+ /** @public
10082
10088
  * @return {number}
10083
10089
  */
10084
10090
  Segment.prototype.getChildCount = function() {
@@ -12425,9 +12431,9 @@ DataTable.prototype.getSegmentChildIds = function(segmentId) {
12425
12431
  };
12426
12432
  /** Sort all of existing segments by multiple sort logics
12427
12433
  * @public
12428
- * @param {Function|Array.<Function>} sortLogics
12429
- * @param {Array.<number>} sortOrders
12430
- * @param {Array.<string>} cids
12434
+ * @param {Function|Array.<Function>|Object} sortLogics
12435
+ * @param {Array.<number>=} sortOrders
12436
+ * @param {Array.<string>=} cids
12431
12437
  * @return {boolean}
12432
12438
  */
12433
12439
  DataTable.prototype.sortSeparators = function (sortLogics, sortOrders, cids) {
@@ -14466,9 +14472,9 @@ RowDefinition.dispose = function(rowDef) {
14466
14472
  * @const
14467
14473
  */
14468
14474
  var SYNAPSE_URL =
14469
- '/synapse/service/suggestions/suggest/?'
14470
- + 'hits=1' // search only 1 result
14471
- + '&profile=' + encodeURIComponent('Field Selector');
14475
+ "/synapse/service/suggestions/suggest/?"
14476
+ + "hits=1" // search only 1 result
14477
+ + "&profile=" + encodeURIComponent("Field Selector");
14472
14478
 
14473
14479
  /* @namespace */
14474
14480
  var FieldDefinition = {};
@@ -14585,18 +14591,13 @@ FieldDefinition._timeSeriesChildren = {};
14585
14591
  * @private
14586
14592
  * @const
14587
14593
  */
14588
- FieldDefinition._synapse = '';
14594
+ FieldDefinition._synapse = "";
14589
14595
  /**
14590
14596
  * @type {string}
14591
14597
  * @private
14592
14598
  * @const
14593
14599
  */
14594
- FieldDefinition._lang = 'en';
14595
- /**
14596
- * @type {boolean}
14597
- * @private
14598
- */
14599
- FieldDefinition._caching = false;
14600
+ FieldDefinition._lang = "en";
14600
14601
  /**
14601
14602
  * @type {boolean}
14602
14603
  * @private
@@ -14623,17 +14624,22 @@ FieldDefinition.set = function(field, def) {
14623
14624
  }
14624
14625
  }
14625
14626
  };
14626
- /** @public
14627
+ /** Get field definition object
14628
+ * @public
14627
14629
  * @function
14628
14630
  * @param {string} field
14629
14631
  * @return {Object}
14630
14632
  */
14631
14633
  FieldDefinition.get = function(field) {
14632
- if(this._caching) {
14633
- return FieldDefinition._defs[field];
14634
- }
14635
- return null;
14634
+ return FieldDefinition._defs[field] || null;
14636
14635
  };
14636
+ /** Get field definition object
14637
+ * @public
14638
+ * @function
14639
+ * @param {string} field
14640
+ * @return {Object}
14641
+ */
14642
+ FieldDefinition.getFieldInfo = FieldDefinition.get;
14637
14643
 
14638
14644
  /** @public
14639
14645
  * @function
@@ -14642,7 +14648,7 @@ FieldDefinition.get = function(field) {
14642
14648
  */
14643
14649
  FieldDefinition.hasFieldInfo = function(field) {
14644
14650
  var val = FieldDefinition.get(field);
14645
- return val && val.field; // Already preventing an error caused by accessing a property on a null value
14651
+ return (val && val.field) ? true : false; // Already preventing an error caused by accessing a property on a null value
14646
14652
  };
14647
14653
 
14648
14654
  /** @public
@@ -14678,15 +14684,6 @@ FieldDefinition.remove = function(field) {
14678
14684
  */
14679
14685
  FieldDefinition.setSynapseConfig = function (config) {
14680
14686
  FieldDefinition._synapse = config;
14681
-
14682
- };
14683
-
14684
- /** @public
14685
- * @function
14686
- * @param {boolean} caching
14687
- */
14688
- FieldDefinition.setFieldCaching = function (caching) {
14689
- FieldDefinition._caching = caching;
14690
14687
  };
14691
14688
 
14692
14689
  /** @public
@@ -14811,7 +14808,7 @@ FieldDefinition.getFieldProperty = function(field, propertyName) {
14811
14808
  return null;
14812
14809
  };
14813
14810
 
14814
- /** to get more info about field via synapse service
14811
+ /** To get more info about field via synapse service
14815
14812
  * @private
14816
14813
  * @param {string} field
14817
14814
  * @returns {Promise}
@@ -14843,12 +14840,12 @@ FieldDefinition.loadFieldInfo = function (field) {
14843
14840
  // everything fine, call synapse service
14844
14841
  else {
14845
14842
  var queryUrl = SYNAPSE_URL
14846
- + '&api-key=' + encodeURIComponent(synapse.apiKey)
14847
- + '&contextApp=' + encodeURIComponent(synapse.contextApp)
14848
- + '&language=' + encodeURIComponent(FieldDefinition._lang)
14849
- + '&query=' + encodeURIComponent(field);
14843
+ + "&api-key=" + encodeURIComponent(synapse.apiKey)
14844
+ + "&contextApp=" + encodeURIComponent(synapse.contextApp)
14845
+ + "&language=" + encodeURIComponent(FieldDefinition._lang)
14846
+ + "&query=" + encodeURIComponent(field);
14850
14847
  if (synapse.auth) {
14851
- queryUrl += '&auth=' + encodeURIComponent(synapse.auth);
14848
+ queryUrl += "&auth=" + encodeURIComponent(synapse.auth);
14852
14849
  }
14853
14850
  // TODO: handle client timeout
14854
14851
  var xmr = new XMLHttpRequest();
@@ -14857,9 +14854,9 @@ FieldDefinition.loadFieldInfo = function (field) {
14857
14854
  FieldDefinition._loadingField[field] = defer;
14858
14855
 
14859
14856
  // for now we care only successful case
14860
- xmr.addEventListener('loadend', onLoadEnd);
14861
- xmr.addEventListener('timeout', onError);
14862
- xmr.addEventListener('error', onError);
14857
+ xmr.addEventListener("loadend", onLoadEnd);
14858
+ xmr.addEventListener("timeout", onError);
14859
+ xmr.addEventListener("error", onError);
14863
14860
  xmr.open("GET", queryUrl, true); // true for asynchronous
14864
14861
  xmr.send();
14865
14862
  }
@@ -14887,7 +14884,7 @@ FieldDefinition._mockOnLoadEndData = function (field, defer) {
14887
14884
  var fieldUpperCase = field.toUpperCase();
14888
14885
  var fieldLowerCase = fieldUpperCase.toLowerCase();
14889
14886
  var label;
14890
- if (fieldLowerCase.indexOf('_') === 2) { // transform XX_ABCD -> Abcd
14887
+ if (fieldLowerCase.indexOf("_") === 2) { // transform XX_ABCD -> Abcd
14891
14888
  label = fieldUpperCase[3] + fieldLowerCase.substring(4);
14892
14889
  } else {
14893
14890
  label = fieldUpperCase[0] + fieldLowerCase.substring(1);
@@ -14949,49 +14946,49 @@ FieldDefinition._mockOnLoadEndData = function (field, defer) {
14949
14946
  function onLoadEnd(e) {
14950
14947
  var xmr = e.currentTarget;
14951
14948
  var defer = xmr._defer;
14952
- var resolve = defer.resolve;
14953
- var reject = defer.reject;
14949
+ var field = xmr._field;
14954
14950
 
14955
- delete FieldDefinition._loadingField[xmr._field];
14951
+ delete FieldDefinition._loadingField[field];
14956
14952
 
14957
14953
  if (xmr.status === 200) { // case success
14958
- var returnObj = {
14959
- field: xmr._field,
14960
- fieldDefinition: null
14961
- };
14962
14954
  var res = JSON.parse(xmr.responseText);
14955
+ var fieldDef = null;
14963
14956
 
14964
14957
  var result = res.result && res.result[0];
14965
14958
  if (result) {
14966
14959
  var item = result.hits && result.hits[0];
14967
14960
  if (item && item.p) {
14968
14961
  var profile = item.p;
14969
- if (profile.fn.toUpperCase() === xmr._field.toUpperCase()) {
14970
- var fieldDef = FieldDefinition.get(xmr._field) || {};
14962
+ if (profile.fn.toUpperCase() === field.toUpperCase()) {
14963
+ fieldDef = FieldDefinition.get(field) || {};
14971
14964
 
14972
14965
  fieldDef.field = profile.fn; // name
14966
+ fieldDef.name = profile.fl; // label
14973
14967
  fieldDef.rank = profile.Rank;
14974
14968
  fieldDef.fieldDataType = profile.fdt; // data type
14969
+ fieldDef.id = profile.fid;
14975
14970
  fieldDef.IsMonitorOnlyField = profile.fimo;
14976
14971
  fieldDef.IsRealtimePortfolioField = profile.firp;
14977
14972
  fieldDef.IsRealtimeField = profile.firt;
14978
- fieldDef.name = profile.fl; // label
14979
14973
  fieldDef.source = profile.fsrc;
14980
14974
  fieldDef.sourceRank = profile.fsrnk;
14981
14975
  fieldDef.description = item.title;
14982
14976
 
14983
- FieldDefinition.set(xmr._field, fieldDef);
14984
- returnObj.fieldDefinition = fieldDef;
14977
+ FieldDefinition.set(field, fieldDef);
14985
14978
  }
14986
14979
  }
14987
14980
  }
14988
- resolve(returnObj);
14981
+ if(fieldDef) {
14982
+ defer.resolve(fieldDef);
14983
+ } else {
14984
+ defer.reject("No definition for " + field);
14985
+ }
14989
14986
  } else if (xmr._error) { // case error && time out
14990
- xmr._error.field = xmr._field;
14991
- reject(xmr._error);
14987
+ xmr._error.field = field;
14988
+ defer.reject(xmr._error);
14992
14989
  } else { // case status not 200
14993
- reject({
14994
- field: xmr._field,
14990
+ defer.reject({
14991
+ field: field,
14995
14992
  status: xmr.status,
14996
14993
  statusText: xmr.statusText,
14997
14994
  request: xmr
@@ -28976,6 +28973,8 @@ var DataView = function(source) {
28976
28973
  t._onRefreshTimeout = t._onRefreshTimeout.bind(t);
28977
28974
  t._updateWrapCount = t._updateWrapCount.bind(t);
28978
28975
 
28976
+ t._byRemovalMap = t._byRemovalMap.bind(t);
28977
+
28979
28978
  t._rids = [];
28980
28979
  t._sortingDefs = [];
28981
28980
  t._columnStats = {};
@@ -29029,6 +29028,15 @@ DataView.prototype._hiddenRids = null;
29029
29028
  * @type {Object.<string, boolean>}
29030
29029
  */
29031
29030
  DataView.prototype._collapsedRids = null; // for segmentation
29031
+ /** @private
29032
+ * @type {Object.<string, number>}
29033
+ */
29034
+ DataView.prototype._excludedRids = null;
29035
+ /** @private
29036
+ * @type {boolean}
29037
+ */
29038
+ DataView.prototype._emptySegmentFiltering = false;
29039
+
29032
29040
  /** @private
29033
29041
  * @type {Object.<string, number>}
29034
29042
  */
@@ -29725,8 +29733,6 @@ DataView.prototype.hideRow = function(rId, hidden) {
29725
29733
  */
29726
29734
  DataView.prototype.hideRows = function(rowRefs, hidden) {
29727
29735
  hidden = hidden !== false;
29728
- var dirty = false;
29729
- var rids = this._toRowIds(rowRefs);
29730
29736
  var hiddenRids = this._hiddenRids;
29731
29737
 
29732
29738
  if(hidden){
@@ -29737,11 +29743,19 @@ DataView.prototype.hideRows = function(rowRefs, hidden) {
29737
29743
  return; // All rows are visible
29738
29744
  }
29739
29745
 
29746
+ var rids = this._toRowIds(rowRefs);
29747
+ var dirty = false;
29748
+
29740
29749
  for(var i = rids.length; --i >= 0;) {
29741
29750
  var rid = rids[i];
29742
29751
  if(rid) { // undefined, null, and an empty string value are not a valid row id
29743
- if(!!hiddenRids[rid] !== hidden) {
29744
- hiddenRids[rid] = hidden;
29752
+ if(hidden) {
29753
+ if(!hiddenRids[rid]) {
29754
+ hiddenRids[rid] = true;
29755
+ dirty = true;
29756
+ }
29757
+ } else if(hiddenRids[rid]) {
29758
+ delete hiddenRids[rid];
29745
29759
  dirty = true;
29746
29760
  }
29747
29761
  }
@@ -29750,11 +29764,9 @@ DataView.prototype.hideRows = function(rowRefs, hidden) {
29750
29764
  if(dirty) {
29751
29765
  if(!hidden) {
29752
29766
  var hasHiddenRow = false;
29753
- for(var key in hiddenRids) {
29754
- if(hiddenRids[key]) {
29755
- hasHiddenRow = true;
29756
- break;
29757
- }
29767
+ for(var key in hiddenRids) { // eslint-disable-line
29768
+ hasHiddenRow = true;
29769
+ break;
29758
29770
  }
29759
29771
  if(!hasHiddenRow) {
29760
29772
  hiddenRids = this._hiddenRids = null;
@@ -29762,6 +29774,7 @@ DataView.prototype.hideRows = function(rowRefs, hidden) {
29762
29774
  }
29763
29775
  this._refreshAndNotify(); // Very slow
29764
29776
  }
29777
+
29765
29778
  };
29766
29779
  /**
29767
29780
  * Show/hide rows in the data view
@@ -29843,23 +29856,14 @@ DataView.prototype.filterOut = function(cid, value) {
29843
29856
  */
29844
29857
  DataView.prototype.filterInOnce = function(cid, value, opt_filteringOut) {
29845
29858
  var checker = this._getFilterLogic(cid, value);
29846
- if(!checker) { return; }
29847
-
29848
- var filteringOut = (opt_filteringOut === true);
29849
- var rids = this._rids;
29850
- var dt = this._dt;
29851
29859
  var removalMap = {};
29852
- var totalRem = 0;
29853
- var len = rids.length;
29854
- for(var i = len; --i >= 0;) {
29855
- var rid = rids[i];
29856
- var values = dt.getRowData(rid);
29857
- if (!values || checker(rid, values) === filteringOut) {
29858
- removalMap[rid] = true;
29859
- ++totalRem;
29860
- }
29860
+ if(!this._getRemovalMap(
29861
+ removalMap,
29862
+ checker,
29863
+ (opt_filteringOut === true)
29864
+ )) {
29865
+ return;
29861
29866
  }
29862
- if(totalRem <= 0) { return; }
29863
29867
 
29864
29868
  var firstChange = this._removeRowIds(removalMap);
29865
29869
 
@@ -29882,13 +29886,13 @@ DataView.prototype.filterOutOnce = function(cid, value) {
29882
29886
  this.filterInOnce(cid, value, true);
29883
29887
  };
29884
29888
  /** @private
29885
- * @param {!Object.<string, *>} removalMap
29889
+ * @param {!Object} removalMap
29886
29890
  * @return {number}
29887
29891
  */
29888
29892
  DataView.prototype._removeRowIds = function(removalMap) {
29889
- var firstChange = this._removeArrayItems(this._rids, removalMap);
29893
+ var firstChange = DataView._removeArrayItems(this._rids, removalMap);
29890
29894
  if(this._groupView) {
29891
- firstChange = this._removeArrayItems(this._groupView, removalMap);
29895
+ firstChange = DataView._removeArrayItems(this._groupView, removalMap);
29892
29896
  }
29893
29897
 
29894
29898
  if(this._groupMembers) {
@@ -29899,6 +29903,7 @@ DataView.prototype._removeRowIds = function(removalMap) {
29899
29903
  }
29900
29904
  }
29901
29905
  return firstChange;
29906
+
29902
29907
  };
29903
29908
  /** @public
29904
29909
  * @fires DataView#pageCountChanged
@@ -31452,9 +31457,9 @@ DataView.prototype.getSegmentChildIds = function(segmentRef) {
31452
31457
  };
31453
31458
  /** Sort all of existing segments by multiple sort logics
31454
31459
  * @public
31455
- * @param {Array.<Function>} sortLogics
31456
- * @param {Array.<number>} sortOrders
31457
- * @param {Array.<string>} cids
31460
+ * @param {Function|Array.<Function>|Object} sortLogics
31461
+ * @param {Array.<number>=} sortOrders
31462
+ * @param {Array.<string>=} cids
31458
31463
  */
31459
31464
  DataView.prototype.sortSeparators = function (sortLogics, sortOrders, cids) {
31460
31465
  this._dt.sortSeparators(sortLogics, sortOrders, cids);
@@ -31466,7 +31471,19 @@ DataView.prototype.sortSeparators = function (sortLogics, sortOrders, cids) {
31466
31471
  DataView.prototype.sortSegments = function (compare) {
31467
31472
  this._dt.sortSegments(compare);
31468
31473
  };
31469
-
31474
+ /** Automatically hide empty segment when all of its member are filtered out. An empty segment will not be hidden, if there is no active filter. Collapsed segment does not count as filtering.
31475
+ * @public
31476
+ * @param {boolean=} enabled
31477
+ */
31478
+ DataView.prototype.enableEmptySegmentFiltering = function (enabled) {
31479
+ enabled = enabled !== false;
31480
+ if(this._emptySegmentFiltering !== enabled) {
31481
+ this._emptySegmentFiltering = enabled;
31482
+ if(this._userFilter) {
31483
+ this._refreshAndNotify();
31484
+ }
31485
+ }
31486
+ };
31470
31487
  /**
31471
31488
  * @public
31472
31489
  * @param {string|number} segmentRef Row id or row index
@@ -31626,26 +31643,35 @@ DataView.prototype._updateRowIds = function(opt_rowIds) {
31626
31643
  // Perform the following sequences: parent view cloning >> row hiding >> row filtering >> row grouping >> sorting >> paging
31627
31644
  this._rids = opt_rowIds || this._parent.getAllRowIds(); // Get all data ids
31628
31645
 
31629
- if(this._hiddenRids) {
31630
- this._removeArrayItems(this._rids, this._hiddenRids);
31631
- }
31646
+ this._dispatch("beforeFiltering", {});
31647
+
31648
+ this._excludedRids = {};
31649
+ var exclusionCount = 0;
31650
+ exclusionCount += DataView._copyObjectKeys(this._excludedRids, this._hiddenRids);
31651
+
31652
+ // Segment separators should not be filtered out (hidden)
31632
31653
  var segments = this._dt._getSegmentSeparators();
31654
+ var filterExceptions = segments ? segments.getSegments() : null;
31655
+ var userRemoval = this._getRemovalMap(this._excludedRids, this._userFilter, this._filteringOut, filterExceptions);
31656
+ exclusionCount += userRemoval;
31657
+
31633
31658
  this._collapsedRids = null;
31634
- var filterExceptions = null;
31635
31659
  if(segments) {
31636
- filterExceptions = segments.getSegments(); // Segment separators should not be filtered out (hidden)
31637
- var collapsedRows = this._collapsedRids = segments.getCollapsedRows(); // Children of collapsed segments must be filtered out (hidden)
31638
- if(collapsedRows) {
31639
- this._removeArrayItems(this._rids, collapsedRows);
31660
+ if(userRemoval && this._emptySegmentFiltering) {
31661
+ exclusionCount += this._getEmptySegments(this._excludedRids, filterExceptions);
31640
31662
  }
31663
+ this._collapsedRids = segments.getCollapsedRows();
31664
+ // Children of collapsed segments must be filtered out (hidden)
31665
+ exclusionCount += DataView._copyObjectKeys(this._excludedRids, this._collapsedRids);
31641
31666
  }
31642
31667
 
31643
- this._dispatch("beforeFiltering", {});
31644
- this._quickFilter(this._userFilter, this._filteringOut, filterExceptions);
31645
-
31646
- if(this._groupLevel > 0 && !opt_rowIds) {
31647
- this._quickFilter(this._groupFilterLogic, false); // Filter In
31668
+ if(this._groupLevel > 0 && !opt_rowIds) { // WARNING: The line below is quite slow
31669
+ exclusionCount += this._getRemovalMap(this._excludedRids, this._groupFilterLogic, false); // Filter In
31670
+ }
31671
+ if(exclusionCount) {
31672
+ this._rids = this._rids.filter(this._byRemovalMap);
31648
31673
  }
31674
+ this._excludedRids = null;
31649
31675
 
31650
31676
  if(this._groupMembers) { // Has grouping
31651
31677
  this._populateGroups(); // View will be properly re-populate inside _populateGroups()
@@ -31917,9 +31943,9 @@ DataView.prototype._onRowUpdated = function(e) { // onUpdate
31917
31943
 
31918
31944
  if(this._groupLevel > 0) {
31919
31945
  if(processingFlag === 1) { // The row is moved to the other group
31920
- if(this._removeArrayItem(this._rids, rid) >= 0) {
31946
+ if(DataView._removeArrayItem(this._rids, rid) >= 0) {
31921
31947
  if(this._groupView) {
31922
- this._removeArrayItem(this._groupView, rid);
31948
+ DataView._removeArrayItem(this._groupView, rid);
31923
31949
  }
31924
31950
  }
31925
31951
  if(this._shared.multiGroupRow) {
@@ -32119,34 +32145,31 @@ DataView.prototype._getRowIndex = function(rids, opt_nextRid, opt_fallback) {
32119
32145
  * @returns {number}
32120
32146
  */
32121
32147
  DataView.prototype._removeDataRow = function(rid) {
32122
- var at = this._removeArrayItem(this._rids, rid);
32148
+ var at = DataView._removeArrayItem(this._rids, rid);
32123
32149
  if(this._groupView && at >= 0) {
32124
- at = this._removeArrayItem(this._groupView, rid);
32150
+ at = DataView._removeArrayItem(this._groupView, rid);
32125
32151
  }
32126
32152
  return at;
32127
32153
  };
32128
32154
  /** @private
32129
- * @param {Array} ary
32155
+ * @param {!Array} ary
32130
32156
  * @param {*} item
32131
32157
  * @return {number} Index of the removed item
32132
32158
  */
32133
- DataView.prototype._removeArrayItem = function(ary, item) {
32134
- var len = ary.length;
32135
- for(var i = 0; i < len; ++i) {
32136
- if(ary[i] === item) {
32137
- ary.splice(i, 1);
32138
- return i;
32139
- }
32159
+ DataView._removeArrayItem = function(ary, item) {
32160
+ var at = ary.indexOf(item);
32161
+ if(at >= 0) {
32162
+ ary.splice(at, 1);
32140
32163
  }
32141
- return -1;
32164
+ return at;
32142
32165
  };
32143
32166
  /** Remove multiple array items
32144
32167
  * @private
32145
32168
  * @param {Array.<string>} ary
32146
- * @param {Object.<string, *>} items
32169
+ * @param {Object} items
32147
32170
  * @return {number} First item index that is being removed. NaN if no item is removed
32148
32171
  */
32149
- DataView.prototype._removeArrayItems = function(ary, items) {
32172
+ DataView._removeArrayItems = function(ary, items) {
32150
32173
  var f = NaN;
32151
32174
  var c = 0;
32152
32175
  for(var i = ary.length; --i >= 0;) {
@@ -32164,6 +32187,24 @@ DataView.prototype._removeArrayItems = function(ary, items) {
32164
32187
  }
32165
32188
  return f;
32166
32189
  };
32190
+ /** @private
32191
+ * @param {Object} baseObj
32192
+ * @param {Object} masterObj
32193
+ * @returns {number}
32194
+ */
32195
+ DataView._copyObjectKeys = function(baseObj, masterObj) {
32196
+ if(masterObj) {
32197
+ var count = 0;
32198
+
32199
+ for(var key in masterObj) {
32200
+ baseObj[key] = 1;
32201
+ ++count; // WARNING: duplicated key can be counted more than once
32202
+ }
32203
+ return count;
32204
+ }
32205
+ return 0;
32206
+ };
32207
+
32167
32208
  /** @private
32168
32209
  * @param {string|null} rid
32169
32210
  * @param {Object} rowData
@@ -32198,9 +32239,6 @@ DataView.prototype.isRowFiltered = function(rid, rowData) {
32198
32239
  return true;
32199
32240
  }
32200
32241
  }
32201
- if(this.isSegmentSeparator(rid)) {
32202
- return false; // Segment separator cannot be filtered
32203
- }
32204
32242
  if(this._collapsedRids) {
32205
32243
  if(this._collapsedRids[rid]) {
32206
32244
  return true;
@@ -32242,41 +32280,92 @@ DataView.prototype._sort = function() {
32242
32280
  };
32243
32281
 
32244
32282
  /** @private
32283
+ * @param {string} rid
32284
+ * @returns {boolean}
32285
+ */
32286
+ DataView.prototype._byRemovalMap = function(rid) {
32287
+ return !this._excludedRids[rid];
32288
+ };
32289
+ /** @private
32290
+ * @param {Object} removalMap
32245
32291
  * @param {Function} checker
32246
32292
  * @param {boolean} filteringOut
32247
32293
  * @param {Object=} exceptions
32294
+ * @returns {number} Number of rids that would be filtered out
32248
32295
  */
32249
- DataView.prototype._quickFilter = function(checker, filteringOut, exceptions) {
32296
+ DataView.prototype._getRemovalMap = function(removalMap, checker, filteringOut, exceptions) {
32250
32297
  if(!checker) {
32251
- return;
32298
+ return 0;
32252
32299
  }
32253
32300
 
32254
32301
  var rids = this._rids; // Make local variable to speed up the process
32255
- var len = rids.length;
32256
32302
  var dt = this._dt;
32257
- var spliceCount = 0;
32258
- for(var i = len; --i >= 0;) {
32259
- var rid = rids[i];
32260
- var removed = false;
32261
- if(!exceptions || !exceptions[rid]) {
32262
- var values = dt.getRowData(rid);
32303
+ var count = 0;
32304
+ var rid, i, values;
32305
+ var len = rids.length;
32306
+
32307
+ if(exceptions) {
32308
+ for(i = len; --i >= 0;) {
32309
+ rid = rids[i];
32310
+ if(!exceptions[rid]) {
32311
+ values = dt.getRowData(rid);
32312
+ if (values) {
32313
+ if(checker(rid, values) === filteringOut) {
32314
+ removalMap[rid] = 1;
32315
+ ++count;
32316
+ }
32317
+ } else {
32318
+ removalMap[rid] = 1;
32319
+ ++count;
32320
+ }
32321
+ }
32322
+ }
32323
+ } else {
32324
+ for(i = len; --i >= 0;) {
32325
+ rid = rids[i];
32326
+ values = dt.getRowData(rid);
32263
32327
  if (values) {
32264
- removed = checker(rid, values) === filteringOut;
32328
+ if(checker(rid, values) === filteringOut) {
32329
+ removalMap[rid] = 1;
32330
+ ++count;
32331
+ }
32265
32332
  } else {
32266
- removed = true;
32333
+ removalMap[rid] = 1;
32334
+ ++count;
32267
32335
  }
32268
32336
  }
32269
- if(removed) {
32270
- ++spliceCount;
32271
- } else if(spliceCount > 0) {
32272
- rids.splice(i + 1, spliceCount);
32273
- spliceCount = 0;
32274
- }
32275
32337
  }
32276
- if(spliceCount > 0) {
32277
- rids.splice(0, spliceCount);
32338
+ return count;
32339
+ };
32340
+ /** @private
32341
+ * @param {Object} removalMap
32342
+ * @param {Object} segmentRids
32343
+ * @returns {number} Number of rids that would be filtered out
32344
+ */
32345
+ DataView.prototype._getEmptySegments = function(removalMap, segmentRids) {
32346
+ var segments = this._dt._getSegmentSeparators();
32347
+ var count = 0;
32348
+ for(var segmentId in segmentRids) {
32349
+ var segment = segments.getSegment(segmentId);
32350
+ if(segment) {
32351
+ var chdr = segment.getChildren();
32352
+ var emptySegment = true;
32353
+ for(var childId in chdr) {
32354
+ if(!removalMap[childId]) {
32355
+ emptySegment = false;
32356
+ break;
32357
+ }
32358
+ }
32359
+ if(emptySegment) {
32360
+ removalMap[segmentId] = 1;
32361
+ ++count;
32362
+ }
32363
+ }
32278
32364
  }
32365
+
32366
+ return count;
32279
32367
  };
32368
+
32280
32369
  /** @private
32281
32370
  * @param {string|Function|undefined} cid
32282
32371
  * @param {*} value
@@ -32555,13 +32644,13 @@ DataView.prototype._removeGroupMember = function (groupIndex, groupId) {
32555
32644
  };
32556
32645
  /** @private
32557
32646
  * @param {string} cid
32558
- * @param {Object.<string, *>} values
32647
+ * @param {Object} values
32559
32648
  * @return {Array.<string>}
32560
32649
  */
32561
32650
  DataView.prototype._defaultGroupCriteria = function(cid, values) {
32562
32651
  var val = values[cid];
32563
32652
  if(Array.isArray(val)) {
32564
- return val.map(function(data) {
32653
+ return val.map(function(data) { // TODO: this is very slow
32565
32654
  return data + "";
32566
32655
  });
32567
32656
  } else {
@@ -32570,11 +32659,11 @@ DataView.prototype._defaultGroupCriteria = function(cid, values) {
32570
32659
  };
32571
32660
  /** @private
32572
32661
  * @param {string|null} rid
32573
- * @param {Object.<string, *>} values
32662
+ * @param {Object} values
32574
32663
  * @return {boolean}
32575
32664
  */
32576
32665
  DataView.prototype._groupFilterLogic = function(rid, values) {
32577
- var gids = this._groupCriteria[this._groupLevel - 1](values);
32666
+ var gids = this._groupCriteria[this._groupLevel - 1](values); // TODO: this is very slow
32578
32667
  return gids.indexOf(this._groupId) >= 0;
32579
32668
  };
32580
32669
 
@@ -36014,7 +36103,7 @@ Core.prototype._batches = null;
36014
36103
  * @return {string}
36015
36104
  */
36016
36105
  Core.getVersion = function () {
36017
- return "5.1.67";
36106
+ return "5.1.70";
36018
36107
  };
36019
36108
  /** {@link ElementWrapper#dispose}
36020
36109
  * @override
@@ -40408,13 +40497,10 @@ Core.prototype._onSectionDataChanged = function (e) {
40408
40497
  for (var r = fromR; r < toR; ++r) {
40409
40498
  if(hasDataView) {
40410
40499
  var rowData = rowDataCollection[r];
40411
- if(!rowData) { // This is a header row
40412
- continue;
40413
- }
40414
40500
 
40415
40501
  e["rowData"] = rowData;
40416
40502
  e["rowId"] = rids[r];
40417
- e["dataValue"] = rowData[cid];
40503
+ e["dataValue"] = rowData ? rowData[cid] : null;
40418
40504
  }
40419
40505
  e["rowIndex"] = r;
40420
40506
  e["cell"] = section["getCell"](c, r, false); // Accessing cell by using bracket allows extenal object to mock Section
@@ -42955,7 +43041,7 @@ SortableTitlePlugin.prototype.sortColumns = function (sortOptions, opt_arg) {
42955
43041
  opt["sortOrder"] || opt["order"]
42956
43042
  );
42957
43043
  if (state) {
42958
- states[i] = state;
43044
+ states.push(state);
42959
43045
  }
42960
43046
  }
42961
43047
  this._sortColumn(states, opt_arg);
@@ -43537,10 +43623,12 @@ SortableTitlePlugin.prototype.sortSeparators = function (comparer) {
43537
43623
  var sortOrders = [];
43538
43624
  var sortFields = [];
43539
43625
  var sortStateCount = this._sortStates.length;
43626
+ var rowDefField = SortableTitlePlugin._toRowDefField();
43540
43627
  for(var i = 0; i < sortStateCount; i++){
43541
43628
  var sortState = this._sortStates[i];
43629
+ var field = this._rowDefMode ? rowDefField : sortState["field"];
43542
43630
  sortOrders.push(sortState["sortOrder"]);
43543
- sortFields.push(sortState["field"]);
43631
+ sortFields.push(field);
43544
43632
  }
43545
43633
  dv.sortSeparators(sortLogics, sortOrders, sortFields);
43546
43634
  }
@@ -44334,6 +44422,19 @@ var _hasFieldOrId = function(colDef, str) {
44334
44422
  return (colDef.getField() === str) || (colDef.getId() === str);
44335
44423
  };
44336
44424
 
44425
+ /** Compare the difference in the 'id' property.
44426
+ * @private
44427
+ * @param {Object} obj1
44428
+ * @param {Object} obj2
44429
+ * @returns {boolean} If the id property of two objects is equal, the return will be true, otherwise it will be false.
44430
+ */
44431
+ var _hasMatchingId = function(obj1, obj2) {
44432
+ if(!obj1 || !obj2 || !obj1.id || !obj2.id) { // Handle nullable, if the object or id have null, it's means difference value
44433
+ return false;
44434
+ }
44435
+ return obj1.id === obj2.id;
44436
+ };
44437
+
44337
44438
  /** @constructor
44338
44439
  * @extends {EventDispatcher}
44339
44440
  * @param {(Element|null)=} placeholder
@@ -44883,7 +44984,6 @@ Grid.prototype.initialize = function(gridOption) {
44883
44984
 
44884
44985
  if (gridOption["fieldCaching"]) {
44885
44986
  t._fieldCaching = gridOption["fieldCaching"];
44886
- js_FieldDefinition.setFieldCaching(t._fieldCaching);
44887
44987
  }
44888
44988
 
44889
44989
  if(gridOption["timeSeriesExpansion"] != null) {
@@ -45633,8 +45733,8 @@ Grid.prototype.replaceColumn = function (columnOption, colRef) {
45633
45733
  * @param {Object} response
45634
45734
  */
45635
45735
  Grid.prototype._onFieldLoadedSuccess = function (field, colDef, response) {
45636
- if (response && response.fieldDefinition) {
45637
- var fieldDef = response.fieldDefinition;
45736
+ if (response && response.id) {
45737
+ var fieldDef = response;
45638
45738
  if (colDef && colDef.getField() === field) {
45639
45739
  if (colDef.isDefaultName() && fieldDef.name) {
45640
45740
  colDef.setName(fieldDef.name);
@@ -45682,6 +45782,34 @@ Grid.prototype._setScrollbarParent = function (host) {
45682
45782
  this._grid.getHScrollbar().attachToExternalElement(host);
45683
45783
  };
45684
45784
 
45785
+ /** Get stored field information. If field information has not been requested or no data has been received yet, null value is returned.
45786
+ * @public
45787
+ * @function
45788
+ * @param {string} field
45789
+ * @return {Object}
45790
+ */
45791
+ Grid.prototype.getFieldInfo = function(field) {
45792
+ return js_FieldDefinition.getFieldInfo(field);
45793
+ };
45794
+ /** Request field information from Synapse service. If field information already exists, a resolved promise is returned. Synapse config must be supplied before the request can be made.
45795
+ * @public
45796
+ * @function
45797
+ * @param {string} field
45798
+ * @return {Promise}
45799
+ * @example
45800
+ * var gridConfig = {
45801
+ * synapse: { // define synapse configuration
45802
+ * apiKey: "xxx",
45803
+ * contextApp: "xxx",
45804
+ * auth: "xxx" (optional)
45805
+ * }
45806
+ * };
45807
+ * var promise = grid.loadFieldInfo("CF_LAST");
45808
+ */
45809
+ Grid.prototype.loadFieldInfo = function(field) {
45810
+ return js_FieldDefinition.loadFieldInfo(field);
45811
+ };
45812
+
45685
45813
  /**
45686
45814
  * @private
45687
45815
  * @param {string} field
@@ -45740,8 +45868,9 @@ Grid.prototype.setColumns = function(columns) {
45740
45868
  /** Remove, add and keep column based on the given column data
45741
45869
  * @public
45742
45870
  * @param {Array.<Object>} columns Array of column options
45871
+ * @param {boolean=} byId=false, if enable it, this method will only check for differences in the 'id' property
45743
45872
  */
45744
- Grid.prototype.restoreColumns = function(columns) {
45873
+ Grid.prototype.restoreColumns = function(columns, byId) {
45745
45874
  var grid = this._grid;
45746
45875
  grid.startBatch("reset");
45747
45876
  var configObj = this.getConfigObject();
@@ -45750,6 +45879,7 @@ Grid.prototype.restoreColumns = function(columns) {
45750
45879
  var preColLen = previousColumns.length;
45751
45880
  var newColLen = columns.length;
45752
45881
 
45882
+ var compareLogic = byId ? _hasMatchingId : deepEqual;
45753
45883
  var removingFields = [];
45754
45884
  var keepingColumns = [];
45755
45885
  var columnOrdering = [];
@@ -45759,7 +45889,7 @@ Grid.prototype.restoreColumns = function(columns) {
45759
45889
  for (i = 0; i < preColLen; i++) {
45760
45890
  found = false;
45761
45891
  for (j = 0; j < newColLen; j++) {
45762
- if (deepEqual(previousColumns[i], columns[j])) {
45892
+ if(compareLogic(previousColumns[i], columns[j])) {
45763
45893
  keepingColumns.push(previousColumns[i]);
45764
45894
  found = true;
45765
45895
  break;
@@ -45780,7 +45910,7 @@ Grid.prototype.restoreColumns = function(columns) {
45780
45910
  for (i = 0; i < newColLen; i++) {
45781
45911
  found = false;
45782
45912
  for (j = 0; j < keepingLen; j++) { // loop only keeping column
45783
- if (deepEqual(columns[i], keepingColumns[j])) {
45913
+ if(compareLogic(columns[i], keepingColumns[j])) {
45784
45914
  found = true;
45785
45915
  var colIndex = this.getColumnIndex(columns[i].field); // We cannot use 'i' (colIndex) in this case, as it will sort the columns. Instead, we need to obtain a new column index from the field.
45786
45916
  columnOrdering.push(this.getColumnId(colIndex));
@@ -49674,7 +49804,11 @@ var _joinSubKeys = function(subA, subB) {
49674
49804
  */
49675
49805
  var _isDynamicChain = function(ric) {
49676
49806
  // Dynamic chain will be 2 . (dot) for example .PG.PA
49677
- return ric.match(/\./g).length > 1;
49807
+ var matching = ric.match(/\./g); // Can be null when doesn't found dot(.)
49808
+ if(matching) {
49809
+ return matching.length > 1;
49810
+ }
49811
+ return false;
49678
49812
  };
49679
49813
 
49680
49814
  /** @private