fix result selection summary issues (#15245)

This commit is contained in:
Alan Ren
2021-04-26 23:07:55 -07:00
committed by GitHub
parent a086ad6ff1
commit 0ed2a5d431
6 changed files with 34 additions and 23 deletions

View File

@@ -654,17 +654,25 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
} }
private async notifyTableSelectionChanged() { private async notifyTableSelectionChanged() {
const selectedValues = []; const selectedCells = [];
for (const range of this.state.selection) { for (const range of this.state.selection) {
const subset = await this.gridDataProvider.getRowData(range.fromRow, range.toRow - range.fromRow + 1); let subset;
subset.rows.forEach(row => { if (this.dataProvider.isDataInMemory) {
// handle the scenario when the data is sorted/filtered,
// we need to use the data that is being displayed
const data = await this.dataProvider.getRangeAsync(range.fromRow, range.toRow - range.fromRow + 1);
subset = data.map(item => Object.keys(item).map(key => item[key]));
} else {
subset = (await this.gridDataProvider.getRowData(range.fromRow, range.toRow - range.fromRow + 1)).rows;
}
subset.forEach(row => {
// start with range.fromCell -1 because we have row number column which is not available in the actual data // 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++) { for (let i = range.fromCell - 1; i < range.toCell; i++) {
selectedValues.push(row[i]?.displayValue); selectedCells.push(row[i]);
} }
}); });
} }
this.queryModelService.notifyCellSelectionChanged(selectedValues); this.queryModelService.notifyCellSelectionChanged(selectedCells);
} }
private onTableClick(event: ITableMouseEvent) { private onTableClick(event: ITableMouseEvent) {
@@ -761,7 +769,8 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
dataWithSchema[this.columns[i].field] = { dataWithSchema[this.columns[i].field] = {
displayValue: r[i - 1].displayValue, displayValue: r[i - 1].displayValue,
ariaLabel: escape(r[i - 1].displayValue), ariaLabel: escape(r[i - 1].displayValue),
isNull: r[i - 1].isNull isNull: r[i - 1].isNull,
invariantCultureDisplayValue: r[i - 1].invariantCultureDisplayValue
}; };
} }
return dataWithSchema as T; return dataWithSchema as T;

View File

