selected cell summary for status bar (#14358)

This commit is contained in:
Alan Ren
2021-02-19 11:29:04 -08:00
committed by GitHub
parent f528ffea9b
commit 83da03a728
7 changed files with 105 additions and 17 deletions

View File

@@ -48,6 +48,7 @@ import { Progress } from 'vs/platform/progress/common/progress';
import { ScrollableView, IView } from 'sql/base/browser/ui/scrollableView/scrollableView';
import { IQueryEditorConfiguration } from 'sql/platform/query/common/query';
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
const ROW_HEIGHT = 29;
const HEADER_HEIGHT = 26;
@@ -373,7 +374,8 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
@IInstantiationService protected readonly instantiationService: IInstantiationService,
@IEditorService private readonly editorService: IEditorService,
@IUntitledTextEditorService private readonly untitledEditorService: IUntitledTextEditorService,
@IConfigurationService private readonly configurationService: IConfigurationService
@IConfigurationService private readonly configurationService: IConfigurationService,
@IQueryModelService private readonly queryModelService: IQueryModelService
) {
super();
let config = this.configurationService.getValue<{ rowHeight: number }>('resultsGrid');
@@ -513,10 +515,11 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
});
this.rebuildActionBar();
this.selectionModel.onSelectedRangesChanged.subscribe(e => {
this.selectionModel.onSelectedRangesChanged.subscribe(async e => {
if (this.state) {
this.state.selection = this.selectionModel.getSelectedRanges();
}
await this.notifyTableSelectionChanged();
});
this.table.grid.onScroll.subscribe((e, data) => {
@@ -590,6 +593,20 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
this.scrolled = false;
}
private async notifyTableSelectionChanged() {
const selectedValues = [];
for (const range of this.state.selection) {
const subset = await this.gridDataProvider.getRowData(range.fromRow, range.toRow - range.fromRow + 1);
subset.rows.forEach(row => {
// start with range.fromCell -1 because we have row number column which is not available in the actual data
for (let i = range.fromCell - 1; i < range.toCell; i++) {
selectedValues.push(row[i]?.displayValue);
}
});
}
this.queryModelService.notifyCellSelectionChanged(selectedValues);
}
private onTableClick(event: ITableMouseEvent) {
// account for not having the number column
let column = this.resultSet.columnInfo[event.cell.cell - 1];
@@ -769,9 +786,10 @@ class GridTable<T> extends GridTableBase<T> {
@IContextKeyService private contextKeyService: IContextKeyService,
@IEditorService editorService: IEditorService,
@IUntitledTextEditorService untitledEditorService: IUntitledTextEditorService,
@IConfigurationService configurationService: IConfigurationService
@IConfigurationService configurationService: IConfigurationService,
@IQueryModelService queryModelService: IQueryModelService
) {
super(state, resultSet, undefined, contextMenuService, instantiationService, editorService, untitledEditorService, configurationService);
super(state, resultSet, undefined, contextMenuService, instantiationService, editorService, untitledEditorService, configurationService, queryModelService);
this._gridDataProvider = this.instantiationService.createInstance(QueryGridDataProvider, this._runner, resultSet.batchId, resultSet.id);
}

View File

@@ -27,7 +27,7 @@ import { localize } from 'vs/nls';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { TimeElapsedStatusBarContributions, RowCountStatusBarContributions, QueryStatusStatusBarContributions } from 'sql/workbench/contrib/query/browser/statusBarItems';
import { TimeElapsedStatusBarContributions, RowCountStatusBarContributions, QueryStatusStatusBarContributions, QueryResultSelectionSummaryStatusBarContribution } from 'sql/workbench/contrib/query/browser/statusBarItems';
import { SqlFlavorStatusbarItem, ChangeFlavorAction } from 'sql/workbench/contrib/query/browser/flavorStatus';
import { IEditorInputFactoryRegistry, Extensions as EditorInputFactoryExtensions } from 'vs/workbench/common/editor';
import { FileQueryEditorInput } from 'sql/workbench/contrib/query/common/fileQueryEditorInput';
@@ -479,3 +479,4 @@ workbenchRegistry.registerWorkbenchContribution(TimeElapsedStatusBarContribution
workbenchRegistry.registerWorkbenchContribution(RowCountStatusBarContributions, LifecyclePhase.Restored);
workbenchRegistry.registerWorkbenchContribution(QueryStatusStatusBarContributions, LifecyclePhase.Restored);
workbenchRegistry.registerWorkbenchContribution(SqlFlavorStatusbarItem, LifecyclePhase.Restored);
workbenchRegistry.registerWorkbenchContribution(QueryResultSelectionSummaryStatusBarContribution, LifecyclePhase.Restored);

View File

@@ -3,18 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
import { IntervalTimer } from 'vs/base/common/async';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { localize } from 'vs/nls';
import QueryRunner from 'sql/workbench/services/query/common/queryRunner';
import { parseNumAsTimeString } from 'sql/platform/connection/common/utils';
import { Event } from 'vs/base/common/event';
import { QueryEditorInput } from 'sql/workbench/common/editor/query/queryEditorInput';
import { IStatusbarService, IStatusbarEntryAccessor, StatusbarAlignment } from 'vs/workbench/services/statusbar/common/statusbar';
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
import QueryRunner from 'sql/workbench/services/query/common/queryRunner';
import { IntervalTimer } from 'vs/base/common/async';
import { Event } from 'vs/base/common/event';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { localize } from 'vs/nls';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/workbench/services/statusbar/common/statusbar';
export class TimeElapsedStatusBarContributions extends Disposable implements IWorkbenchContribution {
private static readonly ID = 'status.query.timeElapsed';
@@ -253,3 +252,54 @@ export class QueryStatusStatusBarContributions extends Disposable implements IWo
this.statusbarService.updateEntryVisibility(QueryStatusStatusBarContributions.ID, true);
}
}
export class QueryResultSelectionSummaryStatusBarContribution extends Disposable implements IWorkbenchContribution {
private static readonly ID = 'status.query.selection-summary';
private statusItem: IStatusbarEntryAccessor;
constructor(
@IStatusbarService private readonly statusbarService: IStatusbarService,
@IEditorService private editorService: IEditorService,
@IQueryModelService queryModelService: IQueryModelService
) {
super();
this.statusItem = this._register(
this.statusbarService.addEntry({
text: '',
ariaLabel: ''
},
QueryResultSelectionSummaryStatusBarContribution.ID,
localize('status.query.selection-summary', "Selection Summary"),
StatusbarAlignment.RIGHT, 100)
);
this._register(editorService.onDidActiveEditorChange(() => { this.hide(); }, this));
this._register(queryModelService.onRunQueryStart(() => { this.hide(); }));
this._register(queryModelService.onCellSelectionChanged((data: string[]) => {
this.onCellSelectionChanged(data);
}));
}
private hide(): void {
this.statusbarService.updateEntryVisibility(QueryResultSelectionSummaryStatusBarContribution.ID, false);
}
private show(): void {
this.statusbarService.updateEntryVisibility(QueryResultSelectionSummaryStatusBarContribution.ID, true);
}
private onCellSelectionChanged(data: string[]): void {
const numericValues = data?.filter(value => !isNaN(parseFloat(value))).map(value => parseFloat(value));
if (numericValues?.length < 2 || !(this.editorService.activeEditor instanceof QueryEditorInput)) {
this.hide();
return;
}
const sum = numericValues.reduce((previous, current, idx, array) => previous + current);
const summaryText = localize('status.query.summaryText', "Average: {0} Count: {1} Sum: {2}", sum / numericValues.length, data.length, sum);
this.statusItem.update({
text: summaryText,
ariaLabel: summaryText
});
this.show();
}
}