table designer new features (#18682)

* support graph tables

* ignore script compare

* ability to refresh view after edit

* reserve focus after refresh view

* primary key and default constraint

* bug fixes

* vbump sts

* comments

* update type

* fix issue
This commit is contained in:
Alan Ren
2022-03-09 14:17:01 -08:00
committed by GitHub
parent 27763c860c
commit e50bded5d1
19 changed files with 352 additions and 153 deletions

View File

@@ -5,7 +5,7 @@
import 'vs/css!./media/buttonColumn.plugin';
import 'vs/css!./media/iconColumn';
import { BaseClickableColumn, getIconCellValue, IconColumnOptions } from 'sql/base/browser/ui/table/plugins/tableColumn';
import { BaseClickableColumn, ClickableColumnOptions, getIconCellValue, IconColumnOptions } from 'sql/base/browser/ui/table/plugins/tableColumn';
import { escape } from 'sql/base/common/strings';
export interface ButtonCellValue {
@@ -13,7 +13,7 @@ export interface ButtonCellValue {
title: string;
}
export interface ButtonColumnOptions extends IconColumnOptions {
export interface ButtonColumnOptions extends IconColumnOptions, ClickableColumnOptions {
/**
* Whether to show the text.
*/
@@ -23,7 +23,7 @@ export interface ButtonColumnOptions extends IconColumnOptions {
export class ButtonColumn<T extends Slick.SlickData> extends BaseClickableColumn<T> {
constructor(private options: ButtonColumnOptions) {
super();
super(options);
}
public get definition(): Slick.Column<T> {
@@ -39,7 +39,8 @@ export class ButtonColumn<T extends Slick.SlickData> extends BaseClickableColumn
}
const buttonTypeCssClass = this.options.showText ? 'slick-plugin-button slick-plugin-text-button' : 'slick-plugin-button slick-plugin-image-only-button';
const buttonText = this.options.showText ? escapedTitle : '';
return `<button tabindex=-1 class="${iconCssClasses} ${buttonTypeCssClass}" title="${escapedTitle}" aria-label="${escapedTitle}">${buttonText}</button>`;
const disabledAttribute = this.isCellEnabled(row, cell) ? '' : 'disabled';
return `<button tabindex=-1 class="${iconCssClasses} ${buttonTypeCssClass}" title="${escapedTitle}" aria-label="${escapedTitle}" ${disabledAttribute}>${buttonText}</button>`;
},
name: this.options.name,
resizable: this.options.resizable,

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/hyperlinkColumn.plugin';
import 'vs/css!./media/iconColumn';
import { BaseClickableColumn, getIconCellValue, IconColumnOptions } from 'sql/base/browser/ui/table/plugins/tableColumn';
import { BaseClickableColumn, getIconCellValue, ClickableColumnOptions, IconColumnOptions } from 'sql/base/browser/ui/table/plugins/tableColumn';
import { escape } from 'sql/base/common/strings';
export interface HyperlinkCellValue {
@@ -13,12 +13,12 @@ export interface HyperlinkCellValue {
url?: string;
}
export interface HyperlinkColumnOptions extends IconColumnOptions {
export interface HyperlinkColumnOptions extends IconColumnOptions, ClickableColumnOptions {
}
export class HyperlinkColumn<T extends Slick.SlickData> extends BaseClickableColumn<T> {
constructor(private options: HyperlinkColumnOptions) {
super();
super(options);
}
public get definition(): Slick.Column<T> {
@@ -31,7 +31,8 @@ export class HyperlinkColumn<T extends Slick.SlickData> extends BaseClickableCol
const cellValue = dataContext[this.options.field] as HyperlinkCellValue;
const cssClasses = iconValue.iconCssClass ? `codicon icon slick-plugin-icon ${iconValue.iconCssClass}` : '';
const urlPart = cellValue?.url ? `href="${encodeURI(cellValue.url)}" target="blank"` : '';
return `<a ${urlPart} class="slick-hyperlink-cell ${cssClasses}" tabindex=-1 title="${escapedTitle}" aria-label="${escapedTitle}">${escapedTitle}</a>`;
const disabledAttribute = this.isCellEnabled(row, cell) ? '' : 'disabled';
return `<a ${urlPart} class="slick-hyperlink-cell ${cssClasses}" tabindex=-1 title="${escapedTitle}" aria-label="${escapedTitle}" ${disabledAttribute}>${escapedTitle}</a>`;
},
name: this.options.name,
resizable: true,

View File

@@ -12,6 +12,11 @@
padding-bottom: 0px;
}
.slick-plugin-button:disabled {
cursor: not-allowed;
opacity: 0.4;
}
.slick-plugin-button.slick-plugin-text-button {
border-width: 1px;
width: 100%;
@@ -27,4 +32,3 @@
border-width: 0px;
background-color: transparent;
}

View File

@@ -17,13 +17,20 @@ export interface TableCellClickEventArgs<T extends Slick.SlickData> {
column: number;
}
export interface ClickableColumnOptions {
/**
* The field name of enabled state in the data.The default enabled state is true.
*/
enabledField?: string;
}
export abstract class BaseClickableColumn<T extends Slick.SlickData> implements Slick.Plugin<T>, TableColumn<T> {
private _handler = new Slick.EventHandler();
private _grid!: Slick.Grid<T>;
private _onClick = new Emitter<TableCellClickEventArgs<T>>();
public onClick = this._onClick.event;
constructor() {
constructor(private readonly _options: ClickableColumnOptions) {
}
public init(grid: Slick.Grid<T>): void {
@@ -46,7 +53,7 @@ export abstract class BaseClickableColumn<T extends Slick.SlickData> implements
public abstract get definition(): Slick.Column<T>;
private handleActiveCellChanged(args: Slick.OnActiveCellChangedEventArgs<T>): void {
if (this.isCurrentColumn(args.cell)) {
if (this.isCellEnabled(args.row, args.cell)) {
const cellElement = this._grid.getActiveCellNode();
if (cellElement && cellElement.children) {
const element = cellElement.children[0] as HTMLElement;
@@ -56,7 +63,7 @@ export abstract class BaseClickableColumn<T extends Slick.SlickData> implements
}
private handleClick(args: Slick.OnClickEventArgs<T>): void {
if (this.isCurrentColumn(args.cell)) {
if (this.isCellEnabled(args.row, args.cell)) {
// SlickGrid will automatically set active cell on mouse click event,
// during the process of setting active cell, blur event will be triggered and handled in a setTimeout block,
// on Windows platform, the context menu is html based which will respond the focus related events and hide the context menu.
@@ -69,7 +76,7 @@ export abstract class BaseClickableColumn<T extends Slick.SlickData> implements
private handleKeyboardEvent(e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>): void {
let event = new StandardKeyboardEvent(e);
if ((event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) && this.isCurrentColumn(args.cell)) {
if ((event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) && this.isCellEnabled(args.row, args.cell)) {
event.stopPropagation();
event.preventDefault();
this.fireClickEvent();
@@ -92,8 +99,11 @@ export abstract class BaseClickableColumn<T extends Slick.SlickData> implements
}
}
private isCurrentColumn(columnIndex: number): boolean {
return this._grid.getColumns()[columnIndex]?.id === this.definition.id;
protected isCellEnabled(row: number, cell: number): boolean {
const isCurrentColumn = this._grid.getColumns()[cell]?.id === this.definition.id;
const dataItem = this._grid.getDataItem(row);
const disabled = dataItem && !!this._options.enabledField && dataItem[this._options.enabledField] === false;
return isCurrentColumn && !disabled;
}
}