@refinitiv-ui/efx-grid 6.0.14 → 6.0.16

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.
Files changed (35) hide show
  1. package/lib/column-format-dialog/index.d.ts +2 -1
  2. package/lib/column-format-dialog/index.js +2 -1
  3. package/lib/column-selection-dialog/index.d.ts +2 -1
  4. package/lib/column-selection-dialog/index.js +2 -1
  5. package/lib/core/dist/core.js +19 -9
  6. package/lib/core/dist/core.min.js +1 -1
  7. package/lib/core/es6/data/DataTable.js +1 -1
  8. package/lib/core/es6/data/Segment.d.ts +3 -3
  9. package/lib/core/es6/data/Segment.js +14 -6
  10. package/lib/core/es6/data/SegmentCollection.d.ts +1 -1
  11. package/lib/core/es6/data/SegmentCollection.js +3 -1
  12. package/lib/core/es6/grid/Core.js +1 -1
  13. package/lib/filter-dialog/index.d.ts +2 -1
  14. package/lib/filter-dialog/index.js +2 -1
  15. package/lib/grid/index.d.ts +2 -1
  16. package/lib/grid/index.js +3 -2
  17. package/lib/rt-grid/dist/rt-grid.js +740 -84
  18. package/lib/rt-grid/dist/rt-grid.min.js +1 -1
  19. package/lib/rt-grid/es6/ColumnDefinition.d.ts +10 -0
  20. package/lib/rt-grid/es6/ColumnDefinition.js +110 -1
  21. package/lib/rt-grid/es6/FieldDefinition.d.ts +6 -0
  22. package/lib/rt-grid/es6/FieldDefinition.js +43 -0
  23. package/lib/rt-grid/es6/Grid.d.ts +2 -0
  24. package/lib/rt-grid/es6/Grid.js +206 -8
  25. package/lib/rt-grid/es6/RowDefinition.d.ts +4 -0
  26. package/lib/rt-grid/es6/RowDefinition.js +57 -0
  27. package/lib/rt-grid/es6/SnapshotFiller.d.ts +1 -0
  28. package/lib/rt-grid/es6/SnapshotFiller.js +125 -17
  29. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +2 -2
  30. package/lib/tr-grid-row-filtering/es6/RowFiltering.d.ts +30 -29
  31. package/lib/tr-grid-row-filtering/es6/RowFiltering.js +176 -98
  32. package/lib/tr-grid-rowcoloring/es6/RowColoring.d.ts +17 -15
  33. package/lib/tr-grid-rowcoloring/es6/RowColoring.js +89 -159
  34. package/lib/versions.json +4 -4
  35. package/package.json +15 -2
