/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/declarativeTable';
import {
Component, Input, Inject, ChangeDetectorRef, forwardRef, ViewChild, ElementRef, OnDestroy, AfterViewInit
} from '@angular/core';
import * as azdata from 'azdata';
import { ComponentBase } from 'sql/workbench/electron-browser/modelComponents/componentBase';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/workbench/electron-browser/modelComponents/interfaces';
import { ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
export enum DeclarativeDataType {
string = 'string',
category = 'category',
boolean = 'boolean',
editableCategory = 'editableCategory'
}
@Component({
selector: 'modelview-declarativeTable',
template: `
`
})
export default class DeclarativeTableComponent extends ComponentBase implements IComponent, OnDestroy, AfterViewInit {
@Input() descriptor: IComponentDescriptor;
@Input() modelStore: IModelStore;
@ViewChild('container', { read: ElementRef }) private _tableContainer: ElementRef;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef, el);
}
ngOnInit(): void {
this.baseInit();
}
ngAfterViewInit(): void {
}
public validate(): Thenable {
return super.validate().then(valid => {
return valid;
});
}
ngOnDestroy(): void {
this.baseDestroy();
}
private isCheckBox(cell: number): boolean {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
return column.valueType === DeclarativeDataType.boolean;
}
private isControlEnabled(cell: number): boolean {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
return !column.isReadOnly;
}
private isLabel(cell: number): boolean {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
return column.isReadOnly && column.valueType === DeclarativeDataType.string;
}
private isChecked(row: number, cell: number): boolean {
let cellData = this.data[row][cell];
return cellData;
}
private onInputBoxChanged(e: string, row: number, cell: number): void {
this.onCellDataChanged(e, row, cell);
}
private onCheckBoxChanged(e: boolean, row: number, cell: number): void {
this.onCellDataChanged(e, row, cell);
}
private onSelectBoxChanged(e: ISelectData | string, row: number, cell: number): void {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
if (column.categoryValues) {
if (typeof e === 'string') {
let category = column.categoryValues.find(c => c.displayName === e);
if (category) {
this.onCellDataChanged(category.name, row, cell);
} else {
this.onCellDataChanged(e, row, cell);
}
} else {
this.onCellDataChanged(column.categoryValues[e.index].name, row, cell);
}
}
}
private onCellDataChanged(newValue: any, row: number, cell: number): void {
this.data[row][cell] = newValue;
this.data = this.data;
let newCellData: azdata.TableCell = {
row: row,
column: cell,
value: newValue
};
this.fireEvent({
eventType: ComponentEventType.onDidChange,
args: newCellData
});
}
private isSelectBox(cell: number): boolean {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
return column.valueType === DeclarativeDataType.category;
}
private isEditableSelectBox(cell: number): boolean {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
return column.valueType === DeclarativeDataType.editableCategory;
}
private isInputBox(cell: number): boolean {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
return column.valueType === DeclarativeDataType.string && !column.isReadOnly;
}
private getColumnWidth(cell: number): string {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
return this.convertSize(column.width, '30px');
}
private GetOptions(cell: number): string[] {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
return column.categoryValues ? column.categoryValues.map(x => x.displayName) : [];
}
private GetSelectedOptionDisplayName(row: number, cell: number): string {
let column: azdata.DeclarativeTableColumn = this.columns[cell];
let cellData = this.data[row][cell];
if (cellData && column.categoryValues) {
let category = column.categoryValues.find(v => v.name === cellData);
if (category) {
return category.displayName;
} else if (this.isEditableSelectBox(cell)) {
return cellData;
} else {
return undefined;
}
} else {
return '';
}
}
/// IComponent implementation
public setLayout(layout: any): void {
// TODO allow configuring the look and feel
this.layout();
}
public setProperties(properties: { [key: string]: any; }): void {
super.setProperties(properties);
}
public get data(): any[][] {
return this.getPropertyOrDefault((props) => props.data, []);
}
public set data(newValue: any[][]) {
this.setPropertyFromUI((props, value) => props.data = value, newValue);
}
public get columns(): azdata.DeclarativeTableColumn[] {
return this.getPropertyOrDefault((props) => props.columns, []);
}
public set columns(newValue: azdata.DeclarativeTableColumn[]) {
this.setPropertyFromUI((props, value) => props.columns = value, newValue);
}
}