Add support for "More Actions" column in Resource Viewer (#13093)

* Add support for "More Actions" column in resource viewer

* update provider

* remove import

* Use menu contribution and make actions column always show

* cleanup

* move context menu anchor

* Comments
This commit is contained in:
Charles Gagnon
2020-10-29 10:50:27 -07:00
committed by GitHub
parent 10f6fe2d09
commit 66da2a46c5
12 changed files with 189 additions and 43 deletions

View File

@@ -4,12 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/resourceViewerTable';
import * as azdata from 'azdata';
import { Table } from 'sql/base/browser/ui/table/table';
import { attachTableStyler, attachButtonStyler } from 'sql/platform/theme/common/styler';
import { RowSelectionModel } from 'sql/base/browser/ui/table/plugins/rowSelectionModel.plugin';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { isHyperlinkCellValue, slickGridDataItemColumnValueExtractor } from 'sql/base/browser/ui/table/formatters';
import { HyperlinkCellValue, isHyperlinkCellValue, TextCellValue } from 'sql/base/browser/ui/table/formatters';
import { HeaderFilter, CommandEventArgs, IExtendedColumn } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
import { Disposable } from 'vs/base/common/lifecycle';
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
@@ -19,11 +20,17 @@ import { isString } from 'vs/base/common/types';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { localize } from 'vs/nls';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ColumnDefinition } from 'sql/workbench/browser/editor/resourceViewer/resourceViewerInput';
import { Emitter } from 'vs/base/common/event';
import { ContextMenuAnchor } from 'sql/workbench/contrib/resourceViewer/browser/resourceViewerEditor';
export class ResourceViewerTable extends Disposable {
private _resourceViewerTable!: Table<Slick.SlickData>;
private _dataView: TableDataView<Slick.SlickData>;
private _resourceViewerTable!: Table<azdata.DataGridItem>;
private _dataView: TableDataView<azdata.DataGridItem>;
private _onContextMenu = new Emitter<{ anchor: ContextMenuAnchor, item: azdata.DataGridItem }>();
public onContextMenu = this._onContextMenu.event;
constructor(parent: HTMLElement,
@IWorkbenchThemeService private _themeService: IWorkbenchThemeService,
@@ -31,17 +38,17 @@ export class ResourceViewerTable extends Disposable {
@ICommandService private _commandService: ICommandService,
@INotificationService private _notificationService: INotificationService) {
super();
let filterFn = (data: Array<Slick.SlickData>): Array<Slick.SlickData> => {
let filterFn = (data: Array<azdata.DataGridItem>): Array<azdata.DataGridItem> => {
return data.filter(item => this.filter(item));
};
this._dataView = new TableDataView<Slick.SlickData>(undefined, undefined, undefined, filterFn);
this._dataView = new TableDataView<azdata.DataGridItem>(undefined, undefined, undefined, filterFn);
this._resourceViewerTable = this._register(new Table(parent, {
sorter: (args) => {
this._dataView.sort(args);
}
}, {
dataItemColumnValueExtractor: slickGridDataItemColumnValueExtractor,
dataItemColumnValueExtractor: dataGridColumnValueExtractor,
forceFitColumns: true
}));
this._resourceViewerTable.setSelectionModel(new RowSelectionModel());
@@ -49,7 +56,12 @@ export class ResourceViewerTable extends Disposable {
this._register(attachButtonStyler(filterPlugin, this._themeService));
this._register(attachTableStyler(this._resourceViewerTable, this._themeService));
this._register(this._resourceViewerTable.onClick(this.onTableClick, this));
this._register(this._resourceViewerTable.onContextMenu((e: ITableMouseEvent) => {
this._onContextMenu.fire({
anchor: e.anchor,
item: this._dataView.getItem(e.cell.row)
});
}));
filterPlugin.onFilterApplied.subscribe(() => {
this._dataView.filter();
this._resourceViewerTable.grid.invalidate();
@@ -57,7 +69,7 @@ export class ResourceViewerTable extends Disposable {
this._resourceViewerTable.grid.resetActiveCell();
this._resourceViewerTable.grid.resizeCanvas();
});
filterPlugin.onCommand.subscribe((e, args: CommandEventArgs<Slick.SlickData>) => {
filterPlugin.onCommand.subscribe((e, args: CommandEventArgs<azdata.DataGridItem>) => {
// Convert filter command to SlickGrid sort args
this._dataView.sort({
grid: args.grid,
@@ -71,7 +83,7 @@ export class ResourceViewerTable extends Disposable {
this._resourceViewerTable.registerPlugin(filterPlugin);
}
public set data(data: Slick.SlickData[]) {
public set data(data: azdata.DataGridItem[]) {
this._dataView.clear();
this._dataView.push(data);
this._resourceViewerTable.grid.setData(this._dataView, true);
@@ -82,6 +94,14 @@ export class ResourceViewerTable extends Disposable {
this._resourceViewerTable.columns = columns;
}
public registerPlugin(plugin: Slick.Plugin<azdata.DataGridItem>): void {
this._resourceViewerTable.registerPlugin(plugin);
}
public unregisterPlugin(plugin: Slick.Plugin<azdata.DataGridItem>): void {
this._resourceViewerTable.unregisterPlugin(plugin);
}
public focus(): void {
this._resourceViewerTable.focus();
}
@@ -107,10 +127,10 @@ export class ResourceViewerTable extends Disposable {
}
private async onTableClick(event: ITableMouseEvent): Promise<void> {
const column = this._resourceViewerTable.columns[event.cell.cell];
const column = this._resourceViewerTable.columns[event.cell.cell] as ColumnDefinition;
if (column) {
const row = this._dataView.getItem(event.cell.row);
const value = row[column.field];
const value = row.fieldValues[column.field];
if (isHyperlinkCellValue(value)) {
if (isString(value.linkOrCommand)) {
try {
@@ -118,7 +138,6 @@ export class ResourceViewerTable extends Disposable {
} catch (err) {
this._notificationService.error(localize('resourceViewerTable.openError', "Error opening link : {0}", err.message ?? err));
}
} else {
try {
await this._commandService.executeCommand(value.linkOrCommand.id, ...(value.linkOrCommand.args ?? []));
@@ -130,3 +149,18 @@ export class ResourceViewerTable extends Disposable {
}
}
}
/**
* Extracts the specified field into the expected object to be handled by SlickGrid and/or formatters as needed.
*/
function dataGridColumnValueExtractor(value: azdata.DataGridItem, columnDef: ColumnDefinition): TextCellValue | HyperlinkCellValue {
const fieldValue = value.fieldValues[columnDef.field];
if (columnDef.type === 'hyperlink') {
return fieldValue as HyperlinkCellValue;
} else {
return <TextCellValue>{
text: fieldValue,
ariaLabel: fieldValue ? escape(fieldValue as string) : fieldValue
};
}
}