@@ -11363,7 +11363,7 @@ DataTable.prototype.setRowData = function(rid, values, eventArg) { // Data chang
11363
11363
  this._prevData[rid] = {};
11364
11364
  if(eventArg) {
11365
11365
  var nextRid = /** @type{string} */(eventArg["nextRid"]); // Used for insertion only
11366
- var rowIndex = (nextRid != null) ? this.getRowIndex(nextRid) : -1;
11366
+ var rowIndex = (nextRid) ? this.getRowIndex(nextRid) : -1;
11367
11367
  if(rowIndex < 0) {
11368
11368
  rowIndex = /** @type{number} */(eventArg["fallback"]);
11369
11369
  }
@@ -11625,7 +11625,7 @@ DataTable.prototype.unshiftRow = function(opt_values, opt_rid) {
11625
11625
  return this.insertRow(0, opt_values, opt_rid);
11626
11626
  };
11627
11627
  /** @public
11628
- * @param {string|number|null=} rowRef
11628
+ * @param {(string|number|null)=} rowRef
11629
11629
  * @param {Object.<string, *>=} values Key/value pair object map
11630
11630
  * @param {string|null=} rid If the given row Id already exists, data is updated and no new row is added. Leave blank or null to let DataTable generate unique row Id
11631
11631
  * @return {string} Return Row id that has been inserted or changed
@@ -11634,11 +11634,13 @@ DataTable.prototype.unshiftRow = function(opt_values, opt_rid) {
11634
11634
  * @see {@link DataTable#removeRow}
11635
11635
  */
11636
11636
  DataTable.prototype.insertRow = function(rowRef, values, rid) {
11637
- var arg = {};
11637
+ var arg = null;
11638
11638
  if(typeof rowRef === "number") {
11639
+ arg = {};
11639
11640
  arg["nextRid"] = this._rids[rowRef];
11640
11641
  arg["fallback"] = rowRef; // Fallback index in case of no nextRid found
11641
- } else {
11642
+ } else if(rowRef) {
11643
+ arg = {};
11642
11644
  arg["nextRid"] = /** @type{string} */(rowRef);
11643
11645
  }
11644
11646
 
@@ -13784,6 +13786,63 @@ RowDefinition.prototype.addConstituent = function(ric) {
13784
13786
 
13785
13787
  return newChild ? childDef : null;
13786
13788
  };
13789
+
13790
+ /** Used to convert autogenerated row to regular real-time row
13791
+ * @public
13792
+ */
13793
+ RowDefinition.prototype._toRealTimeRow = function() {
13794
+ if(!this._ric) { // Empty row
13795
+ return;
13796
+ }
13797
+ if(this.isRowHeader()) {
13798
+ return;
13799
+ }
13800
+
13801
+ this._realTimeField = true;
13802
+ this._dataId = this._rowId + this._ric; // JET/RTK will generate data id to be rowId (given from this rowDef) + ric;
13803
+
13804
+ this._autoGenerated = false;
13805
+ this._parent = null;
13806
+ this._depthLevel = 0;
13807
+
13808
+ this.subscribeForUpdates();
13809
+ };
13810
+
13811
+ /** @public
13812
+ */
13813
+ RowDefinition.prototype.unlinkChain = function() {
13814
+ if(!this._isChain) {
13815
+ return;
13816
+ }
13817
+
13818
+ if(this.isChainExpanded()) {
13819
+ var rowDefs = this.getDescendants();
13820
+ var len = rowDefs.length;
13821
+ for(var i = 0; i < len; i++) {
13822
+ rowDefs[i]._toRealTimeRow();
13823
+ }
13824
+ }
13825
+
13826
+ this.unsubscribeForUpdates();
13827
+
13828
+ var view = this._view;
13829
+ if(view) {
13830
+ var rid = this.getRowId();
13831
+ var segment = view.getSegment(rid);
13832
+ if(segment) {
13833
+ segment.setClassification(null);
13834
+ }
13835
+ view.setSegmentSeparator(rid, false);
13836
+ }
13837
+
13838
+ this._isChain = this._expanded = false;
13839
+ this._chainRic = "";
13840
+ this._userInput = this._ric;
13841
+ this._children = null;
13842
+
13843
+ this.subscribeForUpdates();
13844
+ };
13845
+
13787
13846
  /** @public
13788
13847
  * @return {boolean} Returns true if there is a change in view
13789
13848
  */
@@ -14137,6 +14196,12 @@ FieldDefinition._defs = {
14137
14196
  description: "The latest Ask price."
14138
14197
  }
14139
14198
  };
14199
+
14200
+ /** @type {Object.<string, Object>}
14201
+ * @private
14202
+ */
14203
+ FieldDefinition._timeSeriesChildren = {};
14204
+
14140
14205
  /** api-key to call synapse service
14141
14206
  * @type {string}
14142
14207
  * @private
@@ -14183,6 +14248,25 @@ FieldDefinition.get = function(field) {
14183
14248
  /** @public
14184
14249
  * @function
14185
14250
  * @param {string} field
14251
+ * @return {Object}
14252
+ */
14253
+ FieldDefinition.getTimeSeriesChildren = function(field) {
14254
+ return FieldDefinition._timeSeriesChildren[field];
14255
+ };
14256
+ /** @public
14257
+ * @function
14258
+ * @param {string} tsDef
14259
+ * @param {Object} childDef
14260
+ */
14261
+ FieldDefinition.addTimeSeriesChild = function(tsDef, childDef) {
14262
+ if(!FieldDefinition._timeSeriesChildren[tsDef]) {
14263
+ FieldDefinition._timeSeriesChildren[tsDef] = [];
14264
+ }
14265
+ FieldDefinition._timeSeriesChildren[tsDef].push(childDef);
14266
+ };
14267
+ /** @public
14268
+ * @function
14269
+ * @param {string} field
14186
14270
  */
14187
14271
  FieldDefinition.remove = function(field) {
14188
14272
  delete FieldDefinition._defs[field];
@@ -14205,6 +14289,24 @@ FieldDefinition.setFieldCaching = function (caching) {
14205
14289
  FieldDefinition._caching = caching;
14206
14290
  };
14207
14291
 
14292
+ /** @public
14293
+ * @param {string} field
14294
+ * @return {boolean}=true if field is time series field
14295
+ */
14296
+ FieldDefinition.isTimeSeriesField = function (field) {
14297
+ /*
14298
+ ^TR. => start with TR.
14299
+ [\w]+ => any field with string and value
14300
+ [\(] => open bucket (
14301
+ [\w\-\=\,]* => any property name and follow by = EX. SDATE=2011-11-11, PRIOD=123123
14302
+ EDATE\=+ => EDATE in bucket
14303
+ [\w\-\=\,]+ => another propertie param
14304
+ [\)]$ => end with only )
14305
+ */
14306
+
14307
+ return !!field.toUpperCase().match(/^TR.[\w]+[\(][\w\-\=\,]*EDATE\=+[\w\-\=\,]+[\)]$/g);
14308
+ };
14309
+
14208
14310
  /** to get more info about field via synapse service
14209
14311
  * @private
14210
14312
  * @param {string} field
@@ -14563,8 +14665,17 @@ var ColumnDefinition = function(columnOption, hostGrid) {
14563
14665
 
14564
14666
  this._classes = [];
14565
14667
  this._requiredFields = [];
14668
+ this._children = [];
14669
+ this._parent = [];
14670
+
14671
+ if(columnOption) {
14672
+ if(columnOption["parent"]) { // WARNING: This assume time series child, when have a parent
14673
+ this._initializeTimeSeriesChild(columnOption);
14674
+ } else {
14675
+ this.initialize(columnOption);
14676
+ }
14677
+ }
14566
14678
 
14567
- this.initialize(columnOption);
14568
14679
  };
14569
14680
  //#region Private Members
14570
14681
  /** @type {string}
@@ -14645,6 +14756,10 @@ ColumnDefinition.prototype._eventArg;
14645
14756
  * @private
14646
14757
  */
14647
14758
  ColumnDefinition.prototype._realTimeField = false;
14759
+ /** @type {boolean}
14760
+ * @private
14761
+ */
14762
+ ColumnDefinition.prototype._autoGenerated = false;
14648
14763
 
14649
14764
  /** @type {!Array.<string>}
14650
14765
  * @private
@@ -14681,6 +14796,19 @@ ColumnDefinition.prototype._textSelect = false;
14681
14796
  * @private
14682
14797
  */
14683
14798
  ColumnDefinition.prototype._userModel = null;
14799
+
14800
+ /** @type {Grid~ColumnDefinition}
14801
+ * @private
14802
+ */
14803
+ ColumnDefinition.prototype._parent = null;
14804
+ /** @type {Array<ColumnDefinition>}
14805
+ * @private
14806
+ */
14807
+ ColumnDefinition.prototype._children = null;
14808
+ /** @type {boolean}
14809
+ * @private
14810
+ */
14811
+ ColumnDefinition.prototype._timeSeriesField = false;
14684
14812
  /** @type {Object}
14685
14813
  * @private
14686
14814
  */
@@ -14696,8 +14824,20 @@ ColumnDefinition.prototype.dispose = function() {
14696
14824
  this.setRenderer(null); // this._userRenderers are removed
14697
14825
  this.setSorter(null);
14698
14826
  this._userModel = null;
14827
+ this._parent = null;
14828
+ this._children = null;
14699
14829
  // TODO: Remove any related reference from this._fnEngine
14700
14830
  };
14831
+
14832
+ /** @public
14833
+ * @param {ColumnDefinition~Options|string=} columnOption
14834
+ */
14835
+ ColumnDefinition.prototype._initializeTimeSeriesChild = function(columnOption) {
14836
+ this._autoGenerated = true;
14837
+ var parentDef = /** @type{ColumnDefinition} */(columnOption["parent"]);
14838
+ this._setParent(parentDef);
14839
+ this.initialize(columnOption);
14840
+ };
14701
14841
  /** @public
14702
14842
  * @param {ColumnDefinition~Options|string=} columnOption
14703
14843
  */
@@ -14996,6 +15136,12 @@ ColumnDefinition.prototype.isRealTimeField = function() {
14996
15136
  /** @public
14997
15137
  * @return {boolean}
14998
15138
  */
15139
+ ColumnDefinition.prototype.isTimeSeriesField = function() {
15140
+ return this._timeSeriesField;
15141
+ };
15142
+ /** @public
15143
+ * @return {boolean}
15144
+ */
14999
15145
  ColumnDefinition.prototype.isFormulaField = function() {
15000
15146
  return this._formula ? true : false;
15001
15147
  };
@@ -15181,6 +15327,10 @@ ColumnDefinition.prototype.getConfigObject = function(colOptions) {
15181
15327
  obj["headerAlignment"] = this._headerAlignment;
15182
15328
  }
15183
15329
 
15330
+ if(this._autoGenerated) {
15331
+ obj["autoGenerated"] = this._autoGenerated;
15332
+ }
15333
+
15184
15334
  var core = this._eventArg["core"];
15185
15335
  var grid = this._eventArg["grid"];
15186
15336
  var colIndex = grid.getColumnIndex(this);
@@ -15258,6 +15408,53 @@ ColumnDefinition.prototype.setRenderer = function(func) {
15258
15408
  this._userRenderers = null;
15259
15409
  }
15260
15410
  };
15411
+
15412
+
15413
+ /** @public
15414
+ * @return {ColumnDefinition}
15415
+ */
15416
+ ColumnDefinition.prototype.getParent = function() {
15417
+ return this._parent;
15418
+ };
15419
+
15420
+
15421
+ /**
15422
+ * @private
15423
+ * @param {ColumnDefinition} parentDef
15424
+ * @return {boolean}=true if have any change
15425
+ */
15426
+ ColumnDefinition.prototype._setParent = function(parentDef) {
15427
+ if(this._parent === parentDef || parentDef === this) { // The same parent is given
15428
+ return false;
15429
+ }
15430
+
15431
+ if(parentDef) {
15432
+ this._parent = parentDef;
15433
+ this._parent._addChild(this); // sync child and parent
15434
+ }
15435
+ return false;
15436
+ };
15437
+
15438
+
15439
+ /**
15440
+ * @public
15441
+ * @return {Array.<ColumnDefinition>}
15442
+ */
15443
+ ColumnDefinition.prototype.getChildren = function() {
15444
+ return this._children;
15445
+ };
15446
+
15447
+ /**
15448
+ * @private
15449
+ * @param {string} colDef Child column definition
15450
+ */
15451
+ ColumnDefinition.prototype._addChild = function(colDef) {
15452
+ if(this === colDef || this._children.indexOf(colDef) > -1) {
15453
+ return;
15454
+ }
15455
+ this._children.push(colDef);
15456
+ };
15457
+
15261
15458
  /** Add more renderer to the existing list
15262
15459
  * @public
15263
15460
  * @param {Function} func
@@ -15324,6 +15521,13 @@ ColumnDefinition.prototype.isRowSorting = function() {
15324
15521
  return this._rowSorting ? true : false;
15325
15522
  };
15326
15523
 
15524
+ /** @public
15525
+ * @return {boolean}
15526
+ */
15527
+ ColumnDefinition.prototype.isAutoGenerated = function() {
15528
+ return this._autoGenerated;
15529
+ };
15530
+
15327
15531
  /** To allow user change column name in run-time (language change or localization)
15328
15532
  * @public
15329
15533
  * @param {string} str
@@ -15374,6 +15578,13 @@ ColumnDefinition.prototype._setField = function(field, formulaStr) {
15374
15578
  this._emptyField = false;
15375
15579
  this._realTimeField = field ? true : false;
15376
15580
  }
15581
+
15582
+ if(js_FieldDefinition.isTimeSeriesField(field)) {
15583
+ // children will be clone the config from parent too
15584
+ this._realTimeField = false;
15585
+ this._timeSeriesField = true;
15586
+ }
15587
+
15377
15588
  this._isDefaultName = true;
15378
15589
  this._updateContext("field", field);
15379
15590
  if(this.isRealTimeField()) { // Only realtime field will have a formatted field
@@ -15490,6 +15701,7 @@ ColumnDefinition.prototype.getColumnInfo = function() {
15490
15701
 
15491
15702
 
15492
15703
 
15704
+
15493
15705
  /** @private
15494
15706
  * @param {Object} obj
15495
15707
  * @return {boolean}
@@ -15676,10 +15888,19 @@ SnapshotFiller.prototype._onRequest = function () {
15676
15888
  var instruments = Object.keys(this._rics);
15677
15889
 
15678
15890
  var i;
15679
- var fields = Object.keys(this._fields);
15891
+ var fields = [];
15892
+ var timeSeriesFields = [];
15893
+ for (var field in this._fields) {
15894
+ if(!FieldDefinition.isTimeSeriesField(field)) {
15895
+ fields.push(field);
15896
+ } else {
15897
+ timeSeriesFields.push(field);
15898
+ }
15899
+ }
15680
15900
  var fieldLen = fields.length;
15901
+ var timeSeriesFieldLen = timeSeriesFields.length;
15681
15902
 
15682
- if (!fieldLen || !instruments.length) { // No ADC field or real-time RIC
15903
+ if ( (!fieldLen && !timeSeriesFieldLen ) || !instruments.length) { // No ADC field or real-time RIC
15683
15904
  return;
15684
15905
  }
15685
15906
 
@@ -15689,21 +15910,47 @@ SnapshotFiller.prototype._onRequest = function () {
15689
15910
 
15690
15911
  var onSuccess, payload;
15691
15912
  if (this._rtk) {
15692
- var strFields = fields.join(',');
15693
- payload = {
15694
- "method": "select",
15695
- "formula": strFields,
15696
- "identifiers": instruments,
15697
- "productId": this._adcOptions.productId,
15698
- "output": "Col,In,va,T,NoEmptyTickers" // For customize output server, for more information please visit "https://confluence.refinitiv.com/display/ADC/Data+Cloud+Output+Format"
15699
- };
15700
- onSuccess = this._onRTKSuccess.bind(this, fields);
15701
- this._rtk.Data.Adc
15702
- .request(payload)
15703
- .then(onSuccess)
15704
- .catch(function (err) {
15705
- console.log(err);
15706
- });
15913
+ var strFields;
15914
+ // Request time serie fields
15915
+ if(timeSeriesFields.length > 0) {
15916
+ // request time series field
15917
+ var strtTimeSeriesFields = timeSeriesFields.join(',');
15918
+ payload = {
15919
+ "method": "select",
15920
+ "formula": strtTimeSeriesFields,
15921
+ "identifiers": instruments,
15922
+ "productId": this._adcOptions.productId,
15923
+ "output": "Col,date|,Row,In|,va,T,NoEmptyTickers" // For customize output server, for more information please visit "https://confluence.refinitiv.com/display/ADC/Data+Cloud+Output+Format"
15924
+ };
15925
+ onSuccess = this._onRTKTimeSeriesSuccess.bind(this, timeSeriesFields);
15926
+ this._rtk.Data.Adc
15927
+ .request(payload)
15928
+ .then(onSuccess)
15929
+ .catch(function (err) {
15930
+ console.log(err);
15931
+ });
15932
+ }
15933
+
15934
+ // Request normal adc field
15935
+ if(fields.length > 0) {
15936
+ strFields = fields.join(',');
15937
+ payload = {
15938
+ "method": "select",
15939
+ "formula": strFields,
15940
+ "identifiers": instruments,
15941
+ "productId": this._adcOptions.productId,
15942
+ "output": "Col,In,va,T,NoEmptyTickers" // For customize output server, for more information please visit "https://confluence.refinitiv.com/display/ADC/Data+Cloud+Output+Format"
15943
+ };
15944
+ onSuccess = this._onRTKSuccess.bind(this, fields);
15945
+ this._rtk.Data.Adc
15946
+ .request(payload)
15947
+ .then(onSuccess)
15948
+ .catch(function (err) {
15949
+ console.log(err);
15950
+ });
15951
+ }
15952
+
15953
+
15707
15954
  } else {
15708
15955
  var reqFields = [];
15709
15956
  for(i = 0; i < fieldLen; i++) {
@@ -15865,6 +16112,78 @@ SnapshotFiller.prototype._onRTKSuccess = function (fields, serverResult) {
15865
16112
  };
15866
16113
 
15867
16114
 
16115
+ /** @private
16116
+ * @function
16117
+ * @param {Array.<string>} fields
16118
+ * @param {string} serverResult
16119
+ */
16120
+ SnapshotFiller.prototype._onRTKTimeSeriesSuccess = function (fields, serverResult) {
16121
+
16122
+ // TODO: noti the user for change structure
16123
+ this._dispatch("adcDataReceived", serverResult);
16124
+ var data2D = serverResult["rows"];
16125
+ var svHeaders = serverResult["rows"] && serverResult["rows"][0];
16126
+ if (!Array.isArray(data2D) || !Array.isArray(svHeaders)) {
16127
+ return; // TODO: Return Promise.reject(errMsg);
16128
+ }
16129
+
16130
+ var headerLen = svHeaders.length;
16131
+
16132
+ var headerDates = [];
16133
+ var i, j;
16134
+
16135
+ for (i = 2; i < headerLen; i++) { // Start with 2 (Skip instrunment and date header)
16136
+ headerDates.push(svHeaders[i].v);
16137
+ }
16138
+
16139
+ var ric, j, field;
16140
+ var len = data2D.length;
16141
+ var ricMap = {};
16142
+ var childrenFieldToParent = {};
16143
+
16144
+ var fileNameToTSField = {};
16145
+ var count = 0;
16146
+ for (let i = 1; i < len; i++) {
16147
+ var dataRow = data2D[i];
16148
+ var fieldName = dataRow[1];
16149
+ if(!fileNameToTSField[fieldName]) {
16150
+ fileNameToTSField[fieldName] = fields[count++];
16151
+ }
16152
+ }
16153
+
16154
+ // TODO: Freeze the data view before setting multiple data
16155
+ for (i = 1; i < len; i++) { // to skip column header index, use i = 1
16156
+ var dataRow = data2D[i];
16157
+ ric = dataRow[0];
16158
+ var fieldName = dataRow[1]; // ex. PRICECLOSE
16159
+ if(!ricMap[ric]) {
16160
+ ricMap[ric] = {};
16161
+ }
16162
+ var snapData = ricMap[ric];
16163
+ for (var k = 0; k < headerDates.length; k++) {
16164
+ field = fileNameToTSField[fieldName].replace("TR.", "") + "_" + headerDates[k]; // TODO: make support time series field definition cache
16165
+ childrenFieldToParent[field] = fileNameToTSField[fieldName];
16166
+ snapData[field] = dataRow[2 + k]; // Start with field value
16167
+ }
16168
+ }
16169
+
16170
+ // return result only ric that has update data
16171
+ var dataMapping = {};
16172
+ for (ric in ricMap) {
16173
+ var obj = ricMap[ric];
16174
+ if (!isEmptyObject(obj)) {
16175
+ dataMapping[ric] = obj;
16176
+ }
16177
+ }
16178
+
16179
+ this._dispatch("dataChanged", {
16180
+ data: dataMapping,
16181
+ timeSeries: true,
16182
+ childrenFieldToParent: childrenFieldToParent
16183
+ });
16184
+ };
16185
+
16186
+
15868
16187
  /* harmony default export */ var js_SnapshotFiller = (SnapshotFiller);
15869
16188
 
15870
16189
  // CONCATENATED MODULE: ./node_modules/@grid/core/es6/grid/components/ElementWrapper.js
@@ -34196,7 +34515,7 @@ Core.prototype._rowHeightTimerId = 0;
34196
34515
  * @return {string}
34197
34516
  */
34198
34517
  Core.getVersion = function () {
34199
- return "5.1.25";
34518
+ return "5.1.26";
34200
34519
  };
34201
34520
  /** {@link ElementWrapper#dispose}
34202
34521
  * @override
@@ -41708,6 +42027,13 @@ var excludeAutoGenerated = function (rowDef) {
41708
42027
  return !rowDef.isAutoGenerated();
41709
42028
  };
41710
42029
 
42030
+ /** @private
42031
+ * @param {Object} colConfig column config
42032
+ * @return {boolean}
42033
+ */
42034
+ var _byNonAutoGeneratedColumn = function (colConfig) {
42035
+ return !colConfig.autoGenerated;
42036
+ };
41711
42037
  /** @private
41712
42038
  * @param {string} rowDefA
41713
42039
  * @param {string} rowDefB
@@ -41733,6 +42059,8 @@ var Grid = function(placeholder, config) {
41733
42059
  t._recalculateFormulas = t._recalculateFormulas.bind(t);
41734
42060
  t._updateStreamingData = t._updateStreamingData.bind(t);
41735
42061
  t.updateColumnTitle = t.updateColumnTitle.bind(t);
42062
+ t._insertTimeSeriesChildren = t._insertTimeSeriesChildren.bind(t);
42063
+
41736
42064
 
41737
42065
  t._onPostSectionDataBinding = t._onPostSectionDataBinding.bind(t);
41738
42066
  t._asyncClearDataUpdates = t._asyncClearDataUpdates.bind(t);
@@ -41756,6 +42084,8 @@ var Grid = function(placeholder, config) {
41756
42084
  t._formulaConflator = new Conflator(300, t._onFormulaDataChanged);
41757
42085
  t._chainConflator = new Conflator(100, t._addMemberOfChain);
41758
42086
  t._columnTitleConflator = new Conflator(0, t.updateColumnTitle);
42087
+ t._timeSeriesChildConflator = new Conflator(0, t._insertTimeSeriesChildren);
42088
+
41759
42089
 
41760
42090
  t._defaultColumnOptions = {};
41761
42091
 
@@ -42502,8 +42832,8 @@ Grid.prototype.getConfigObject = function (gridOptions) {
42502
42832
  grid.getConfigObject(obj);
42503
42833
  }
42504
42834
 
42505
- var i;
42506
- var len = this.getColumnCount();
42835
+ var i, len;
42836
+ len = this.getColumnCount();
42507
42837
  for (i = 0; i < len; ++i) {
42508
42838
  var column = columns[i];
42509
42839
  if(!column) {
@@ -42514,6 +42844,8 @@ Grid.prototype.getConfigObject = function (gridOptions) {
42514
42844
  colDef.getConfigObject(column);
42515
42845
  }
42516
42846
 
42847
+ obj.columns = columns = columns.filter(_byNonAutoGeneratedColumn);
42848
+
42517
42849
  if(this._topNode.style.overflow === "") {
42518
42850
  obj["scrollbar"] = false;
42519
42851
  }
@@ -42754,6 +43086,116 @@ Grid.prototype.insertColumn = function (columnOption, idx) {
42754
43086
  this._grid.insertColumn(idx, configObj); // columnAdded is fired
42755
43087
  };
42756
43088
 
43089
+ /** @private
43090
+ * @param {Object} e snapshort change event object
43091
+ */
43092
+ Grid.prototype._updateTimeSeriesFields = function (e) {
43093
+ var snapShortData = e.data;
43094
+ var childFields;
43095
+ for (var ric in snapShortData) {
43096
+ childFields = snapShortData[ric];
43097
+ this.setRicData(ric, snapShortData[ric]);
43098
+ }
43099
+ var parentField, field, colIndex, parentColDef, childColIndex;
43100
+
43101
+ var firstField;
43102
+ for (field in childFields) {
43103
+ firstField = field;
43104
+ break;
43105
+ }
43106
+
43107
+ parentField = e.childrenFieldToParent[firstField];
43108
+ colIndex = this.getColumnIndex(parentField);
43109
+ this._grid.setColumnVisibility(colIndex);
43110
+ parentColDef = this._getColumnDefinition(colIndex);
43111
+
43112
+
43113
+ var children = parentColDef.getChildren();
43114
+ var i, len, childDef, childField;
43115
+ len = children.length;
43116
+ if(len > 0){
43117
+ for (i = 0; i < len; i++) {
43118
+ childDef = children[i];
43119
+ childField = childDef.getField();
43120
+ if(!childFields[childField]) {
43121
+ this.removeColumn(childField);
43122
+ }
43123
+ }
43124
+ }
43125
+
43126
+ for (childField in childFields) {
43127
+ parentField = e.childrenFieldToParent[childField];
43128
+ colIndex = this.getColumnIndex(parentField);
43129
+ parentColDef = this._getColumnDefinition(colIndex);
43130
+ childColIndex = this.getColumnIndex(childField);
43131
+ if(childColIndex < 0) { // not found column index in view tried to clone from parent
43132
+ this._cloneTimeSeriesColumn(parentColDef, childField, colIndex);
43133
+ js_FieldDefinition.addTimeSeriesChild(parentField, childField);
43134
+ }
43135
+ }
43136
+
43137
+ };
43138
+
43139
+
43140
+ /** @private
43141
+ * @param {ColumnDefinition} colDef
43142
+ */
43143
+ Grid.prototype._insertTimeSeriesChildren = function (colDef) {
43144
+ if(this._timeSeriesChildConflator.conflate(colDef) ) {
43145
+ return;
43146
+ }
43147
+
43148
+ var colDefs = this._timeSeriesChildConflator.popAllData();
43149
+ var i, j, len, childField, idx;
43150
+
43151
+ for (i = 0; i < colDefs.length; i++) {
43152
+ colDef = colDefs[i];
43153
+ idx = this.getColumnIndex(colDef);
43154
+ this._grid.setColumnVisibility(idx); // hide parent field
43155
+
43156
+ if(!colDef) {
43157
+ continue;
43158
+ }
43159
+ var childFields = js_FieldDefinition.getTimeSeriesChildren(colDef.getField());
43160
+ if(!childFields) { // not found time series field
43161
+ return;
43162
+ }
43163
+
43164
+ len = childFields.length;
43165
+ if(len < 1) {
43166
+ return; // normal field
43167
+ }
43168
+
43169
+ for (j = 0; j < len; j++) {
43170
+ idx = this.getColumnIndex(colDef);
43171
+ childField = childFields[j];
43172
+ this._cloneTimeSeriesColumn(colDef, childField, idx);
43173
+ }
43174
+ }
43175
+
43176
+ };
43177
+
43178
+ /** @private
43179
+ * @param {ColumnDefinition} parentColDef Parent definition
43180
+ * @param {string} childField field
43181
+ * @param {number} idx index of insertion column
43182
+ */
43183
+ Grid.prototype._cloneTimeSeriesColumn = function (parentColDef, childField, idx) {
43184
+ var parentConfig, columnOption, obj, key;
43185
+ parentConfig = parentColDef.getConfigObject();
43186
+ obj = {};
43187
+ for (key in parentConfig) {
43188
+ if(key !== "hidden") {
43189
+ obj[key] = parentConfig[key];
43190
+ }
43191
+ }
43192
+ columnOption = Object(Util["b" /* cloneObject */])(obj);
43193
+ columnOption["field"] = childField.replace("TR.", "");
43194
+ columnOption["name"] = childField.split("_")[1].split("T")[0]; // Currently, response server format utc date ex "2022-11-23T00:00:00"
43195
+ columnOption["parent"] = parentColDef;
43196
+ this.insertColumn(columnOption, idx++);
43197
+
43198
+ };
42757
43199
 
42758
43200
  /** @public
42759
43201
  * @param {ColumnDefinition~Options|string} columnOption String will be treated as field, while object is treated as the column options
@@ -42815,6 +43257,10 @@ Grid.prototype.replaceColumn = function (columnOption, colRef) {
42815
43257
  colConfig["width"] = 1;
42816
43258
  }
42817
43259
 
43260
+ var colDef = this.getColumnDefinition(colIndex);
43261
+ if(colDef.getChildren()) { // Parent time series field doesn't provide hidden property
43262
+ colConfig["hidden"] = false;
43263
+ }
42818
43264
  this.insertColumn(colConfig, colIndex);
42819
43265
  this.removeColumn(colIndex + 1); // remove existing column after insert
42820
43266
  };
@@ -42851,7 +43297,15 @@ Grid.prototype._onFieldLoadedError = function (err) {
42851
43297
  * @param {string} referrer
42852
43298
  */
42853
43299
  Grid.prototype._onFieldLoaded = function (field, referrer) {
42854
- this._connector.addFields(field, referrer);
43300
+ // async process, the field can be remove before column added
43301
+ var colIndex = this.getColumnIndex(field);
43302
+ if(colIndex > -1) {
43303
+ var colDef = this._getColumnDefinition(field);
43304
+ if(colDef.isTimeSeriesField()) {
43305
+ this._insertTimeSeriesChildren(colDef);
43306
+ }
43307
+ this._connector.addFields(field, referrer);
43308
+ }
42855
43309
  };
42856
43310
 
42857
43311
  /**
@@ -42880,8 +43334,8 @@ Grid.prototype._shouldLoadFieldInfo = function (field, isRealTime) {
42880
43334
  var fieldDef = js_FieldDefinition.get(field);
42881
43335
  if (!fieldDef &&
42882
43336
  field !== 'X_RIC_NAME' && // ignore X_RIC_NAME
42883
- (isRealTime || ColumnDefinition.isAdcField(field)) &&
42884
- (this._RTK || window["JET"])
43337
+ (isRealTime || ColumnDefinition.isAdcField(field)) && // realtime field or adc field (Without static field)
43338
+ (this._RTK || window["JET"]) // have rtk instance or window jet sub
42885
43339
  ) {
42886
43340
  return true;
42887
43341
  }
@@ -43007,9 +43461,15 @@ Grid.prototype._onColumnAdded = function(e) {
43007
43461
  onLoaded = this._onFieldLoaded.bind(this, field, referrer);
43008
43462
  prom = prom.then(onLoaded).catch(onLoaded);
43009
43463
  } else {
43464
+ if(colDef.isTimeSeriesField()) {
43465
+ this._insertTimeSeriesChildren(colDef);
43466
+ }
43010
43467
  this._connector.addFields(field, referrer);
43011
43468
  }
43012
43469
  } else {
43470
+ if(colDef.isTimeSeriesField()) {
43471
+ this._insertTimeSeriesChildren(colDef);
43472
+ }
43013
43473
  this._connector.addFields(field, referrer);
43014
43474
  }
43015
43475
  }
@@ -43027,6 +43487,19 @@ Grid.prototype.removeColumn = function(colRef) {
43027
43487
  }
43028
43488
 
43029
43489
  var colDef = this.getColumnDefinition(colIndex);
43490
+ var children = colDef.getChildren();
43491
+ if(children) {
43492
+ var len = children.length;
43493
+ if(len > 0) { // remove time series child
43494
+ var i, childDef;
43495
+ for (i = 0; i < len; i++) {
43496
+ childDef = children[i];
43497
+ this.removeColumn(childDef);
43498
+ }
43499
+ colIndex = this.getColumnIndex(colRef); // children in parent will be remove the parent should be get new index
43500
+ }
43501
+ }
43502
+
43030
43503
  if(!colDef.isRealTimeField()) {
43031
43504
  if(this._dc) {
43032
43505
  this._dc.removeStaticFields([colDef.getField()]);
@@ -43099,6 +43572,7 @@ Grid.prototype.removeAllColumns = function() {
43099
43572
  // TODO: Remove fields that are related to the column (e.g. fields for coloring)
43100
43573
 
43101
43574
  this._columnTitleConflator.reset();
43575
+ this._timeSeriesChildConflator.reset();
43102
43576
 
43103
43577
  this._connector.removeAllFields();
43104
43578
  this._grid.setColumnCount(0);
@@ -43127,7 +43601,22 @@ Grid.prototype.moveColumn = function (fromColIndex, toColIndex) {
43127
43601
  */
43128
43602
  Grid.prototype.hideColumn = function(colRef, hidden) {
43129
43603
  var colIndex = this.getColumnIndex(colRef);
43130
- this._grid.hideColumn(colIndex, hidden);
43604
+ if(colIndex < 0) { // not found
43605
+ return;
43606
+ }
43607
+ var colDef = this.getColumnDefinition(colIndex);
43608
+ var children = colDef.getChildren();
43609
+ var len = children.length;
43610
+ if(len > 0) { // remove time series child, and parent shouldn't unHide
43611
+ var i, childDef;
43612
+ for (i = 0; i < len; i++) {
43613
+ childDef = children[i];
43614
+ this.hideColumn(childDef, hidden);
43615
+ }
43616
+ } else {
43617
+ this._grid.hideColumn(colIndex, hidden);
43618
+ }
43619
+
43131
43620
  };
43132
43621
  /** Hide multiple columns at once. The hidden columns still occupy the same index.
43133
43622
  * @public
@@ -43744,6 +44233,28 @@ Grid.prototype.setRic = function(rowRef, str) {
43744
44233
  }
43745
44234
  }
43746
44235
  };
44236
+ /** Unlink the chain and its constituents. When the chain is expanded,
44237
+ * the chain row and its members are converted from autogenerated to
44238
+ * regular real-time rows. Only the chain row will be transformed to
44239
+ * a conventional real-time row if the chain is collapsed.
44240
+ * All converted rows will continue to have their data updated.
44241
+ *
44242
+ * @public
44243
+ * @param {Grid~RowReference} rowRef
44244
+ */
44245
+ Grid.prototype.unlinkChain = function(rowRef) {
44246
+ var rowDef = this._getRowDefinition(rowRef);
44247
+ if(!rowDef) {
44248
+ return;
44249
+ }
44250
+
44251
+ if(!rowDef.isChain()) {
44252
+ return;
44253
+ }
44254
+
44255
+ rowDef.unlinkChain();
44256
+ };
44257
+
43747
44258
  /** Alias to setRic
43748
44259
  * @public
43749
44260
  * @function
@@ -43907,6 +44418,7 @@ Grid.prototype._getAllColumnDefinitions = function() {
43907
44418
  }
43908
44419
  return colDefs;
43909
44420
  };
44421
+
43910
44422
  /** @public
43911
44423
  * @param {number|string} rowRef Row index as shown in the view or row id (string)
43912
44424
  * @return {RowDefinition}
@@ -44662,9 +45174,14 @@ Grid.prototype._snapshotFillerDataChanged = function (e) {
44662
45174
  if (!this._dt) return;
44663
45175
 
44664
45176
  var data = e.data;
44665
- for (var ric in data) {
44666
- this.setRicData(ric, data[ric]);
45177
+ if(e.timeSeries) {
45178
+ this._updateTimeSeriesFields(e); // Increase or decrease time series field
45179
+ } else {
45180
+ for (var ric in data) {
45181
+ this.setRicData(ric, data[ric]);
45182
+ }
44667
45183
  }
45184
+
44668
45185
  if(!this._lastPollingRequest) { // This is the first time we receive successful ADC response
44669
45186
  this._lastPollingRequest = 1; // Allow polling to be started
44670
45187
  }
@@ -47020,6 +47537,7 @@ MockArchive.prototype.filter = function(func) {
47020
47537
  // CONCATENATED MODULE: ./node_modules/tr-grid-util/es6/jet/mockDataAPI.js
47021
47538
 
47022
47539
 
47540
+
47023
47541
  /**
47024
47542
  * @private
47025
47543
  * @type {object}
@@ -47044,6 +47562,7 @@ function setInvalidFields(fields) {
47044
47562
  }
47045
47563
  }
47046
47564
 
47565
+
47047
47566
  var dataGen = new DataGenerator();
47048
47567
 
47049
47568
  /** @private
@@ -47145,70 +47664,207 @@ Adc.request = function (payload, mockResponse) {
47145
47664
  return Promise.resolve(JSON.stringify(mockResponse));
47146
47665
  }
47147
47666
 
47148
- var i, f, len, row;
47149
- var identifiers = payload.identifiers;
47150
- var formula = payload.formula.split(",");
47151
- var fields = [];
47667
+ // build row header
47668
+ var rows = [];
47669
+ var i, f, len, row, j;
47670
+ var identifiers, formula, fields, invalidDict;
47671
+ if(payload.output === "Col,date|,Row,In|,va,T,NoEmptyTickers") {
47672
+
47673
+ identifiers = payload.identifiers;
47674
+ formula = payload.formula.trim().split(/(?=,TR.)/);// TODO: check each field with another way, this doesn't work when user use some comma (,) formula
47675
+ fields = [];
47676
+
47677
+ // _invalidFieldDict is a dictionary of non exist field
47678
+ // so we must remove invalid field to make "mocking api" return result more like a "real api".
47679
+ invalidDict = _invalidFieldDict;
47680
+ for (i = 0; i < formula.length; i++) {
47681
+ f = formula[i];
47682
+ if (!invalidDict[f]) {
47683
+ fields.push(f);
47684
+ }
47685
+ }
47686
+
47687
+ var fieldCount = fields.length;
47688
+ // formula = payload.formula.trim().split(",TR"); // TODO: split wit
47689
+
47690
+ rows.push([
47691
+ {
47692
+ "h": true,
47693
+ "i": "instrument",
47694
+ "v": "Instrument"
47695
+ },
47696
+ {
47697
+ "h": true,
47698
+ "i": "date",
47699
+ "v": "Date"
47700
+ }
47701
+ ]);
47702
+
47703
+ for (var index = 0; index < fieldCount; index++) {
47704
+ var timeSeriesField = fields[index];
47705
+
47706
+ var regex = /TR.(.*)(?=\()/;
47707
+ var result = timeSeriesField.match(regex);
47708
+ var field = result[0].replace("TR.", "");
47709
+ var phrase = timeSeriesField.toLowerCase();
47710
+ var startDateRegex = /sdate=(.*)[,]/;
47711
+ var endDateRegex = /edate=(.*)[)]/;
47712
+ var startDateMatch = phrase.match(startDateRegex);
47713
+ var endDateMatch = phrase.match(endDateRegex);
47714
+
47715
+ var startDate = startDateMatch ? startDateMatch[1] : DateTime.format(new Date(), "YYYY-MM-DD");
47716
+ var endDate = endDateMatch[1];
47717
+
47718
+ var swapDateTmp;
47719
+ if(startDate > endDate) {
47720
+ swapDateTmp = startDate;
47721
+ startDate = endDate;
47722
+ endDate = swapDateTmp;
47723
+ }
47724
+
47725
+ var msBetweenDate = (+new Date(endDate)) - (+new Date(startDate));
47726
+
47727
+ var msInDay = 1000 * 60 * 60 * 24;
47728
+ var betweenDay = msBetweenDate / msInDay;
47729
+ // var betweenDay = Math.floor(Math.random() * 10); // For random length
47730
+
47731
+
47732
+ for (i = 0; i <= betweenDay; i++) {
47733
+ var date = new Date(new Date(startDate).setDate(new Date(startDate).getDate() + i));
47734
+ var fieldValue = {
47735
+ "h": true,
47736
+ "v": DateTime.format(date, "YYYY-MM-DDT00:00:00")
47737
+ };
47738
+ if(index === 0) { // add header 1 time
47739
+ rows[0].push(fieldValue);
47740
+ }
47741
+ }
47152
47742
 
47153
- // _invalidFieldDict is a dictionary of non exist field
47154
- // so we must remove invalid field to make "mocking api" return result more like a "real api".
47155
- var invalidDict = _invalidFieldDict;
47156
- for (i = 0; i < formula.length; i++) {
47157
- f = formula[i];
47158
- if (!invalidDict[f]) {
47159
- fields.push(f);
47743
+ var rics = identifiers;
47744
+ for (i = 0; i < rics.length; i++) {
47745
+
47746
+ var ric = rics[i];
47747
+ var rowValue = [
47748
+ ric,
47749
+ field
47750
+ ];
47751
+ for (j = 1; j <= betweenDay + 1; j++) {
47752
+ var generatedValue = DataGenerator.generateRecord(field);
47753
+ rowValue.push(generatedValue[field]);
47754
+
47755
+ }
47756
+ rows.push(rowValue);
47757
+ }
47758
+ // The example rows should be look like
47759
+ /*
47760
+ [
47761
+ [
47762
+ {
47763
+ "h": true,
47764
+ "i": "instrument",
47765
+ "v": "Instrument"
47766
+ },
47767
+ {
47768
+ "h": true,
47769
+ "i": "date",
47770
+ "v": "Date"
47771
+ },
47772
+ {
47773
+ "h": true,
47774
+ "v": "2011-08-11T00:00:00"
47775
+ },
47776
+ {
47777
+ "h": true,
47778
+ "v": "2011-08-12T00:00:00"
47779
+ },
47780
+ {
47781
+ "h": true,
47782
+ "v": "2011-08-15T00:00:00"
47783
+ }
47784
+ ],
47785
+ [
47786
+ "IBM",
47787
+ "Price Close", // NOTE: this cannot be detech we join it with space Ex. PriceClose
47788
+ 159.25449372,
47789
+ 160.6585848,
47790
+ 165.23382036
47791
+ ],
47792
+ [
47793
+ "GOOGL.O",
47794
+ "Price Close",
47795
+ 14.066881653,
47796
+ 14.107921423,
47797
+ 13.944262828
47798
+ ]
47799
+ ]
47800
+ */
47160
47801
  }
47161
- }
47162
47802
 
47163
- // build row header
47164
- var rows = [];
47165
- rows[0] = [{
47166
- "h": true,
47167
- "i": "instrument",
47168
- "v": "Instrument"
47169
- }];
47170
- for (i = 0; i < fields.length; i++) {
47171
- f = fields[i];
47172
- rows[0].push({
47173
- "h": true,
47174
- "r": f.toUpperCase()
47175
- // "v": "Price Close", // Doesn't use
47176
- // "p": "I_TRP_PH_PriceClose" // Doesn't use this property
47177
- });
47178
- }
47803
+ } else {
47179
47804
 
47180
- // build data
47181
- var rowMap = {};
47805
+ identifiers = payload.identifiers;
47806
+ formula = payload.formula.trim().split(","); // TODO: check each field with another way, this doesn't work when user use some comma (,) formula
47807
+ fields = [];
47182
47808
 
47183
- len = identifiers.length;
47184
- var rowData = dataGen.generate(fields, len);
47185
- for (i = 0; i < len; ++i) {
47186
- var inst = identifiers[i];
47187
- row = rowMap[inst];
47188
- if (!row) {
47189
- row = rowMap[inst] = rowData[i];
47190
- row.unshift(inst); // prepend instrument on each row
47809
+ // _invalidFieldDict is a dictionary of non exist field
47810
+ // so we must remove invalid field to make "mocking api" return result more like a "real api".
47811
+ invalidDict = _invalidFieldDict;
47812
+ for (i = 0; i < formula.length; i++) {
47813
+ f = formula[i];
47814
+ if (!invalidDict[f]) {
47815
+ fields.push(f);
47816
+ }
47191
47817
  }
47192
- rows.push(row);
47193
- }
47194
47818
 
47195
- // There is a chance that rtk will return multiple row data per instrument
47196
- // so we must create mock up for this case
47197
- if (rows.length > 0) {
47198
- var chance = dataGen.randInt(1, 10);
47199
- if (chance <= 3) { // chance 30%
47200
- var pos = dataGen.randInt(0, rows.length - 1); // random row pos
47201
- row = rows[pos];
47202
- len = row.length;
47203
- var mockupRow = new Array(len);
47204
- mockupRow[0] = row[0]; // 1st index is for instrument
47205
- for (i = 1; i < len; i++) {
47206
- mockupRow[i] = ''; // real case will return null or empty string
47819
+ rows[0] = [{
47820
+ "h": true,
47821
+ "i": "instrument",
47822
+ "v": "Instrument"
47823
+ }];
47824
+ for (i = 0; i < fields.length; i++) {
47825
+ f = fields[i];
47826
+ rows[0].push({
47827
+ "h": true,
47828
+ "r": f.toUpperCase().trim()
47829
+ // "v": "Price Close", // Doesn't use
47830
+ // "p": "I_TRP_PH_PriceClose" // Doesn't use this property
47831
+ });
47832
+ }
47833
+
47834
+ // build data
47835
+ var rowMap = {};
47836
+
47837
+ len = identifiers.length;
47838
+ var rowData = dataGen.generate(fields, len);
47839
+ for (i = 0; i < len; ++i) {
47840
+ var inst = identifiers[i];
47841
+ row = rowMap[inst];
47842
+ if (!row) {
47843
+ row = rowMap[inst] = rowData[i];
47844
+ row.unshift(inst); // prepend instrument on each row
47845
+ }
47846
+ rows.push(row);
47847
+ }
47848
+
47849
+ // There is a chance that rtk will return multiple row data per instrument
47850
+ // so we must create mock up for this case
47851
+ if (rows.length > 0) {
47852
+ var chance = dataGen.randInt(1, 10);
47853
+ if (chance <= 3) { // chance 30%
47854
+ var pos = dataGen.randInt(0, rows.length - 1); // random row pos
47855
+ row = rows[pos];
47856
+ len = row.length;
47857
+ var mockupRow = new Array(len);
47858
+ mockupRow[0] = row[0]; // 1st index is for instrument
47859
+ for (i = 1; i < len; i++) {
47860
+ mockupRow[i] = ''; // real case will return null or empty string
47861
+ }
47862
+ rows.splice(pos + 1, 0, mockupRow);
47207
47863
  }
47208
- rows.splice(pos + 1, 0, mockupRow);
47209
47864
  }
47210
47865
  }
47211
47866
 
47867
+
47212
47868
  /*
47213
47869
  response type is :
47214
47870
  {