mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 09:35:37 -05:00
table based explorer widget (#10279)
* bump sts * extend widget container * remove title * wip * refactoring * Revert "extend widget container" * showTitle option * fix properties widget error * icon column * icon and button columns * use textwithicon column * icon * refactor and filter * context menu * refactor * tests * fix hygiene * tests * comments
This commit is contained in:
@@ -162,3 +162,27 @@
|
||||
.hc-black .slick-header-menu {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.slick-icon-cell-content,
|
||||
.slick-button-cell-content {
|
||||
background-position: 7px center !important;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 16px !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-left: 30px;
|
||||
color: inherit !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.slick-icon-cell,
|
||||
.slick-button-cell {
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.slick-button-cell-content {
|
||||
cursor: pointer;
|
||||
border-width: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
99
src/sql/base/browser/ui/table/plugins/buttonColumn.plugin.ts
Normal file
99
src/sql/base/browser/ui/table/plugins/buttonColumn.plugin.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextWithIconColumnDefinition } from 'sql/base/browser/ui/table/plugins/textWithIconColumn';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
|
||||
export interface ButtonColumnDefinition<T extends Slick.SlickData> extends TextWithIconColumnDefinition<T> {
|
||||
}
|
||||
|
||||
export interface ButtonColumnOptions {
|
||||
iconCssClass?: string;
|
||||
title?: string;
|
||||
width?: number;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export interface ButtonClickEventArgs<T extends Slick.SlickData> {
|
||||
item: T;
|
||||
position: { x: number, y: number };
|
||||
}
|
||||
|
||||
export class ButtonColumn<T extends Slick.SlickData> implements Slick.Plugin<T> {
|
||||
private _handler = new Slick.EventHandler();
|
||||
private _definition: ButtonColumnDefinition<T>;
|
||||
private _grid: Slick.Grid<T>;
|
||||
private _onClick = new Emitter<ButtonClickEventArgs<T>>();
|
||||
public onClick = this._onClick.event;
|
||||
|
||||
constructor(private options: ButtonColumnOptions) {
|
||||
this._definition = {
|
||||
id: options.id,
|
||||
resizable: false,
|
||||
name: '',
|
||||
formatter: (row: number, cell: number, value: any, columnDef: Slick.Column<T>, dataContext: T): string => {
|
||||
return this.formatter(row, cell, value, columnDef, dataContext);
|
||||
},
|
||||
width: options.width,
|
||||
selectable: false,
|
||||
iconCssClassField: options.iconCssClass
|
||||
};
|
||||
}
|
||||
|
||||
public init(grid: Slick.Grid<T>): void {
|
||||
this._grid = grid;
|
||||
this._handler.subscribe(grid.onClick, (e: DOMEvent, args: Slick.OnClickEventArgs<T>) => this.handleClick(args));
|
||||
this._handler.subscribe(grid.onKeyDown, (e: DOMEvent, args: Slick.OnKeyDownEventArgs<T>) => this.handleKeyboardEvent(e as KeyboardEvent, args));
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this._handler.unsubscribeAll();
|
||||
}
|
||||
|
||||
private handleClick(args: Slick.OnClickEventArgs<T>): void {
|
||||
if (this.shouldFireClickEvent(args.cell)) {
|
||||
this._grid.setActiveCell(args.row, args.cell);
|
||||
this.fireClickEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private handleKeyboardEvent(e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>): void {
|
||||
let event = new StandardKeyboardEvent(e);
|
||||
if ((event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) && this.shouldFireClickEvent(args.cell)) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
this.fireClickEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public get definition(): ButtonColumnDefinition<T> {
|
||||
return this._definition;
|
||||
}
|
||||
|
||||
private fireClickEvent(): void {
|
||||
const activeCell = this._grid.getActiveCell();
|
||||
const activeCellPosition = this._grid.getActiveCellPosition();
|
||||
if (activeCell && activeCellPosition) {
|
||||
this._onClick.fire({
|
||||
item: this._grid.getDataItem(activeCell.row),
|
||||
position: {
|
||||
x: (activeCellPosition.left + activeCellPosition.right) / 2,
|
||||
y: (activeCellPosition.bottom + activeCellPosition.top) / 2
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private shouldFireClickEvent(columnIndex: number): boolean {
|
||||
return this._grid.getColumns()[columnIndex].id === this.definition.id;
|
||||
}
|
||||
|
||||
private formatter(row: number, cell: number, value: any, columnDef: Slick.Column<T>, dataContext: T): string {
|
||||
const buttonColumn = columnDef as ButtonColumnDefinition<T>;
|
||||
return `<div class="codicon icon slick-button-cell-content ${buttonColumn.iconCssClassField}" aria-label="${this.options.title}"></div>`;
|
||||
}
|
||||
}
|
||||
46
src/sql/base/browser/ui/table/plugins/textWithIconColumn.ts
Normal file
46
src/sql/base/browser/ui/table/plugins/textWithIconColumn.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Definition for column with icon on the left of text.
|
||||
*/
|
||||
export interface TextWithIconColumnDefinition<T extends Slick.SlickData> extends Slick.Column<T> {
|
||||
iconCssClassField?: string;
|
||||
}
|
||||
|
||||
export interface TextWithIconColumnOptions {
|
||||
iconCssClassField?: string;
|
||||
field?: string;
|
||||
width?: number;
|
||||
id?: string;
|
||||
resizable?: boolean;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export class TextWithIconColumn<T extends Slick.SlickData> {
|
||||
|
||||
private _definition: TextWithIconColumnDefinition<T>;
|
||||
|
||||
constructor(options: TextWithIconColumnOptions) {
|
||||
this._definition = {
|
||||
id: options.id,
|
||||
field: options.field,
|
||||
resizable: options.resizable,
|
||||
formatter: this.formatter,
|
||||
width: options.width,
|
||||
name: options.name,
|
||||
iconCssClassField: options.iconCssClassField,
|
||||
cssClass: 'slick-icon-cell'
|
||||
};
|
||||
}
|
||||
private formatter(row: number, cell: number, value: any, columnDef: Slick.Column<T>, dataContext: T): string {
|
||||
const iconColumn = columnDef as TextWithIconColumnDefinition<T>;
|
||||
return `<div class="icon codicon slick-icon-cell-content ${dataContext[iconColumn.iconCssClassField]}">${value}</div>`;
|
||||
}
|
||||
|
||||
public get definition(): TextWithIconColumnDefinition<T> {
|
||||
return this._definition;
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,9 @@ export class Table<T extends Slick.SlickData> extends Widget implements IDisposa
|
||||
private _onClick = new Emitter<ITableMouseEvent>();
|
||||
public readonly onClick: Event<ITableMouseEvent> = this._onClick.event;
|
||||
|
||||
private _onDoubleClick = new Emitter<ITableMouseEvent>();
|
||||
public readonly onDoubleClick: Event<ITableMouseEvent> = this._onDoubleClick.event;
|
||||
|
||||
private _onHeaderClick = new Emitter<ITableMouseEvent>();
|
||||
public readonly onHeaderClick: Event<ITableMouseEvent> = this._onHeaderClick.event;
|
||||
|
||||
@@ -116,6 +119,7 @@ export class Table<T extends Slick.SlickData> extends Widget implements IDisposa
|
||||
this.mapMouseEvent(this._grid.onContextMenu, this._onContextMenu);
|
||||
this.mapMouseEvent(this._grid.onClick, this._onClick);
|
||||
this.mapMouseEvent(this._grid.onHeaderClick, this._onHeaderClick);
|
||||
this.mapMouseEvent(this._grid.onDblClick, this._onDoubleClick);
|
||||
this._grid.onColumnsResized.subscribe(() => this._onColumnResize.fire());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user