From c1cb9000a9d54b10a52118ffe7dc1ded7fc8a804 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Wed, 1 May 2019 12:36:16 -0700 Subject: [PATCH] Various results grid scrolling fixes (#5285) --- .../scrollableSplitview.ts | 6 +- .../ui/table/media/slickColorTheme.css | 2 +- src/sql/platform/query/common/queryRunner.ts | 2 +- .../parts/query/browser/queryResultsView.ts | 60 ++++++++----------- .../parts/query/electron-browser/gridPanel.ts | 16 +++-- 5 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/sql/base/browser/ui/scrollableSplitview/scrollableSplitview.ts b/src/sql/base/browser/ui/scrollableSplitview/scrollableSplitview.ts index 7eb50c41d3..d85f71f4f5 100644 --- a/src/sql/base/browser/ui/scrollableSplitview/scrollableSplitview.ts +++ b/src/sql/base/browser/ui/scrollableSplitview/scrollableSplitview.ts @@ -611,9 +611,9 @@ export class ScrollableSplitView extends HeightMap implements IDisposable { } else { item.size = size; this.updateSize(item.view.id!, size); - let top = item.top + item.size; - for (let i = index + 1; i < this.viewItems.length; i++) { - let currentItem = this.viewItems[i]; + let top: number = 0; + for (let i = 0; i < this.viewItems.length; i++) { + let currentItem: IViewItem = this.viewItems[i]; this.updateTop(currentItem.view.id!, top); top += currentItem.size; } diff --git a/src/sql/base/browser/ui/table/media/slickColorTheme.css b/src/sql/base/browser/ui/table/media/slickColorTheme.css index f6b0953f2e..bd92a83354 100644 --- a/src/sql/base/browser/ui/table/media/slickColorTheme.css +++ b/src/sql/base/browser/ui/table/media/slickColorTheme.css @@ -148,7 +148,7 @@ .vs ::-webkit-scrollbar { width: 14px; - height: 10px; + height: 12px; } .vs ::-webkit-scrollbar-thumb { background: hsla(0,0%,47%,.4); diff --git a/src/sql/platform/query/common/queryRunner.ts b/src/sql/platform/query/common/queryRunner.ts index 9dfe0948c1..a7838bf7cd 100644 --- a/src/sql/platform/query/common/queryRunner.ts +++ b/src/sql/platform/query/common/queryRunner.ts @@ -343,7 +343,7 @@ export default class QueryRunner extends Disposable { let resultSet = result.resultSetSummary; let batchSet: azdata.BatchSummary; if (!resultSet.batchId) { - // Missing the batchId. In this case, default to always using the first batch in the list + // Missing the batchId or processing batchId==0. In this case, default to always using the first batch in the list // or create one in the case the DMP extension didn't obey the contract perfectly if (this._batchSets.length > 0) { batchSet = this._batchSets[0]; diff --git a/src/sql/workbench/parts/query/browser/queryResultsView.ts b/src/sql/workbench/parts/query/browser/queryResultsView.ts index 35bf0ed810..23ecce7aa3 100644 --- a/src/sql/workbench/parts/query/browser/queryResultsView.ts +++ b/src/sql/workbench/parts/query/browser/queryResultsView.ts @@ -29,7 +29,6 @@ class ResultsView extends Disposable implements IPanelView { private messagePanel: MessagePanel; private container = document.createElement('div'); private currentDimension: DOM.Dimension; - private needsGridResize = false; private _state: ResultsViewState; constructor(private instantiationService: IInstantiationService) { @@ -52,38 +51,15 @@ class ResultsView extends Disposable implements IPanelView { this.gridPanel.layout(0); } else if (size > 0 && !this.gridPanel.isVisible()) { this.gridPanel.setVisible(true); - let panelSize: number; - if (this.state && this.state.gridPanelSize) { - panelSize = this.state.gridPanelSize; - } else if (this.currentDimension) { - panelSize = Math.round(this.currentDimension.height * 0.7); - } else { - panelSize = 200; - this.needsGridResize = true; + this.panelViewlet.addPanels([{ panel: this.gridPanel, index: 0, size: 200 }]); + } + if (this.gridPanel.isVisible()) { + if (this.state.messagePanelSize) { + this.panelViewlet.resizePanel(this.messagePanel, this.state.messagePanelSize); } - this.panelViewlet.addPanels([{ panel: this.gridPanel, index: 0, size: panelSize }]); + this.panelViewlet.resizePanel(this.gridPanel, this.getGridPanelSize()); } }); - let resizeList = Event.any(this.gridPanel.onDidChange, this.messagePanel.onDidChange)(() => { - let panelSize: number; - if (this.state && this.state.gridPanelSize) { - panelSize = this.state.gridPanelSize; - } else if (this.currentDimension) { - panelSize = Math.round(this.currentDimension.height * 0.7); - } else { - panelSize = 200; - this.needsGridResize = true; - } - if (this.state.messagePanelSize) { - this.panelViewlet.resizePanel(this.gridPanel, this.state.messagePanelSize); - } - this.panelViewlet.resizePanel(this.gridPanel, panelSize); - }); - // once the user changes the sash we should stop trying to resize the grid - Event.once(this.panelViewlet.onDidSashChange)(e => { - this.needsGridResize = false; - resizeList.dispose(); - }); this.panelViewlet.onDidSashChange(e => { if (this.state) { @@ -103,15 +79,19 @@ class ResultsView extends Disposable implements IPanelView { layout(dimension: DOM.Dimension): void { this.panelViewlet.layout(dimension); - // the grid won't be resize if the height has not changed so we need to do it manually + // the grid won't be resized if the height has not changed so we need to do it manually if (this.currentDimension && dimension.height === this.currentDimension.height) { this.gridPanel.layout(dimension.height); } this.currentDimension = dimension; - if (this.needsGridResize) { - this.panelViewlet.resizePanel(this.gridPanel, this.state.gridPanelSize || Math.round(this.currentDimension.height * 0.7)); - // we have the right scroll position saved as part of gridPanel state, use this to re-position scrollbar - this.gridPanel.resetScrollPosition(); + + // resize the messages and grid panels + this.panelViewlet.resizePanel(this.gridPanel, this.getGridPanelSize()); + // we have the right scroll position saved as part of gridPanel state, use this to re-position scrollbar + this.gridPanel.resetScrollPosition(); + + if (this.state.messagePanelSize) { + this.panelViewlet.resizePanel(this.messagePanel, this.state.messagePanelSize); } } @@ -146,6 +126,16 @@ class ResultsView extends Disposable implements IPanelView { public get state(): ResultsViewState { return this._state; } + + private getGridPanelSize(): number { + if (this.state && this.state.gridPanelSize) { + return this.state.gridPanelSize; + } else if (this.currentDimension) { + return Math.round(Math.max(this.currentDimension.height * 0.7, this.currentDimension.height - 150)); + } else { + return 200; + } + } } class ResultsTab implements IPanelTab { diff --git a/src/sql/workbench/parts/query/electron-browser/gridPanel.ts b/src/sql/workbench/parts/query/electron-browser/gridPanel.ts index b59f9b321a..c824553280 100644 --- a/src/sql/workbench/parts/query/electron-browser/gridPanel.ts +++ b/src/sql/workbench/parts/query/electron-browser/gridPanel.ts @@ -297,13 +297,18 @@ export class GridPanel extends ViewletPanel { tables.push(table); } - // possible to need a sort? + this.tables = this.tables.concat(tables); + + // turn-off special-case process when only a single table is being displayed + if (this.tables.length > 1) { + for (let i = 0; i < this.tables.length; ++i) { + this.tables[i].isOnlyTable = false; + } + } if (isUndefinedOrNull(this.maximizedGrid)) { this.splitView.addViews(tables, tables.map(i => i.minimumSize), this.splitView.length); } - - this.tables = this.tables.concat(tables); } public clear() { @@ -404,6 +409,8 @@ class GridTable extends Disposable implements IView { private rowHeight: number; + public isOnlyTable: boolean = true; + public get resultSet(): azdata.ResultSetSummary { return this._resultSet; } @@ -713,7 +720,8 @@ class GridTable extends Disposable implements IView { public get minimumSize(): number { // clamp between ensuring we can show the actionbar, while also making sure we don't take too much space - return Math.max(Math.min(this.maxSize, MIN_GRID_HEIGHT), ACTIONBAR_HEIGHT + BOTTOM_PADDING); + // if there is only one table then allow a minimum size of ROW_HEIGHT + return this.isOnlyTable ? ROW_HEIGHT : Math.max(Math.min(this.maxSize, MIN_GRID_HEIGHT), ACTIONBAR_HEIGHT + BOTTOM_PADDING); } public get maximumSize(): number {