diff --git a/src/sql/platform/query/common/query.ts b/src/sql/platform/query/common/query.ts index 311898632b..e50b4ad61a 100644 --- a/src/sql/platform/query/common/query.ts +++ b/src/sql/platform/query/common/query.ts @@ -30,6 +30,7 @@ export interface IQueryEditorConfiguration { readonly optimizedTable: boolean, readonly inMemoryDataProcessingThreshold: number, readonly openAfterSave: boolean + readonly showActionBar: boolean; }, readonly messages: { readonly showBatchTime: boolean, diff --git a/src/sql/workbench/contrib/query/browser/gridPanel.ts b/src/sql/workbench/contrib/query/browser/gridPanel.ts index 98365543a5..a08fbbf644 100644 --- a/src/sql/workbench/contrib/query/browser/gridPanel.ts +++ b/src/sql/workbench/contrib/query/browser/gridPanel.ts @@ -62,6 +62,7 @@ const HEADER_HEIGHT = 26; const MIN_GRID_HEIGHT_ROWS = 8; const ESTIMATED_SCROLL_BAR_HEIGHT = 15; const BOTTOM_PADDING = 15; +const NO_ACTIONBAR_ADDITIONAL_PADDING = 75; const ACTIONBAR_WIDTH = 36; // minimum height needed to show the full actionbar @@ -478,18 +479,12 @@ export abstract class GridTableBase extends Disposable implements IView { // actionsOrientation controls the orientation (horizontal or vertical) of the actionBar private build(): void { - let actionBarContainer = document.createElement('div'); - - // Create a horizontal actionbar if orientation passed in is HORIZONTAL - if (this.options.actionOrientation === ActionsOrientation.HORIZONTAL) { - actionBarContainer.className = 'grid-panel action-bar horizontal'; - this.container.appendChild(actionBarContainer); - } - this.tableContainer = document.createElement('div'); this.tableContainer.className = 'grid-panel'; this.tableContainer.style.display = 'inline-block'; - this.tableContainer.style.width = `calc(100% - ${ACTIONBAR_WIDTH}px)`; + + let actionBarWidth = this.showActionBar ? ACTIONBAR_WIDTH : 0; + this.tableContainer.style.width = `calc(100% - ${actionBarWidth}px)`; this.container.appendChild(this.tableContainer); @@ -563,12 +558,7 @@ export abstract class GridTableBase extends Disposable implements IView { if (this.styles) { this.table.style(this.styles); } - // If the actionsOrientation passed in is "VERTICAL" (or no actionsOrientation is passed in at all), create a vertical actionBar - if (this.options.actionOrientation === ActionsOrientation.VERTICAL) { - actionBarContainer.className = 'grid-panel action-bar vertical'; - actionBarContainer.style.width = ACTIONBAR_WIDTH + 'px'; - this.container.appendChild(actionBarContainer); - } + let context: IGridActionContext = { gridDataProvider: this.gridDataProvider, table: this.table, @@ -576,14 +566,15 @@ export abstract class GridTableBase extends Disposable implements IView { batchId: this.resultSet.batchId, resultId: this.resultSet.id }; - this.actionBar = new ActionBar(actionBarContainer, { - orientation: this.options.actionOrientation, context: context - }); + this.initializeActionBar(context); + // update context before we run an action this.selectionModel.onSelectedRangesChanged.subscribe(e => { this.actionBar.context = this.generateContext(); }); + this.rebuildActionBar(); + this.selectionModel.onSelectedRangesChanged.subscribe(async e => { if (this.state) { this.state.selection = this.selectionModel.getSelectedRanges(); @@ -628,6 +619,26 @@ export abstract class GridTableBase extends Disposable implements IView { })); } + private initializeActionBar(context: IGridActionContext): void { + let actionBarContainer = document.createElement('div'); + + // Create a horizontal actionbar if orientation passed in is HORIZONTAL + if (this.options.actionOrientation === ActionsOrientation.HORIZONTAL) { + actionBarContainer.className = 'grid-panel action-bar horizontal'; + this.container.appendChild(actionBarContainer); + } + // if the actionsOrientation passed in is "VERTICAL" (or no actionsOrientation is passed in at all), create a vertical actionBar + else { + actionBarContainer.className = 'grid-panel action-bar vertical'; + actionBarContainer.style.width = (this.showActionBar ? ACTIONBAR_WIDTH : 0) + 'px'; + this.container.appendChild(actionBarContainer); + } + + this.actionBar = new ActionBar(actionBarContainer, { + orientation: this.options.actionOrientation, context: context + }); + } + private restoreScrollState() { if (this.state.scrollPositionX || this.state.scrollPositionY) { this.table.grid.scrollTo(this.state.scrollPositionY); @@ -810,11 +821,17 @@ export abstract class GridTableBase 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 // 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); + let actionBarHeight = this.showActionBar ? ACTIONBAR_HEIGHT : 0; + let bottomPadding = this.showActionBar ? BOTTOM_PADDING : BOTTOM_PADDING + NO_ACTIONBAR_ADDITIONAL_PADDING; + + return this.isOnlyTable ? ROW_HEIGHT : Math.max(Math.min(this.maxSize, MIN_GRID_HEIGHT), actionBarHeight + bottomPadding); } public get maximumSize(): number { - return Math.max(this.maxSize, ACTIONBAR_HEIGHT + BOTTOM_PADDING); + let actionBarHeight = this.showActionBar ? ACTIONBAR_HEIGHT : 0; + let bottomPadding = this.showActionBar ? BOTTOM_PADDING : BOTTOM_PADDING + NO_ACTIONBAR_ADDITIONAL_PADDING; + + return Math.max(this.maxSize, actionBarHeight + bottomPadding); } private loadData(offset: number, count: number): Thenable { @@ -933,7 +950,7 @@ class GridTable extends GridTableBase { super(state, resultSet, { actionOrientation: ActionsOrientation.VERTICAL, inMemoryDataProcessing: true, - showActionBar: true, + showActionBar: configurationService.getValue('queryEditor').results.showActionBar, inMemoryDataCountThreshold: configurationService.getValue('queryEditor').results.inMemoryDataProcessingThreshold, }, contextMenuService, instantiationService, editorService, untitledEditorService, configurationService, queryModelService, themeService, contextViewService, notificationService, executionPlanService, accessibilityService, quickInputService); this._gridDataProvider = this.instantiationService.createInstance(QueryGridDataProvider, this._runner, resultSet.batchId, resultSet.id); diff --git a/src/sql/workbench/contrib/query/browser/query.contribution.ts b/src/sql/workbench/contrib/query/browser/query.contribution.ts index b1edb5ff8a..a41d21aeef 100644 --- a/src/sql/workbench/contrib/query/browser/query.contribution.ts +++ b/src/sql/workbench/contrib/query/browser/query.contribution.ts @@ -442,6 +442,11 @@ const queryEditorConfiguration: IConfigurationNode = { 'description': localize('queryEditor.results.openAfterSave', "Whether to open the file in Azure Data Studio after the result is saved."), 'default': true }, + 'queryEditor.results.showActionBar': { + 'type': 'boolean', + 'description': localize('queryEditor.results.showActionBar', "Whether to show the action bar in the query results view"), + 'default': true + }, 'queryEditor.messages.showBatchTime': { 'type': 'boolean', 'description': localize('queryEditor.messages.showBatchTime', "Should execution time be shown for individual batches"),