@refinitiv-ui/efx-grid 6.0.125 → 6.0.127

Sign up to get free protection for your applications and to get access to all the features.
@@ -175,12 +175,6 @@ import { ElementWrapper } from "../../core/es6/grid/components/ElementWrapper.js
175
175
  * @description Fired only when a row will be removed through Grid's API and before occurring of the actual removal
176
176
  */
177
177
 
178
- /** @type {string}
179
- * @private
180
- * @const
181
- */
182
- const SUB_ID = "SUB_ID";
183
-
184
178
  /** @private
185
179
  * @param {RowDefinition} rowDef
186
180
  * @return {Object}
@@ -315,10 +309,10 @@ let Grid = function(placeholder, config) {
315
309
 
316
310
  t._onDataChanged = t._onDataChanged.bind(t);
317
311
  t._onQuote2PostUpdate = t._onQuote2PostUpdate.bind(t);
312
+ t._onQ2DataChanged = t._onQ2DataChanged.bind(t);
318
313
  t._onDataComposed = t._onDataComposed.bind(t);
319
314
  t._onSubSegmentChanged = t._onSubSegmentChanged.bind(t);
320
315
  t._recalculateFormulas = t._recalculateFormulas.bind(t);
321
- t._updateStreamingData = t._updateStreamingData.bind(t);
322
316
  t.updateColumnTitle = t.updateColumnTitle.bind(t);
323
317
  t._populateTimeSeriesChildren = t._populateTimeSeriesChildren.bind(t);
324
318
 
@@ -330,7 +324,7 @@ let Grid = function(placeholder, config) {
330
324
  t._updateRowData = t._updateRowData.bind(t);
331
325
  t._onFormulaDataChanged = t._onFormulaDataChanged.bind(t);
332
326
  t._onFormulaDataRequired = t._onFormulaDataRequired.bind(t);
333
- t._addMemberOfChain = t._addMemberOfChain.bind(t);
327
+ t._registerConstituents = t._registerConstituents.bind(t);
334
328
  t._onColumnAdded = t._onColumnAdded.bind(t);
335
329
  t._onRowExpansionBinding = t._onRowExpansionBinding.bind(t);
336
330
  t._onColumnHeaderBinding = t._onColumnHeaderBinding.bind(t);
@@ -345,9 +339,9 @@ let Grid = function(placeholder, config) {
345
339
  t._onVScroll = t._onVScroll.bind(t);
346
340
  t._selfScrollToRow = t._selfScrollToRow.bind(t);
347
341
 
348
- t._streamingConflator = new Conflator(50, t._updateStreamingData);
342
+ t._dcConflator = new Conflator(50, t._onDataChanged);
349
343
  t._formulaConflator = new Conflator(300, t._onFormulaDataChanged);
350
- t._chainConflator = new Conflator(100, t._addMemberOfChain);
344
+ t._chainConflator = new Conflator(100, t._registerConstituents);
351
345
  t._columnTitleConflator = new Conflator(0, t.updateColumnTitle);
352
346
  t._timeSeriesChildConflator = new Conflator(0, t._populateTimeSeriesChildren);
353
347
 
@@ -484,7 +478,7 @@ Grid.prototype._sharedDataSource = false;
484
478
  */
485
479
  Grid.prototype._sharedSorter = false;
486
480
 
487
- /** JET.Quotes2 Subscription
481
+ /** JET/RTK's Quotes2 subscription object
488
482
  * @type {Object}
489
483
  * @private
490
484
  */
@@ -502,7 +496,7 @@ Grid.prototype._columnSorter = null;
502
496
  /** @private
503
497
  * @type {Conflator}
504
498
  */
505
- Grid.prototype._streamingConflator = null;
499
+ Grid.prototype._dcConflator = null;
506
500
  /** @private
507
501
  * @type {SnapshotFiller}
508
502
  */
@@ -525,10 +519,6 @@ Grid.prototype._fnEngine = null;
525
519
  */
526
520
  Grid.prototype._formulaConflator = null;
