diff --git a/src/sql/base/browser/ui/editableDropdown/editableDropdown.component.ts b/src/sql/base/browser/ui/editableDropdown/editableDropdown.component.ts new file mode 100644 index 0000000000..76690be161 --- /dev/null +++ b/src/sql/base/browser/ui/editableDropdown/editableDropdown.component.ts @@ -0,0 +1,75 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { + Component, Inject, forwardRef, ElementRef, OnInit, Input, + Output, OnChanges, SimpleChanges, EventEmitter +} from '@angular/core'; + +import { Dropdown, IDropdownOptions } from 'sql/base/browser/ui/editableDropdown/dropdown'; +import { AngularDisposable } from 'sql/base/common/lifecycle'; + +import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { attachEditableDropdownStyler } from 'sql/common/theme/styler'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; + +@Component({ + selector: 'editable-select-box', + template: '' +}) +export class EditableDropDown extends AngularDisposable implements OnInit, OnChanges { + private _selectbox: Dropdown; + + @Input() options: string[]; + @Input() selectedOption: string; + @Input() onlyEmitOnChange = false; + + @Output() onDidSelect = new EventEmitter(); + + private _previousVal: string; + + constructor( + @Inject(forwardRef(() => ElementRef)) private _el: ElementRef, + @Inject(IThemeService) private themeService: IThemeService, + @Inject(IContextViewService) private contextViewService: IContextViewService + ) { + super(); + } + + ngOnInit(): void { + let dropdownOptions: IDropdownOptions = { + values: [], + strictSelection: false, + placeholder: '', + maxHeight: 125, + ariaLabel: '', + actionLabel: '' + }; + this._selectbox = new Dropdown(this._el.nativeElement, this.contextViewService, this.themeService, dropdownOptions); + this._selectbox.values = this.options; + this._selectbox.value = this.selectedOption; + + this._selectbox.onValueChange(e => { + if (this.onlyEmitOnChange) { + if (this._previousVal !== e) { + this.onDidSelect.emit(e); + this._previousVal = e; + } + } else { + this.onDidSelect.emit(e); + } + }); + this._register(attachEditableDropdownStyler(this._selectbox, this.themeService)); + } + + ngOnChanges(changes: SimpleChanges): void { + } + + public get value(): string { + return this._selectbox.value; + } +} diff --git a/src/sql/parts/dashboard/dashboard.module.ts b/src/sql/parts/dashboard/dashboard.module.ts index 26b3f24d50..f2511e4d5d 100644 --- a/src/sql/parts/dashboard/dashboard.module.ts +++ b/src/sql/parts/dashboard/dashboard.module.ts @@ -57,13 +57,14 @@ import { OperatorsViewComponent } from 'sql/parts/jobManagement/views/operatorsV import { ProxiesViewComponent } from 'sql/parts/jobManagement/views/proxiesView.component'; import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component'; +import { EditableDropDown } from 'sql/base/browser/ui/editableDropdown/editabledropdown.component'; import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox.component'; let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer, DashboardWidgetContainer, DashboardGridContainer, DashboardErrorContainer, DashboardNavSection, ModelViewContent, WebviewContent, WidgetContent, ComponentHostDirective, BreadcrumbComponent, ControlHostContent, DashboardControlHostContainer, JobsViewComponent, AgentViewComponent, JobHistoryComponent, JobStepsViewComponent, AlertsViewComponent, ProxiesViewComponent, OperatorsViewComponent, - DashboardModelViewContainer, ModelComponentWrapper, Checkbox, SelectBox, InputBox,]; + DashboardModelViewContainer, ModelComponentWrapper, Checkbox, EditableDropDown, SelectBox, InputBox,]; /* Panel */ import { PanelModule } from 'sql/base/browser/ui/panel/panel.module'; diff --git a/src/sql/parts/modelComponents/declarativeTable.component.ts b/src/sql/parts/modelComponents/declarativeTable.component.ts index d0dcaee12e..1ba7c09767 100644 --- a/src/sql/parts/modelComponents/declarativeTable.component.ts +++ b/src/sql/parts/modelComponents/declarativeTable.component.ts @@ -17,6 +17,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { Event, Emitter } from 'vs/base/common/event'; import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component'; +import { EditableDropDown } from 'sql/base/browser/ui/editableDropdown/editabledropdown.component'; import { ISelectData } from 'vs/base/browser/ui/selectBox/selectBox'; import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox.component'; import * as nls from 'vs/nls'; @@ -24,29 +25,41 @@ import * as nls from 'vs/nls'; export enum DeclarativeDataType { string = 'string', category = 'category', - boolean = 'boolean' + boolean = 'boolean', + editableCategory = 'editableCategory' } @Component({ selector: 'modelview-declarativeTable', template: ` + + - + + + + + + + + +
{{column.displayName}}{{column.displayName}}
+ {{cellData}}
` @@ -109,10 +122,20 @@ export default class DeclarativeTableComponent extends ComponentBase implements this.onCellDataChanged(e, row, cell); } - private onSelectBoxChanged(e: ISelectData, row: number, cell: number): void { + private onSelectBoxChanged(e: ISelectData | string, row: number, cell: number): void { + let column: sqlops.DeclarativeTableColumn = this.columns[cell]; if (column.categoryValues) { - this.onCellDataChanged(column.categoryValues[e.index].name, row, cell); + 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); + } } } @@ -135,6 +158,11 @@ export default class DeclarativeTableComponent extends ComponentBase implements return column.valueType === DeclarativeDataType.category; } + private isEditableSelectBox(cell: number): boolean { + let column: sqlops.DeclarativeTableColumn = this.columns[cell]; + return column.valueType === DeclarativeDataType.editableCategory; + } + private isInputBox(cell: number): boolean { let column: sqlops.DeclarativeTableColumn = this.columns[cell]; return column.valueType === DeclarativeDataType.string && !column.isReadOnly; @@ -142,7 +170,7 @@ export default class DeclarativeTableComponent extends ComponentBase implements private getColumnWidth(cell: number): string { let column: sqlops.DeclarativeTableColumn = this.columns[cell]; - return this.convertSize(column.width); + return this.convertSize(column.width, '30px'); } private GetOptions(cell: number): string[] { diff --git a/src/sql/parts/modelComponents/declarativeTable.css b/src/sql/parts/modelComponents/declarativeTable.css index 6c44c30651..1247c26eb5 100644 --- a/src/sql/parts/modelComponents/declarativeTable.css +++ b/src/sql/parts/modelComponents/declarativeTable.css @@ -2,7 +2,7 @@ .declarative-table { padding: 5px 30px 0px 30px; box-sizing: border-box; - width:100%; + border-collapse: collapse; } @@ -13,6 +13,7 @@ padding: 5px; border: 1px solid gray; background-color: #F5F5F5; + vertical-align: top; } .vs-dark .declarative-table-header { diff --git a/src/sql/platform/dialog/dialog.module.ts b/src/sql/platform/dialog/dialog.module.ts index 9e66776e44..bf6a88fec3 100644 --- a/src/sql/platform/dialog/dialog.module.ts +++ b/src/sql/platform/dialog/dialog.module.ts @@ -22,6 +22,7 @@ import { IBootstrapParams, ISelector, providerIterator } from 'sql/services/boot import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component'; +import { EditableDropDown } from 'sql/base/browser/ui/editableDropdown/editabledropdown.component'; import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox.component'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -36,6 +37,7 @@ export const DialogModule = (params, selector: string, instantiationService: IIn declarations: [ Checkbox, SelectBox, + EditableDropDown, InputBox, DialogContainer, WizardNavigation, diff --git a/src/sql/sqlops.proposed.d.ts b/src/sql/sqlops.proposed.d.ts index 651725887c..66aa18905f 100644 --- a/src/sql/sqlops.proposed.d.ts +++ b/src/sql/sqlops.proposed.d.ts @@ -390,7 +390,8 @@ declare module 'sqlops' { export enum DeclarativeDataType { string = 'string', category = 'category', - boolean = 'boolean' + boolean = 'boolean', + editableCategory = 'editableCategory' } export interface RadioButtonProperties { diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index dafc7ba2f6..3b149a2f13 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -272,7 +272,8 @@ export enum DataProviderType { export enum DeclarativeDataType { string = 'string', category = 'category', - boolean = 'boolean' + boolean = 'boolean', + editableCategory = 'editableCategory' } export enum CardType {