diff --git a/src/sql/workbench/browser/editData/editDataInput.ts b/src/sql/workbench/browser/editData/editDataInput.ts index 43f7023feb..8907c62d94 100644 --- a/src/sql/workbench/browser/editData/editDataInput.ts +++ b/src/sql/workbench/browser/editData/editDataInput.ts @@ -85,8 +85,10 @@ export class EditDataInput extends EditorInput implements IConnectableInput { this._register( this._queryModelService.onEditSessionReady((result) => { - if (self.uri === result.ownerUri) { - self.initEditEnd(result); + if (this.uri === result.ownerUri) { + this._results.editDataGridPanel.onRefreshComplete.then(() => { + this.initEditEnd(result); + }); } }) ); diff --git a/src/sql/workbench/browser/editData/editDataResultsInput.ts b/src/sql/workbench/browser/editData/editDataResultsInput.ts index 712cf30496..b2ec6c951c 100644 --- a/src/sql/workbench/browser/editData/editDataResultsInput.ts +++ b/src/sql/workbench/browser/editData/editDataResultsInput.ts @@ -7,6 +7,10 @@ import { EditorInput } from 'vs/workbench/common/editor'; import { Emitter } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; +export interface IGridPanel { + readonly onRefreshComplete: Promise; +} + /** * Input for the EditDataResultsEditor. This input helps with logic for the viewing and editing of * data in the results grid. @@ -25,6 +29,7 @@ export class EditDataResultsInput extends EditorInput { public readonly onRestoreViewStateEmitter = new Emitter(); public readonly onSaveViewStateEmitter = new Emitter(); + private _editDataGridPanel: IGridPanel; constructor(private _uri: string) { super(); @@ -32,6 +37,14 @@ export class EditDataResultsInput extends EditorInput { this._hasBootstrapped = false; } + get editDataGridPanel(): IGridPanel { + return this._editDataGridPanel; + } + + set editDataGridPanel(gridPanel: IGridPanel) { + this._editDataGridPanel = gridPanel; + } + getTypeId(): string { return EditDataResultsInput.ID; } diff --git a/src/sql/workbench/contrib/editData/browser/editDataGridPanel.ts b/src/sql/workbench/contrib/editData/browser/editDataGridPanel.ts index b4b6e1b30b..d21b7ba941 100644 --- a/src/sql/workbench/contrib/editData/browser/editDataGridPanel.ts +++ b/src/sql/workbench/contrib/editData/browser/editDataGridPanel.ts @@ -39,7 +39,8 @@ import { onUnexpectedError } from 'vs/base/common/errors'; export class EditDataGridPanel extends GridParentComponent { // The time(in milliseconds) we wait before refreshing the grid. // We use clearTimeout and setTimeout pair to avoid unnecessary refreshes. - private refreshGridTimeoutInMs = 200; + // Timeout is set to allow the grid to refresh fully before allowing a manual refresh. + private refreshGridTimeoutInMs = 1000; // The timeout handle for the refresh grid task private refreshGridTimeoutHandle: any; @@ -78,6 +79,7 @@ export class EditDataGridPanel extends GridParentComponent { public loadDataFunction: (offset: number, count: number) => Promise<{}[]>; public onBeforeAppendCell: (row: number, column: number) => string; public onGridRendered: (event: Slick.OnRenderedEventArgs) => void; + public onRefreshComplete: Promise; private savedViewState: { gridSelections: Slick.Range[]; @@ -132,7 +134,7 @@ export class EditDataGridPanel extends GridParentComponent { self.handleMessage(self, event); break; case 'resultSet': - self.handleResultSet(self, event); + this.onRefreshComplete = self.handleResultSet(self, event); break; case 'editSessionReady': self.handleEditSessionReady(self, event); @@ -358,7 +360,7 @@ export class EditDataGridPanel extends GridParentComponent { } } - handleResultSet(self: EditDataGridPanel, event: any): void { + async handleResultSet(self: EditDataGridPanel, event: any): Promise { // Clone the data before altering it to avoid impacting other subscribers let resultSet = assign({}, event.data); if (!resultSet.complete) { @@ -385,7 +387,7 @@ export class EditDataGridPanel extends GridParentComponent { self.windowSize, index => { return {}; }, resultSet.rowCount, - this.loadDataFunction, + await this.loadDataFunction, ), columnDefinitions: [rowNumberColumn.getColumnDefinition()].concat(resultSet.columnInfo.map((c, i) => { let columnIndex = (i + 1).toString(); @@ -410,14 +412,7 @@ export class EditDataGridPanel extends GridParentComponent { if (self.placeHolderDataSets[0]) { this.refreshDatasets(); } - self.refreshGrid(); - - // Setup the state of the selected cell - this.resetCurrentCell(); - this.removingNewRow = false; - this.newRowVisible = false; - this.dirtyCells = []; - + await self.refreshGrid(true); } /** @@ -440,7 +435,11 @@ export class EditDataGridPanel extends GridParentComponent { return inputStr.replace(/(\r\n|\n|\r)/g, '\u0000'); } - private refreshGrid(): Thenable { + /** + * Code that handles the refresh of the grid. + * @param isManual flag used when called by handleResultSet, for required additional processing. + */ + private refreshGrid(isManual?: boolean): Thenable { return new Promise(async (resolve, reject) => { clearTimeout(this.refreshGridTimeoutHandle); @@ -462,11 +461,18 @@ export class EditDataGridPanel extends GridParentComponent { this.logService.error('data set is empty, refresh cancelled.'); reject(); } - if (this.firstRender) { - setTimeout(() => this.setActive()); + this.resetCurrentCell(); + this.setActive(); } - resolve(); + else if (isManual) { + this.resetCurrentCell(); + this.removingNewRow = false; + this.newRowVisible = false; + this.dirtyCells = []; + } + //allow for the grid to render fully before returning. + setTimeout(() => resolve(), 500); }, this.refreshGridTimeoutInMs); }); } diff --git a/src/sql/workbench/contrib/editData/browser/editDataResultsEditor.ts b/src/sql/workbench/contrib/editData/browser/editDataResultsEditor.ts index 5f66a78823..9fc79c7822 100644 --- a/src/sql/workbench/contrib/editData/browser/editDataResultsEditor.ts +++ b/src/sql/workbench/contrib/editData/browser/editDataResultsEditor.ts @@ -105,6 +105,7 @@ export class EditDataResultsEditor extends BaseEditor { // to events from the backing data service this._applySettings(); let editGridPanel = this._register(this._instantiationService.createInstance(EditDataGridPanel, dataService, input.onSaveViewStateEmitter.event, input.onRestoreViewStateEmitter.event)); + input.editDataGridPanel = editGridPanel; editGridPanel.render(this.getContainer()); } }