@@ -6,6 +6,7 @@
import { parseNumAsTimeString } from 'sql/platform/connection/common/utils'; import { parseNumAsTimeString } from 'sql/platform/connection/common/utils';
import { QueryEditorInput } from 'sql/workbench/common/editor/query/queryEditorInput'; import { QueryEditorInput } from 'sql/workbench/common/editor/query/queryEditorInput';
import { INotebookService } from 'sql/workbench/services/notebook/browser/notebookService'; import { INotebookService } from 'sql/workbench/services/notebook/browser/notebookService';
import { ICellValue } from 'sql/workbench/services/query/common/query';
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel'; import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
import QueryRunner from 'sql/workbench/services/query/common/queryRunner'; import QueryRunner from 'sql/workbench/services/query/common/queryRunner';
import { IntervalTimer } from 'vs/base/common/async'; import { IntervalTimer } from 'vs/base/common/async';
@@ -277,8 +278,8 @@ export class QueryResultSelectionSummaryStatusBarContribution extends Disposable
this._register(editorService.onDidActiveEditorChange(() => { this.hide(); }, this)); this._register(editorService.onDidActiveEditorChange(() => { this.hide(); }, this));
this._register(queryModelService.onRunQueryStart(() => { this.hide(); })); this._register(queryModelService.onRunQueryStart(() => { this.hide(); }));
this._register(notebookService.onCodeCellExecutionStart(() => { this.hide(); })); this._register(notebookService.onCodeCellExecutionStart(() => { this.hide(); }));
this._register(queryModelService.onCellSelectionChanged((data: string[]) => { this._register(queryModelService.onCellSelectionChanged((selectedCells: ICellValue[]) => {
this.onCellSelectionChanged(data); this.onCellSelectionChanged(selectedCells);
})); }));
} }
@@ -290,15 +291,15 @@ export class QueryResultSelectionSummaryStatusBarContribution extends Disposable
this.statusbarService.updateEntryVisibility(QueryResultSelectionSummaryStatusBarContribution.ID, true); this.statusbarService.updateEntryVisibility(QueryResultSelectionSummaryStatusBarContribution.ID, true);
} }
private onCellSelectionChanged(data: string[]): void { private onCellSelectionChanged(selectedCells: ICellValue[]): void {
const numericValues = data?.filter(value => !Number.isNaN(Number(value))).map(value => Number(value)); const numericValues = selectedCells?.map(cell => cell.invariantCultureDisplayValue || cell.displayValue).filter(value => !Number.isNaN(Number(value))).map(value => Number(value));
if (numericValues?.length < 2) { if (numericValues?.length < 2) {
this.hide(); this.hide();
return; return;
} }
const sum = numericValues.reduce((previous, current, idx, array) => previous + current); const sum = numericValues.reduce((previous, current, idx, array) => previous + current);
const summaryText = localize('status.query.summaryText', "Average: {0} Count: {1} Sum: {2}", Number((sum / numericValues.length).toFixed(3)), data.length, sum); const summaryText = localize('status.query.summaryText', "Average: {0} Count: {1} Sum: {2}", Number((sum / numericValues.length).toFixed(3)), selectedCells.length, sum);
this.statusItem.update({ this.statusItem.update({
text: summaryText, text: summaryText,
ariaLabel: summaryText ariaLabel: summaryText

View File

@@ -73,4 +73,5 @@ export interface ResultSetSubset {
export interface ICellValue { export interface ICellValue {
displayValue: string; displayValue: string;
isNull?: boolean; isNull?: boolean;
invariantCultureDisplayValue?: string;
} }

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import QueryRunner from 'sql/workbench/services/query/common/queryRunner'; import QueryRunner from 'sql/workbench/services/query/common/queryRunner';
import { IQueryMessage, ResultSetSubset } from 'sql/workbench/services/query/common/query'; import { ICellValue, IQueryMessage, ResultSetSubset } from 'sql/workbench/services/query/common/query';
import { DataService } from 'sql/workbench/services/query/common/dataService'; import { DataService } from 'sql/workbench/services/query/common/dataService';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Event } from 'vs/base/common/event'; import { Event } from 'vs/base/common/event';
@@ -48,8 +48,8 @@ export interface IQueryEvent {
export interface IQueryModelService { export interface IQueryModelService {
_serviceBrand: undefined; _serviceBrand: undefined;
onCellSelectionChanged: Event<string[]>; onCellSelectionChanged: Event<ICellValue[]>;
notifyCellSelectionChanged(selectedValues: string[]): void; notifyCellSelectionChanged(selectedValues: ICellValue[]): void;
getQueryRunner(uri: string): QueryRunner | undefined; getQueryRunner(uri: string): QueryRunner | undefined;

View File

@@ -5,7 +5,7 @@
import * as GridContentEvents from 'sql/workbench/services/query/common/gridContentEvents'; import * as GridContentEvents from 'sql/workbench/services/query/common/gridContentEvents';
import QueryRunner from 'sql/workbench/services/query/common/queryRunner'; import QueryRunner from 'sql/workbench/services/query/common/queryRunner';
import { ResultSetSubset } from 'sql/workbench/services/query/common/query'; import { ICellValue, ResultSetSubset } from 'sql/workbench/services/query/common/query';
import { DataService } from 'sql/workbench/services/query/common/dataService'; import { DataService } from 'sql/workbench/services/query/common/dataService';
import { IQueryModelService, IQueryEvent } from 'sql/workbench/services/query/common/queryModel'; import { IQueryModelService, IQueryEvent } from 'sql/workbench/services/query/common/queryModel';
@@ -62,7 +62,7 @@ export class QueryModelService implements IQueryModelService {
private _onRunQueryComplete: Emitter<string>; private _onRunQueryComplete: Emitter<string>;
private _onQueryEvent: Emitter<IQueryEvent>; private _onQueryEvent: Emitter<IQueryEvent>;
private _onEditSessionReady: Emitter<azdata.EditSessionReadyParams>; private _onEditSessionReady: Emitter<azdata.EditSessionReadyParams>;
private _onCellSelectionChangedEmitter = new Emitter<string[]>(); private _onCellSelectionChangedEmitter = new Emitter<ICellValue[]>();
// EVENTS ///////////////////////////////////////////////////////////// // EVENTS /////////////////////////////////////////////////////////////
public get onRunQueryStart(): Event<string> { return this._onRunQueryStart.event; } public get onRunQueryStart(): Event<string> { return this._onRunQueryStart.event; }
@@ -70,7 +70,7 @@ export class QueryModelService implements IQueryModelService {
public get onRunQueryComplete(): Event<string> { return this._onRunQueryComplete.event; } public get onRunQueryComplete(): Event<string> { return this._onRunQueryComplete.event; }
public get onQueryEvent(): Event<IQueryEvent> { return this._onQueryEvent.event; } public get onQueryEvent(): Event<IQueryEvent> { return this._onQueryEvent.event; }
public get onEditSessionReady(): Event<azdata.EditSessionReadyParams> { return this._onEditSessionReady.event; } public get onEditSessionReady(): Event<azdata.EditSessionReadyParams> { return this._onEditSessionReady.event; }
public get onCellSelectionChanged(): Event<string[]> { return this._onCellSelectionChangedEmitter.event; } public get onCellSelectionChanged(): Event<ICellValue[]> { return this._onCellSelectionChangedEmitter.event; }
// CONSTRUCTOR ///////////////////////////////////////////////////////// // CONSTRUCTOR /////////////////////////////////////////////////////////
constructor( constructor(
@@ -100,10 +100,10 @@ export class QueryModelService implements IQueryModelService {
/** /**
* Notify the event subscribers about the new selected cell values * Notify the event subscribers about the new selected cell values
* @param selectedValues current selected cell values * @param selectedCells current selected cells
*/ */
public notifyCellSelectionChanged(selectedValues: string[]): void { public notifyCellSelectionChanged(selectedCells: ICellValue[]): void {
this._onCellSelectionChangedEmitter.fire(selectedValues); this._onCellSelectionChangedEmitter.fire(selectedCells);
} }
/** /**

View File

@@ -10,12 +10,12 @@ import { Event } from 'vs/base/common/event';
import { QueryInfo } from 'sql/workbench/services/query/common/queryModelService'; import { QueryInfo } from 'sql/workbench/services/query/common/queryModelService';
import { DataService } from 'sql/workbench/services/query/common/dataService'; import { DataService } from 'sql/workbench/services/query/common/dataService';
import { IRange } from 'vs/editor/common/core/range'; import { IRange } from 'vs/editor/common/core/range';
import { ICellValue } from 'sql/workbench/services/query/common/query';
export class TestQueryModelService implements IQueryModelService { export class TestQueryModelService implements IQueryModelService {
_serviceBrand: any; _serviceBrand: any;
onRunQueryUpdate: Event<string>; onRunQueryUpdate: Event<string>;
onCellSelectionChanged: Event<string[]>; onCellSelectionChanged: Event<ICellValue[]>;
notifyCellSelectionChanged(selectedValues: string[]): void { notifyCellSelectionChanged(selectedCells: ICellValue[]): void {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }
getQueryRunner(uri: string): QueryRunner { getQueryRunner(uri: string): QueryRunner {