From 10875f26dcd9b4acbef012b0bc05253a9456fbc0 Mon Sep 17 00:00:00 2001 From: Abbie Petchtes Date: Wed, 12 Sep 2018 20:18:40 -0700 Subject: [PATCH] add divcontainer in modelview (#2559) * add divcontainer in modelview * address comment --- .../components.contribution.ts | 5 +- .../modelComponents/divContainer.component.ts | 120 ++++++++++++++++++ .../parts/modelComponents/divContainer.css | 5 + src/sql/sqlops.proposed.d.ts | 45 +++++++ .../workbench/api/common/sqlExtHostTypes.ts | 1 + .../workbench/api/node/extHostModelView.ts | 62 ++++++--- 6 files changed, 219 insertions(+), 19 deletions(-) create mode 100644 src/sql/parts/modelComponents/divContainer.component.ts create mode 100644 src/sql/parts/modelComponents/divContainer.css diff --git a/src/sql/parts/modelComponents/components.contribution.ts b/src/sql/parts/modelComponents/components.contribution.ts index 3851bb5563..69ee3cc684 100644 --- a/src/sql/parts/modelComponents/components.contribution.ts +++ b/src/sql/parts/modelComponents/components.contribution.ts @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - +import DivContainer from './divContainer.component'; import FlexContainer from './flexContainer.component'; import FormContainer from './formContainer.component'; import ToolbarContainer from './toolbarContainer.component'; @@ -25,6 +25,9 @@ import EditorComponent from './editor.component'; import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry'; import { ModelComponentTypes } from 'sql/workbench/api/common/sqlExtHostTypes'; +export const DIV_CONTAINER = 'div-container'; +registerComponentType(DIV_CONTAINER, ModelComponentTypes.DivContainer, DivContainer); + export const FLEX_CONTAINER = 'flex-container'; registerComponentType(FLEX_CONTAINER, ModelComponentTypes.FlexContainer, FlexContainer); diff --git a/src/sql/parts/modelComponents/divContainer.component.ts b/src/sql/parts/modelComponents/divContainer.component.ts new file mode 100644 index 0000000000..ca0d46fb8e --- /dev/null +++ b/src/sql/parts/modelComponents/divContainer.component.ts @@ -0,0 +1,120 @@ +/*--------------------------------------------------------------------------------------------- + * 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!./divContainer'; + +import { + Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver, + ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList, +} from '@angular/core'; + +import { IComponent, IComponentDescriptor, IModelStore } from 'sql/parts/modelComponents/interfaces'; +import * as sqlops from 'sqlops'; + +import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service'; +import { ContainerBase } from 'sql/parts/modelComponents/componentBase'; +import { ModelComponentWrapper } from 'sql/parts/modelComponents/modelComponentWrapper.component'; + +import types = require('vs/base/common/types'); + +class DivItem { + constructor(public descriptor: IComponentDescriptor, public config: sqlops.DivItemLayout) { } +} + +@Component({ + template: ` +
+
+ + +
+
+ ` +}) +export default class DivContainer extends ContainerBase implements IComponent, OnDestroy { + @Input() descriptor: IComponentDescriptor; + @Input() modelStore: IModelStore; + @ViewChild('divContainer', { read: ElementRef }) divContainer; + private _height: string; + private _width: string; + private _overflowY: string; + + constructor( + @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef, + @Inject(forwardRef(() => ElementRef)) el: ElementRef + ) { + super(changeRef, el); + this._overflowY = ''; // default + } + + ngOnInit(): void { + this.baseInit(); + } + + ngOnDestroy(): void { + this.baseDestroy(); + } + + + /// IComponent implementation + + public setLayout(layout: sqlops.DivLayout): void { + this._height = this.convertSize(layout.height); + this._width = this.convertSize(layout.width); + this.layout(); + } + + public setProperties(properties: { [key: string]: any; }): void { + super.setProperties(properties); + if (this.overflowY !== this._overflowY) { + this.updateOverflowY(); + } + this.updateScroll(); + } + + private updateOverflowY() { + this._overflowY = this.overflowY; + if (this._overflowY) { + let element = this.divContainer.nativeElement; + element.style.overflowY = this._overflowY; + } + } + + private updateScroll() { + let element = this.divContainer.nativeElement; + element.scrollTop = element.scrollTop - this.yOffsetChange; + element.dispatchEvent(new Event('scroll')); + } + + // CSS-bound properties + public get height(): string { + return this._height; + } + + public get width(): string { + return this._width; + } + + // CSS-bound properties + public get overflowY(): string { + return this.getPropertyOrDefault((props) => props.overflowY, ''); + } + public set overflowY(newValue: string) { + this.setPropertyFromUI((properties, newValue) => { properties.overflowY = newValue; }, newValue); + } + + public get yOffsetChange(): number { + return this.getPropertyOrDefault((props) => props.yOffsetChange, 0); + } + public set yOffsetChange(newValue: number) { + this.setPropertyFromUI((properties, newValue) => { properties.yOffsetChange = newValue; }, newValue); + } + + private getItemOrder(item: DivItem): number { + return item.config ? item.config.order : 0; + } + private getItemStyles(item: DivItem): { [key: string]: string } { + return item.config && item.config.CSSStyles ? item.config.CSSStyles : {}; + } +} diff --git a/src/sql/parts/modelComponents/divContainer.css b/src/sql/parts/modelComponents/divContainer.css new file mode 100644 index 0000000000..16f0d4ffa0 --- /dev/null +++ b/src/sql/parts/modelComponents/divContainer.css @@ -0,0 +1,5 @@ + +.divContainer { + display: block; + height: 100%; +} \ No newline at end of file diff --git a/src/sql/sqlops.proposed.d.ts b/src/sql/sqlops.proposed.d.ts index c13005f2de..21f5517914 100644 --- a/src/sql/sqlops.proposed.d.ts +++ b/src/sql/sqlops.proposed.d.ts @@ -17,6 +17,7 @@ declare module 'sqlops' { */ export interface ModelBuilder { navContainer(): ContainerBuilder; + divContainer(): DivBuilder; flexContainer(): FlexBuilder; card(): ComponentBuilder; inputBox(): ComponentBuilder; @@ -72,6 +73,10 @@ declare module 'sqlops' { } + export interface DivBuilder extends ContainerBuilder { + + } + export interface GroupBuilder extends ContainerBuilder { } @@ -346,6 +351,33 @@ declare module 'sqlops' { export interface GroupItemLayout { } + export interface DivLayout { + /** + * Container Height + */ + height?: number | string; + + /** + * Container Width + */ + width?: number | string; + } + + export interface DivItemLayout { + /** + * Matches the order CSS property and its available values. + */ + order?: number; + + /** + * Matches the CSS style key and its available values. + */ + CSSStyles?: { [key: string]: string }; + } + + export interface DivContainer extends Container, DivContainerProperties { + } + export interface FlexContainer extends Container { } @@ -568,6 +600,19 @@ declare module 'sqlops' { loading?: boolean; } + export interface DivContainerProperties extends ComponentProperties { + /** + * Matches the overflow-y CSS property and its available values. + */ + overflowY?: string; + + /** + * Setting the scroll based on the y offset + * This is used when its child component is webview + */ + yOffsetChange?: number; + } + export interface CardComponent extends Component, CardProperties { onDidActionClick: vscode.Event; onCardSelectedChanged: vscode.Event; diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index a593e8a7d0..66df5de751 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -131,6 +131,7 @@ export enum FrequencyRelativeIntervals { export enum ModelComponentTypes { NavContainer, + DivContainer, FlexContainer, Card, InputBox, diff --git a/src/sql/workbench/api/node/extHostModelView.ts b/src/sql/workbench/api/node/extHostModelView.ts index 6a5ce5f213..c11ade049c 100644 --- a/src/sql/workbench/api/node/extHostModelView.ts +++ b/src/sql/workbench/api/node/extHostModelView.ts @@ -32,14 +32,21 @@ class ModelBuilderImpl implements sqlops.ModelBuilder { navContainer(): sqlops.ContainerBuilder { let id = this.getNextComponentId(); - let container: ContainerBuilderImpl = new ContainerBuilderImpl(this._proxy, this._handle, ModelComponentTypes.NavContainer, id); + let container: GenericContainerBuilder = new GenericContainerBuilder(this._proxy, this._handle, ModelComponentTypes.NavContainer, id); + this._componentBuilders.set(id, container); + return container; + } + + divContainer(): sqlops.DivBuilder { + let id = this.getNextComponentId(); + let container = new DivContainerBuilder(this._proxy, this._handle, ModelComponentTypes.DivContainer, id); this._componentBuilders.set(id, container); return container; } flexContainer(): sqlops.FlexBuilder { let id = this.getNextComponentId(); - let container: ContainerBuilderImpl = new ContainerBuilderImpl(this._proxy, this._handle, ModelComponentTypes.FlexContainer, id); + let container: GenericContainerBuilder = new GenericContainerBuilder(this._proxy, this._handle, ModelComponentTypes.FlexContainer, id); this._componentBuilders.set(id, container); return container; } @@ -60,7 +67,7 @@ class ModelBuilderImpl implements sqlops.ModelBuilder { groupContainer(): sqlops.GroupBuilder { let id = this.getNextComponentId(); - let container: ContainerBuilderImpl = new ContainerBuilderImpl(this._proxy, this._handle, ModelComponentTypes.Group, id); + let container: GenericContainerBuilder = new GenericContainerBuilder(this._proxy, this._handle, ModelComponentTypes.Group, id); this._componentBuilders.set(id, container); return container; } @@ -241,17 +248,9 @@ class ComponentBuilderImpl implements sqlops.Compone } } -class GenericComponentBuilder extends ComponentBuilderImpl { - constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) { - super(new ComponentWrapper(proxy, handle, type, id)); - } - -} - - class ContainerBuilderImpl extends ComponentBuilderImpl implements sqlops.ContainerBuilder { - constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) { - super(new ComponentWrapper(proxy, handle, type, id)); + constructor(componentWrapper: ComponentWrapper) { + super(componentWrapper); } withLayout(layout: TLayout): sqlops.ContainerBuilder { @@ -268,7 +267,19 @@ class ContainerBuilderImpl ext } } -class FormContainerBuilder extends ContainerBuilderImpl implements sqlops.FormBuilder { +class GenericContainerBuilder extends ContainerBuilderImpl { + constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) { + super(new ComponentWrapper(proxy, handle, type, id)); + } +} + +class DivContainerBuilder extends ContainerBuilderImpl { + constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) { + super(new DivContainerWrapper(proxy, handle, type, id)); + } +} + +class FormContainerBuilder extends GenericContainerBuilder implements sqlops.FormBuilder { constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string, private _builder: ModelBuilderImpl) { super(proxy, handle, type, id); } @@ -376,7 +387,7 @@ class FormContainerBuilder extends ContainerBuilderImpl implements sqlops.ToolbarBuilder { +class ToolbarContainerBuilder extends GenericContainerBuilder implements sqlops.ToolbarBuilder { withToolbarItems(components: sqlops.ToolbarComponent[]): sqlops.ContainerBuilder { this._component.itemConfigs = components.map(item => { return this.convertToItemConfig(item); @@ -844,9 +855,6 @@ class WebViewWrapper extends ComponentWrapper implements sqlops.WebViewComponent public set options(o: vscode.WebviewOptions) { this.setProperty('options', o); } - - - } class EditorWrapper extends ComponentWrapper implements sqlops.EditorComponent { @@ -1162,6 +1170,24 @@ class FileBrowserTreeComponentWrapper extends ComponentWrapper implements sqlops } } +class DivContainerWrapper extends ComponentWrapper implements sqlops.DivContainer { + public get overflowY(): string { + return this.properties['overflowY']; + } + + public set overflowY(value: string) { + this.setProperty('overflowY', value); + } + + public get yOffsetChange(): number { + return this.properties['yOffsetChange']; + } + + public set yOffsetChange(value: number) { + this.setProperty('yOffsetChange', value); + } +} + class TreeComponentWrapper extends ComponentWrapper implements sqlops.TreeComponent { constructor(