527
521
 
528
- /** @private
529
- * @type {Object.<string, Object>}
530
- */
531
- Grid.prototype._chainMembers = null;
532
522
  /** @private
533
523
  * @type {Conflator}
534
524
  */
@@ -637,7 +627,15 @@ Grid.prototype.dispose = function() {
637
627
  this._grid.dispose();
638
628
  this._connector.reset();
639
629
 
640
- if(!this._sharedDataSource) { // make sure that it is the final grid, and that it will be dispose data
630
+ if(!this._sharedDataSource) { // Make sure that this is the final grid, and its data is disposed
631
+ if(this._subs) {
632
+ this._subs.removeEventListener("postUpdate", this._onQuote2PostUpdate);
633
+ this._subs.removeEventListener("dataChanged", this._onQ2DataChanged);
634
+ this._subs["dispose"]();
635
+ }
636
+ if(this._dc) {
637
+ this._dc.dispose();
638
+ }
641
639
  if(this._dt) {
642
640
  this._dt.dispose();
643
641
  }
@@ -645,12 +643,7 @@ Grid.prototype.dispose = function() {
645
643
  this._dv.dispose();
646
644
  }
647
645
  }
648
- this._mainGrid = this._dt = this._dv = null;
649
-
650
- if(this._subs) {
651
- this._subs["dispose"]();
652
- this._subs = null;
653
- }
646
+ this._mainGrid = this._dc = this._dt = this._dv = this._subs = null;
654
647
 
655
648
  if(this._focusingArgs) {
656
649
  _clearTimeout(this._focusingArgs.id);
@@ -679,7 +672,11 @@ Grid.prototype.listen = Grid.prototype.addEventListener;
679
672
  /** @public
680
673
  */
681
674
  Grid.prototype.initSubscription = function() {
682
- if(!this._dc || this._dc.getSubscriptions()) { // Subscription is already initialized
675
+ if(this._subs) { // Subscription is already initialized
676
+ return;
677
+ }
678
+ if(this._sharedDataSource) {
679
+ this._subs = this._mainGrid._subs;
683
680
  return;
684
681
  }
685
682
 
@@ -692,6 +689,9 @@ Grid.prototype.initSubscription = function() {
692
689
  }
693
690
  if(q) {
694
691
  s = q["create"]();
692
+ if(this._RTK && this._RTK.prefetchWorkaround) { // The workaround for RTK Quotes has a bug concerning the removal of the last row; it isn't removed.
693
+ s.addRic("DUMMY.WORKAROUND", "DUMMY.WORKAROUND");
694
+ }
695
695
  }
696
696
  if(!s) {
697
697
  return;
@@ -702,8 +702,8 @@ Grid.prototype.initSubscription = function() {
702
702
 
703
703
  this._subs = s;
704
704
  this._subs["start"]();
705
- this._dc.setSubscriptions(s);
706
705
  this._subs.addEventListener("postUpdate", this._onQuote2PostUpdate);
706
+ this._subs.addEventListener("dataChanged", this._onQ2DataChanged);
707
707
 
708
708
  // TODO: Subscriptions should be registered per row.
709
709
  // However, chain subscription cannot be integrated with DataConnector in this current implementation.
@@ -712,7 +712,7 @@ Grid.prototype.initSubscription = function() {
712
712
  for(let i = 0; i < len; ++i) {
713
713
  let rowDef = rowDefs[i];
714
714
  if(rowDef) {
715
- rowDef.subscribeForUpdates();
715
+ rowDef.subscribeForUpdates(s);
716
716
  }
717
717
  }
718
718
  };
@@ -2320,29 +2320,31 @@ Grid.prototype._initDuplicateRicData = function(rowDef) {
2320
2320
  };
2321
2321
 
2322
2322
  /** @private
2323
- * @param {Object} rowDef
2324
- * @param {Array<Object>} children
2323
+ * @param {Object} newRowDef
2325
2324
  */
2326
- Grid.prototype._cloneChain = function(rowDef) {
2327
- let rowDefs = this._connector.getRowDefByRic(rowDef.getSymbol());
2325
+ Grid.prototype._cloneChain = function(newRowDef) {
2326
+ let rowDefs = this._connector.getRowDefByRic(newRowDef.getSymbol());
2328
2327
  let firstRowDef = rowDefs ? rowDefs[0] : null;
2329
2328
  let constituents = firstRowDef ? firstRowDef.getChildren() : null;
2330
-
2331
- if(!constituents) {
2332
- return;
2333
- }
2334
- let count = constituents.length;
2335
- if(count < 0 ) {
2329
+ let count = constituents ? constituents.length : 0;
2330
+ if(count < 0) {
2336
2331
  return;
2337
2332
  }
2338
2333
 
2339
- let subId = rowDef.getData(SUB_ID);
2334
+ let subId = newRowDef.getSubId();
2335
+ if(!subId) {
2336
+ return; // A chain without subscription cannot have constituents
2337
+ }
2338
+ let evtArg = {
2339
+ "subId": subId
2340
+ };
2340
2341
  for (let i = 0; i < count; i++) {
2341
- let childRowDef = constituents[i];
2342
- let rowData = childRowDef.cloneRowData();
2343
- rowData["SUB_ID"] = subId;
2344
- let rid = subId + rowData["RIC"];
2345
- this._dc.setRowData(rid, rowData);
2342
+ let childRowDef = constituents[i]; // TODO: the constituents should be sorted by CHILD_ORDER first
2343
+ evtArg["ric"] = childRowDef.getRic();
2344
+ evtArg["values"] = childRowDef.cloneRowData();
2345
+ evtArg["values"]["SUB_ID"] = subId; // Imitate real-time service responses
2346
+
2347
+ this._onQ2DataChanged(evtArg); // WARNING: evtArg is shared across multiple calls
2346
2348
  }
2347
2349
  };
2348
2350
  /** @public
@@ -2368,7 +2370,7 @@ Grid.prototype.insertRow = function(rowOption, rowRef) {
2368
2370
  }
2369
2371
  }
2370
2372
  let rowDef = new RowDefinition(rowOption);
2371
- rowDef.setDataSource(this._dc); // This could also subscribe chain index/ric to JET/RTK
2373
+ rowDef.setDataSource(this._dc, this._subs); // This could also subscribe chain index/ric to JET/RTK
2372
2374
  this._initDuplicateRicData(rowDef);
2373
2375
 
2374
2376
  rowDef.registerToView(this._dv, this._getRowId(rowRef));
@@ -2680,17 +2682,16 @@ Grid.prototype.removeAllRows = function() {
2680
2682
  if(!this._dt.getRowCount()) {
2681
2683
  return;
2682
2684
  }
2685
+ // Data source is not shared at this point
2683
2686
  let rowDefs = this._getAllRowDefinitions();
2684
2687
 
2685
- if(!this._sharedDataSource) {
2686
- this._dc.clearAllData();
2687
- this._dt.clearAllData();
2688
- this._clearDataUpdates();
2689
- }
2688
+ this._dc.clearAllData();
2689
+ this._dt.clearAllData();
2690
+ this._clearDataUpdates();
2690
2691
 
2691
- rowDefs.forEach(RowDefinition.dispose);
2692
+ rowDefs.forEach(RowDefinition.dispose); // Each individual subscription is unsubscribed along with disposed rowDef
2692
2693
 
2693
- this._streamingConflator.reset();
2694
+ this._dcConflator.reset();
2694
2695
  this._formulaConflator.reset();
2695
2696
  this._chainConflator.reset();
2696
2697
  this._connector.removeAllRics();
@@ -3587,94 +3588,127 @@ Grid.prototype._onQuote2PostUpdate = function (e) {
3587
3588
  }
3588
3589
  };
3589
3590
 
3590
- /** @private
3591
- * @param {!Object} e
3592
- */
3593
- Grid.prototype._onDataChanged = function(e) {
3594
- let rowData = e["rowData"]; // Use rowData to retrieve corresponding subscription object
3595
- if (!rowData || this._unlinking) {
3596
- return; // This must be a global change
3591
+ /**
3592
+ * @private
3593
+ * @param {Object} e
3594
+ */
3595
+ Grid.prototype._onQ2DataChanged = function (e) {
3596
+ let subId = e["subId"];
3597
+ let rowDef = this._getRowDefinitionById(subId);
3598
+ if(!rowDef) {
3599
+ return; // WARNING: This should not be happened because row has been removed but the data is still received
3597
3600
  }
3598
- let rowDef = rowData[ROW_DEF];
3599
3601
 
3600
- if(rowDef) {
3601
- let rowId = rowDef.getRowId();
3602
- if(rowId) {
3603
- // e["rid"] could be from JET/RTK (rowId + ric) or static data update (rowId)
3604
- let curRowData = this._dc.getRowData(e["rid"]);
3605
- if (curRowData) {
3606
- if(rowDef.addUpdate(e)) { // This is the only place that update array can grow. It is used for blinking data.
3607
- this._dt._hasNewUpdates = true; // Mark data table for cleaning it up later
3602
+ let values = e["values"];
3603
+ if (values) {
3604
+ let ric = e["ric"];
3605
+ if(rowDef.verifyConstituent(ric)) {
3606
+ let parentDef = rowDef;
3607
+ let childDef = parentDef.getConstituent(ric);
3608
+ if(childDef) { // The constituent will share the same sub id as its parent
3609
+ rowDef = childDef;
3610
+ } else {
3611
+ rowDef = childDef = parentDef.addConstituent(ric);
3612
+ if(!childDef) {
3613
+ return; // Parent chain is not alive
3608
3614
  }
3609
- this._updateStreamingData();
3610
- } else if(rowDef.isAutoGenerated()) { // Subscription and its parent has been removed by Real-time provider
3611
- rowDef.setParent(null); // Manually remove child reference from its parent
3612
- this._removeRow(rowDef);
3615
+ this._connector.addRic(childDef); // TODO: JET/RTK should not re-subscribe this
3616
+ this._registerConstituents(childDef);
3613
3617
  }
3614
3618
  }
3615
- return;
3616
- }
3617
3619
 
3618
- // The new data update has no row definition, meaning that we have found a new constituent from a chain.
3619
- let subId = rowData[SUB_ID]; // The constituent will share the same sub id as its parent
3620
- if(subId) {
3621
- let parentDef = this._getRowDefinitionById(subId);
3622
- if(parentDef && parentDef.isChain() && parentDef.getRic() !== rowData["RIC"]) { // TODO: Check for delayed ric
3623
- if(!this._chainMembers) {
3624
- this._chainMembers = {};
3625
- }
3626
- if(!this._chainMembers[e["rid"]]) { // Prevent duplication
3627
- this._chainMembers[e["rid"]] = rowData;
3628
- this._addMemberOfChain(rowData);
3629
- }
3630
- }
3620
+ rowDef.setRowData(values); // Trigger data changes
3621
+ } else if(rowDef.isConstituent()) { // Subscription and its parent has been removed by Real-time provider
3622
+ rowDef.setParent(null); // Manually remove child reference from its parent
3623
+ this._removeRow(rowDef);
3631
3624
  }
3632
3625
  };
3626
+
3633
3627
  /** @private
3634
- * @param {!Object} rowData
3628
+ * @param {RowDefinition} rowDef
3635
3629
  */
3636
- Grid.prototype._addMemberOfChain = function(rowData) {
3637
- if(this._chainConflator.conflate(rowData)) {
3630
+ Grid.prototype._registerConstituents = function(rowDef) {
3631
+ if(this._chainConflator.conflate(rowDef)) {
3632
+ return;
3633
+ }
3634
+ let view = this._dv;
3635
+ let dt = view ? view.getDataSource() : null;
3636
+ if(!dt) {
3638
3637
  return;
3639
3638
  }
3640
3639
 
3641
- let rows = this._chainConflator.popAllData(); // This must have no duplication
3642
- let len = rows ? rows.length : 0;
3640
+ let childDefs = this._chainConflator.popAllData(); // This must have no duplication
3641
+ let childCount = childDefs ? childDefs.length : 0;
3642
+
3643
+ // Validate row definition and collect its info
3643
3644
  let i;
3645
+ let validDefs = [];
3646
+ let maxCountMap = {};
3647
+ for(i = 0; i < childCount; ++i) {
3648
+ let childDef = childDefs[i];
3649
+ let parentDef = childDef.getParent();
3650
+ if(!parentDef) {
3651
+ break; // A constituent without parent cannot be added to the view
3652
+ }
3653
+ let parentRowId = parentDef.getRowId();
3654
+ let maxCount = maxCountMap[parentRowId];
3655
+ if(maxCount == null) {
3656
+ maxCount = maxCountMap[parentRowId] = parentDef.countChildInView();
3657
+ }
3658
+ validDefs.push(childDef);
3659
+ }
3660
+
3661
+ childCount = validDefs.length;
3662
+ if(!childCount) {
3663
+ return;
3664
+ }
3644
3665
 
3645
3666
  let prevState = false;
3646
- if(len > 1) {
3667
+ if(childCount > 1) {
3647
3668
  prevState = this._dt.freeze(); // Avoid sorting for each insertion
3648
3669
  }
3649
- let childDefs = [];
3650
- for(i = 0; i < len; ++i) {
3651
- rowData = /** @type{!Object} */(rows[i]);
3652
- let subId = rowData[SUB_ID];
3653
- let parentDef = this._getRowDefinitionById(subId);
3654
- if(parentDef) {
3655
- let childDef = parentDef.addConstituent(/** @type{string} */(rowData["RIC"]), this._dt);
3656
- if(childDef) {
3657
- childDefs.push(childDef);
3658
- } // else { // childDef has already been added
3659
- }
3660
- }
3661
- this._chainMembers = null; // Clear all waiting chain members
3662
3670
 
3663
- let childCount = childDefs.length;
3664
- if(childCount) {
3665
- for(i = childCount; --i >= 0;) {
3666
- this._connector.addRic(childDefs[i]); // TODO: JET/RTK should not re-subscribe this
3671
+ for(i = 0; i < childCount; ++i) {
3672
+ let childDef = validDefs[i];
3673
+ let parentDef = childDef.getParent();
3674
+ let parentRowId = parentDef.getRowId();
3675
+ let maxCount = maxCountMap[parentRowId];
3676
+
3677
+ // TODO: Handle nested children
3678
+ view.addSegmentChild(parentRowId, childDef.getRowId());
3679
+
3680
+ // Added order and child order can be different
3681
+ // CHILD_ORDER value from real-time service indicates the order of constituents.
3682
+ let destIndex = dt.getRowIndex(parentRowId) + 1; // WARNING: Not checking for negative index
3683
+ let childOrder = childDef.getData("CHILD_ORDER"); // CHILD_ORDER starts from 0
3684
+ if(childOrder != null && childOrder < maxCount) {
3685
+ destIndex += childOrder;
3686
+ } else {
3687
+ destIndex += maxCount;
3667
3688
  }
3689
+ let destRowId = dt.getRowId(destIndex);
3690
+ childDef.registerToView(view, destRowId);
3691
+ maxCountMap[parentRowId] = maxCount + 1; // Since new child has been added to the view, maxCount has to be updated
3668
3692
  }
3669
- if(len > 1) {
3693
+ if(childCount > 1) {
3670
3694
  this._dt.freeze(prevState);
3671
3695
  }
3672
3696
  };
3673
3697
 
3674
3698
  /** @private
3699
+ * @param {Object} e
3675
3700
  */
3676
- Grid.prototype._updateStreamingData = function() {
3677
- if(this._streamingConflator.conflate()) {
3701
+ Grid.prototype._onDataChanged = function(e) {
3702
+ if(this._dt && e && e["rid"] && e["changes"]) {
3703
+ let rowDef = this._getRowDefinitionById(e["rid"]);
3704
+ if(rowDef) {
3705
+ if(rowDef.addUpdate(e["changes"])) { // This is the only place that update array can grow. It is used for blinking data.
3706
+ this._dt._hasNewUpdates = true; // Mark data table for cleaning it up later
3707
+ }
3708
+ }
3709
+ }
3710
+
3711
+ if(this._dcConflator.conflate()) {
3678
3712
  return;
3679
3713
  }
3680
3714
 
@@ -3975,9 +4009,9 @@ Grid.prototype._onSubSegmentChanged = function(e) {
3975
4009
  // let parentId = segment.getParentId();
3976
4010
  let segmentId = segment.getId();
3977
4011
  rowDef = new RowDefinition({
3978
- "segmentId": segmentId
4012
+ "segmentId": segmentId // WARNING: This could cause row id duplication
3979
4013
  });
3980
- rowDef.setDataSource(this._dc);
4014
+ rowDef.setDataSource(this._dc); // auto generated row does not require a subscription
3981
4015
  rowDef.registerToView(this._dv);
3982
4016
  }
3983
4017
  };
@@ -1,4 +1,4 @@
1
- import { arrayToObject, cloneObject } from "../../tr-grid-util/es6/Util.js";
1
+ import { arrayToObject } from "../../tr-grid-util/es6/Util.js";
2
2
  import { DataCache } from "../../core/es6/data/DataCache.js";
3
3
  import { DataTable } from "../../core/es6/data/DataTable.js";
4
4
 
@@ -48,7 +48,7 @@ declare class RowDefinition {
48
48
 
49
49
  public getType(): string;
50
50
 
51
- public setDataSource(dataSource: DataCache|null): void;
51
+ public setDataSource(dataSource: DataCache|null, subs?: any): void;
52
52
 
53
53
  public getDataSource(): DataCache|null;
54
54
 
@@ -68,6 +68,8 @@ declare class RowDefinition {
68
68
 
69
69
  public setRowData(data: { [key: string]: any }): void;
70
70
 
71
+ public resetRowData(): void;
72
+
71
73
  public setData(field: string, value: any): void;
72
74
 
73
75
  public getUserInput(): string;
@@ -86,6 +88,8 @@ declare class RowDefinition {
86
88
 
87
89
  public isChain(): boolean;
88
90
 
91
+ public isConstituent(): boolean;
92
+
89
93
  public static hasChain(rowDef: RowDefinition|null): boolean;
90
94
 
91
95
  public isChainCollapsed(): boolean;
@@ -96,21 +100,21 @@ declare class RowDefinition {
96
100
 
97
101
  public isRealTimeRow(): boolean;
98
102
 
99
- public subscribeForUpdates(): boolean;
103
+ public subscribeForUpdates(subs?: any): boolean;
100
104
 
101
- public unsubscribeForUpdates(): any;
105
+ public unsubscribeForUpdates(): null;
102
106
 
103
107
  public isSubscribing(): boolean;
104
108
 
105
- public addUpdate(e: any): boolean;
109
+ public getSubId(): string;
110
+
111
+ public addUpdate(changes: any): boolean;
106
112
 
107
113
  public getUpdates(): { [key: string]: number }|null;
108
114
 
109
115
  public resetUpdates(): void;
110
116
 
111
- public registerToView(view: DataView|null, destRowId?: string|null): void;
112
-
113
- public static deregisterFromView(rowIds: (string)[]|null, rowDef: RowDefinition|null): (string)[]|null;
117
+ public registerToView(view: DataView|null, destRowId?: string|null): boolean;
114
118
 
115
119
  public unlinkChain(): void;
116
120
 
@@ -128,6 +132,8 @@ declare class RowDefinition {
128
132
 
129
133
  public getChildCount(): number;
130
134
 
135
+ public countChildInView(): number;
136
+
131
137
  public getParent(): RowDefinition|null;
132
138
 
133
139
  public getDepthLevel(): number;