From 1847c2e3228d80b99fdf92f28e4e95b36982028f Mon Sep 17 00:00:00 2001 From: Leila Lali Date: Thu, 3 May 2018 17:11:55 -0700 Subject: [PATCH] added checkbox component (#1330) --- .../modelComponents/checkbox.component.ts | 108 ++++++++++++++++++ .../components.contribution.ts | 5 + .../formContainer.component.ts | 54 ++++++--- src/sql/parts/modelComponents/formLayout.css | 24 +++- src/sql/sqlops.proposed.d.ts | 14 ++- .../workbench/api/common/sqlExtHostTypes.ts | 1 + .../workbench/api/node/extHostModelView.ts | 33 ++++++ 7 files changed, 224 insertions(+), 15 deletions(-) create mode 100644 src/sql/parts/modelComponents/checkbox.component.ts diff --git a/src/sql/parts/modelComponents/checkbox.component.ts b/src/sql/parts/modelComponents/checkbox.component.ts new file mode 100644 index 0000000000..edf91666f0 --- /dev/null +++ b/src/sql/parts/modelComponents/checkbox.component.ts @@ -0,0 +1,108 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { + Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver, + ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList, AfterViewInit +} from '@angular/core'; + +import * as sqlops from 'sqlops'; +import Event, { Emitter } from 'vs/base/common/event'; + +import { ComponentBase } from 'sql/parts/modelComponents/componentBase'; +import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces'; +import { Checkbox, ICheckboxOptions } from 'sql/base/browser/ui/checkbox/checkbox'; +import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; +import { attachInputBoxStyler, attachListStyler } from 'vs/platform/theme/common/styler'; + +@Component({ + selector: 'inputBox', + template: ` +
+ ` +}) +export default class CheckBoxComponent extends ComponentBase implements IComponent, OnDestroy, AfterViewInit { + @Input() descriptor: IComponentDescriptor; + @Input() modelStore: IModelStore; + private _input: Checkbox; + + @ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef; + constructor( + @Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface, + @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) { + super(changeRef); + } + + ngOnInit(): void { + this.baseInit(); + + } + + ngAfterViewInit(): void { + if (this._inputContainer) { + let inputOptions: ICheckboxOptions = { + label: '' + }; + + this._input = new Checkbox(this._inputContainer.nativeElement, inputOptions); + + this._register(this._input); + this._register(this._input.onChange(e => { + this.value = this._input.checked; + this._onEventEmitter.fire({ + eventType: ComponentEventType.onDidChange, + args: e + }); + })); + } + } + + ngOnDestroy(): void { + this.baseDestroy(); + } + + /// IComponent implementation + + public layout(): void { + this._changeRef.detectChanges(); + } + + public setLayout(layout: any): void { + // TODO allow configuring the look and feel + this.layout(); + } + + public setProperties(properties: { [key: string]: any; }): void { + super.setProperties(properties); + this._input.checked = this.checked; + this._input.label = this.label; + } + + // CSS-bound properties + + public get checked(): boolean { + return this.getPropertyOrDefault((props) => props.value, false); + } + + public set value(newValue: boolean) { + this.setPropertyFromUI(this.setInputBoxProperties, newValue); + } + + private setInputBoxProperties(properties: sqlops.CheckBoxProperties, value: boolean): void { + properties.checked = value; + } + + private get label(): string { + return this.getPropertyOrDefault((props) => props.label, ''); + } + + private set label(newValue: string) { + this.setPropertyFromUI(this.setValueProperties, newValue); + } + + private setValueProperties(properties: sqlops.CheckBoxProperties, label: string): void { + properties.label = label; + } +} diff --git a/src/sql/parts/modelComponents/components.contribution.ts b/src/sql/parts/modelComponents/components.contribution.ts index 45047b89d8..7df5acd9e2 100644 --- a/src/sql/parts/modelComponents/components.contribution.ts +++ b/src/sql/parts/modelComponents/components.contribution.ts @@ -9,6 +9,7 @@ import CardComponent from './card.component'; import InputBoxComponent from './inputbox.component'; import DropDownComponent from './dropdown.component'; import ButtonComponent from './button.component'; +import CheckBoxComponent from './checkbox.component'; import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry'; import { ModelComponentTypes } from 'sql/workbench/api/common/sqlExtHostTypes'; @@ -29,3 +30,7 @@ registerComponentType(DROPDOWN_COMPONENT, ModelComponentTypes.DropDown, DropDown export const BUTTON_COMPONENT = 'button-component'; registerComponentType(BUTTON_COMPONENT, ModelComponentTypes.Button, ButtonComponent); + + +export const CHECKBOX_COMPONENT = 'checkbox-component'; +registerComponentType(CHECKBOX_COMPONENT, ModelComponentTypes.CheckBox, CheckBoxComponent); diff --git a/src/sql/parts/modelComponents/formContainer.component.ts b/src/sql/parts/modelComponents/formContainer.component.ts index 0190b9dab8..7342871a09 100644 --- a/src/sql/parts/modelComponents/formContainer.component.ts +++ b/src/sql/parts/modelComponents/formContainer.component.ts @@ -21,6 +21,7 @@ export interface TitledFormItemLayout { title: string; actions?: string[]; isFormComponent: Boolean; + horizontal: boolean; } class FormItem { constructor(public descriptor: IComponentDescriptor, public config: TitledFormItemLayout) { } @@ -32,17 +33,36 @@ class FormItem { [style.alignItems]="alignItems" [style.alignContent]="alignContent">
-
{{getItemTitle(item)}}
-
- - -
-
-
- + +
{{getItemTitle(item)}}
+
+
-
+
+
+
+ + +
+
+
+ + +
{{getItemTitle(item)}}
+
+ + +
+
+ +
+ + +
+ +
+
@@ -58,9 +78,9 @@ export default class FormContainer extends ContainerBase impleme @ViewChildren(ModelComponentWrapper) private _componentWrappers: QueryList; @ViewChild('container', { read: ElementRef }) private _container: ElementRef; - constructor ( - @Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface, - @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) { + constructor( + @Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface, + @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) { super(changeRef); } @@ -98,7 +118,7 @@ export default class FormContainer extends ContainerBase impleme return itemConfig ? itemConfig.title : ''; } - private getActionComponents(item: FormItem): FormItem[]{ + private getActionComponents(item: FormItem): FormItem[] { let items = this.items; let itemConfig = item.config; if (itemConfig && itemConfig.actions) { @@ -125,4 +145,12 @@ export default class FormContainer extends ContainerBase impleme public setLayout(layout: any): void { this.layout(); } + + private isHorizontal(item: FormItem): boolean { + return item && item.config && item.config.horizontal; + } + + private isVertical(item: FormItem): boolean { + return item && item.config && !item.config.horizontal; + } } diff --git a/src/sql/parts/modelComponents/formLayout.css b/src/sql/parts/modelComponents/formLayout.css index fa4291768a..d2b2a1520a 100644 --- a/src/sql/parts/modelComponents/formLayout.css +++ b/src/sql/parts/modelComponents/formLayout.css @@ -5,13 +5,35 @@ padding: 30px; } +.form-actions-table { + display:table; +} + .form-row { display: table-row; width: 100px; + padding-bottom: 10px; +} + +.form-item-row { + padding-bottom: 5px; + width: 300px; +} + +.form-item-title { + + padding-top: 20px; } .form-cell { - padding: 5px; + padding-top: 20px; + padding-right: 5px; + display: table-cell; +} + +.form-actions-cell { + padding-top: 5px; + padding-right: 5px; display: table-cell; } diff --git a/src/sql/sqlops.proposed.d.ts b/src/sql/sqlops.proposed.d.ts index 435441465b..5e2cfdb2bc 100644 --- a/src/sql/sqlops.proposed.d.ts +++ b/src/sql/sqlops.proposed.d.ts @@ -20,6 +20,7 @@ declare module 'sqlops' { flexContainer(): FlexBuilder; card(): ComponentBuilder; inputBox(): ComponentBuilder; + checkBox(): ComponentBuilder; button(): ComponentBuilder; dropDown(): ComponentBuilder; dashboardWidget(widgetId: string): ComponentBuilder; @@ -144,7 +145,7 @@ declare module 'sqlops' { } export interface FormItemLayout { - + horizontal: boolean; } export interface FormLayout { @@ -188,6 +189,11 @@ declare module 'sqlops' { value?: string; } + export interface CheckBoxProperties { + checked?: boolean; + label?: string; + } + export interface DropDownProperties { value?: string; values?: string[]; @@ -208,6 +214,12 @@ declare module 'sqlops' { onTextChanged: vscode.Event; } + export interface CheckBoxComponent extends Component { + checked: boolean; + label: string; + onChanged: vscode.Event; + } + export interface DropDownComponent extends Component { value: string; values: string[]; diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index 05f8dd2a9d..921db2e2b7 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -70,6 +70,7 @@ export enum ModelComponentTypes { InputBox, DropDown, Button, + CheckBox, DashboardWidget, DashboardWebview, Form diff --git a/src/sql/workbench/api/node/extHostModelView.ts b/src/sql/workbench/api/node/extHostModelView.ts index d5d517da19..d783234704 100644 --- a/src/sql/workbench/api/node/extHostModelView.ts +++ b/src/sql/workbench/api/node/extHostModelView.ts @@ -48,6 +48,11 @@ class ModelBuilderImpl implements sqlops.ModelBuilder { return this.withEventHandler(new InputBoxWrapper(this._proxy, this._handle, id), id); } + checkBox(): sqlops.ComponentBuilder { + let id = this.getNextComponentId(); + return this.withEventHandler(new CheckBoxWrapper(this._proxy, this._handle, id), id); + } + button(): sqlops.ComponentBuilder { let id = this.getNextComponentId(); return this.withEventHandler(new ButtonWrapper(this._proxy, this._handle, id), id); @@ -343,6 +348,34 @@ class InputBoxWrapper extends ComponentWrapper implements sqlops.InputBoxCompone } } +class CheckBoxWrapper extends ComponentWrapper implements sqlops.CheckBoxComponent { + + constructor(proxy: MainThreadModelViewShape, handle: number, id: string) { + super(proxy, handle, ModelComponentTypes.CheckBox, id); + this.properties = {}; + this._emitterMap.set(ComponentEventType.onDidChange, new Emitter()); + } + + public get checked(): boolean { + return this.properties['checked']; + } + public set checked(v: boolean) { + this.setProperty('checked', v); + } + + public get label(): string { + return this.properties['label']; + } + public set label(v: string) { + this.setProperty('label', v); + } + + public get onChanged(): vscode.Event { + let emitter = this._emitterMap.get(ComponentEventType.onDidChange); + return emitter && emitter.event; + } +} + class DropDownWrapper extends ComponentWrapper implements sqlops.DropDownComponent { constructor(proxy: MainThreadModelViewShape, handle: number, id: string) {