Add incremental grid loading option to notebooks (#16577)

* render grids incrementally

* add loading spinner

* fix loading animation

* move rendergrids to notebook editor component

* add setting for incremental grid loading

* check configuration

* just use setTimeout to queue grids

* remove extra line

* add setter/getter for isloading

* add comment
This commit is contained in:
Lucy Zhang
2021-08-05 13:44:26 -07:00
committed by GitHub
parent c6308b77df
commit 9f761c44c4
2 changed files with 39 additions and 5 deletions

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { OnInit, Component, Input, Inject, ViewChild, ElementRef } from '@angular/core';
import { OnInit, Component, Input, Inject, ViewChild, ElementRef, ChangeDetectorRef, forwardRef } from '@angular/core';
import * as azdata from 'azdata';
import { IGridDataProvider, getResultsString } from 'sql/workbench/services/query/common/gridDataProvider';
@@ -23,7 +23,7 @@ import { localize } from 'vs/nls';
import { IAction } from 'vs/base/common/actions';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { IMimeComponent } from 'sql/workbench/contrib/notebook/browser/outputs/mimeRegistry';
import { ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { CellExecutionState, ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { MimeModel } from 'sql/workbench/services/notebook/browser/outputs/mimemodel';
import { GridTableState } from 'sql/workbench/common/editor/query/gridTableState';
import { GridTableBase } from 'sql/workbench/contrib/query/browser/gridPanel';
@@ -51,7 +51,9 @@ import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
@Component({
selector: GridOutputComponent.SELECTOR,
template: `<div #output class="notebook-cellTable"></div>`
template: `
<loading-spinner [loading]="loading"></loading-spinner>
<div #output class="notebook-cellTable"></div>`
})
export class GridOutputComponent extends AngularDisposable implements IMimeComponent, OnInit {
public static readonly SELECTOR: string = 'grid-output';
@@ -66,12 +68,17 @@ export class GridOutputComponent extends AngularDisposable implements IMimeCompo
private _batchId: number | undefined;
private _id: number | undefined;
private _layoutCalledOnce: boolean = false;
private _incrementalGridRenderingEnabled: boolean;
private _isLoading: boolean = false;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(IThemeService) private readonly themeService: IThemeService
@Inject(IThemeService) private readonly themeService: IThemeService,
@Inject(IConfigurationService) private configurationService: IConfigurationService
) {
super();
this._incrementalGridRenderingEnabled = this.configurationService.getValue('notebook.enableIncrementalGridRendering');
}
@Input() set bundleOptions(value: MimeModel.IOptions) {
@@ -102,6 +109,17 @@ export class GridOutputComponent extends AngularDisposable implements IMimeCompo
this._cellOutput = value;
}
get loading(): boolean {
return this._isLoading;
}
@Input() set loading(isLoading: boolean) {
this._isLoading = isLoading;
if (!(this._changeRef['destroyed'])) {
this._changeRef.detectChanges();
}
}
async ngOnInit() {
if (this.cellModel) {
let outputId: QueryResultId = this.cellModel.getOutputId(this._cellOutput);
@@ -114,10 +132,21 @@ export class GridOutputComponent extends AngularDisposable implements IMimeCompo
this.updateResult(e.resultSet, e.rows);
}
}));
if (this._cellModel.executionState === CellExecutionState.Running || !this._incrementalGridRenderingEnabled) {
await this.renderGrid();
} else {
this.loading = true;
// setTimeout adds the renderGrid call to a queue that gets called after all current tasks get executed -
// this allows the rest of the notebook to render first before rendering grids incrementally.
setTimeout(async () => {
await this.renderGrid();
this.loading = false;
});
}
}
await this.renderGrid();
}
async renderGrid(): Promise<void> {
if (!this._bundleOptions || !this._cellModel || !this.mimeType) {
return;