Add hyperlink support to DataGrid columns (#13061)

* Add hyperlink support to DataGrid columns

* pr feedback

* Remove unused aria label

* fix error message display

* fix compile
This commit is contained in:
Charles Gagnon
2020-10-26 08:43:09 -07:00
committed by GitHub
parent 3ad39bd0d3
commit ff45bdd072
4 changed files with 137 additions and 31 deletions

View File

@@ -13,6 +13,7 @@ import { getDataGridFormatter } from 'sql/workbench/services/dataGridProvider/br
export interface ColumnDefinition extends Slick.Column<Slick.SlickData> {
name: string;
type: string;
filterable?: boolean;
}
@@ -69,28 +70,27 @@ export class ResourceViewerInput extends EditorInput {
]);
}
private fetchColumns(): void {
this._dataGridProvider.getDataGridColumns(this._providerId).then(columns => {
this.columns = columns.map(col => {
return {
name: col.name,
field: col.field,
id: col.id,
formatter: getDataGridFormatter(col.type),
sortable: col.sortable ?? true,
filterable: col.filterable ?? true,
resizable: col.resizable ?? true,
tooltip: col.tooltip,
width: col.width
};
});
}).catch(err => onUnexpectedError(err));
private async fetchColumns(): Promise<void> {
const columns = await this._dataGridProvider.getDataGridColumns(this._providerId);
this.columns = columns.map(col => {
return {
name: col.name,
field: col.field,
id: col.id,
formatter: getDataGridFormatter(col.type),
sortable: col.sortable ?? true,
filterable: col.filterable ?? true,
resizable: col.resizable ?? true,
tooltip: col.tooltip,
width: col.width,
type: col.type
};
});
}
private fetchItems(): void {
this._dataGridProvider.getDataGridItems(this._providerId).then(items => {
this._data = items;
this._onDataChanged.fire();
}).catch(err => onUnexpectedError(err));
private async fetchItems(): Promise<void> {
const items = await this._dataGridProvider.getDataGridItems(this._providerId);
this._data = items;
this._onDataChanged.fire();
}
}

View File

@@ -9,17 +9,27 @@ import { attachTableStyler, attachButtonStyler } from 'sql/platform/theme/common
import { RowSelectionModel } from 'sql/base/browser/ui/table/plugins/rowSelectionModel.plugin';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { slickGridDataItemColumnValueExtractor } from 'sql/base/browser/ui/table/formatters';
import { isHyperlinkCellValue, slickGridDataItemColumnValueExtractor } 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';
import { ITableMouseEvent } from 'sql/base/browser/ui/table/interfaces';
import { IOpenerService } from 'vs/platform/opener/common/opener';
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';
export class ResourceViewerTable extends Disposable {
private _resourceViewerTable!: Table<Slick.SlickData>;
private _dataView: TableDataView<Slick.SlickData>;
constructor(parent: HTMLElement, @IWorkbenchThemeService private _themeService: IWorkbenchThemeService) {
constructor(parent: HTMLElement,
@IWorkbenchThemeService private _themeService: IWorkbenchThemeService,
@IOpenerService private _openerService: IOpenerService,
@ICommandService private _commandService: ICommandService,
@INotificationService private _notificationService: INotificationService) {
super();
let filterFn = (data: Array<Slick.SlickData>): Array<Slick.SlickData> => {
return data.filter(item => this.filter(item));
@@ -38,6 +48,8 @@ export class ResourceViewerTable extends Disposable {
let filterPlugin = new HeaderFilter<Slick.SlickData>();
this._register(attachButtonStyler(filterPlugin, this._themeService));
this._register(attachTableStyler(this._resourceViewerTable, this._themeService));
this._register(this._resourceViewerTable.onClick(this.onTableClick, this));
filterPlugin.onFilterApplied.subscribe(() => {
this._dataView.filter();
this._resourceViewerTable.grid.invalidate();
@@ -93,4 +105,28 @@ export class ResourceViewerTable extends Disposable {
}
return value;
}
private async onTableClick(event: ITableMouseEvent): Promise<void> {
const column = this._resourceViewerTable.columns[event.cell.cell];
if (column) {
const row = this._dataView.getItem(event.cell.row);
const value = row[column.field];
if (isHyperlinkCellValue(value)) {
if (isString(value.linkOrCommand)) {
try {
await this._openerService.open(value.linkOrCommand);
} 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 ?? []));
} catch (err) {
this._notificationService.error(localize('resourceViewerTable.commandError', "Error executing command '{0}' : {1}", value.linkOrCommand.id, err.message ?? err));
}
}
}
}
}
}