add divcontainer in modelview (#2559)

* add divcontainer in modelview

* address comment
This commit is contained in:
Abbie Petchtes
2018-09-12 20:18:40 -07:00
committed by GitHub
parent d62e809c18
commit 10875f26dc
6 changed files with 219 additions and 19 deletions

View File

@@ -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);

View File

@@ -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: `
<div #divContainer *ngIf="items" class="divContainer" [style.height]="height" [style.width]="width">
<div *ngFor="let item of items" [style.order]="getItemOrder(item)" [ngStyle]="getItemStyles(item)">
<model-component-wrapper [descriptor]="item.descriptor" [modelStore]="modelStore">
</model-component-wrapper>
</div>
</div>
`
})
export default class DivContainer extends ContainerBase<sqlops.DivItemLayout> 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 = <HTMLElement> this.divContainer.nativeElement;
element.style.overflowY = this._overflowY;
}
}
private updateScroll() {
let element = <HTMLElement> 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<sqlops.DivContainerProperties, any>((props) => props.overflowY, '');
}
public set overflowY(newValue: string) {
this.setPropertyFromUI<sqlops.DivContainerProperties, any>((properties, newValue) => { properties.overflowY = newValue; }, newValue);
}
public get yOffsetChange(): number {
return this.getPropertyOrDefault<sqlops.DivContainerProperties, any>((props) => props.yOffsetChange, 0);
}
public set yOffsetChange(newValue: number) {
this.setPropertyFromUI<sqlops.DivContainerProperties, any>((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 : {};
}
}

View File

@@ -0,0 +1,5 @@
.divContainer {
display: block;
height: 100%;
}

View File

@@ -17,6 +17,7 @@ declare module 'sqlops' {
*/
export interface ModelBuilder {
navContainer(): ContainerBuilder<NavContainer, any, any>;
divContainer(): DivBuilder;
flexContainer(): FlexBuilder;
card(): ComponentBuilder<CardComponent>;
inputBox(): ComponentBuilder<InputBoxComponent>;
@@ -72,6 +73,10 @@ declare module 'sqlops' {
}
export interface DivBuilder extends ContainerBuilder<DivContainer, DivLayout, DivItemLayout> {
}
export interface GroupBuilder extends ContainerBuilder<GroupContainer, GroupLayout, GroupItemLayout> {
}
@@ -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<DivLayout, DivItemLayout>, DivContainerProperties {
}
export interface FlexContainer extends Container<FlexLayout, FlexItemLayout> {
}
@@ -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<ActionDescriptor>;
onCardSelectedChanged: vscode.Event<any>;

View File

@@ -131,6 +131,7 @@ export enum FrequencyRelativeIntervals {
export enum ModelComponentTypes {
NavContainer,
DivContainer,
FlexContainer,
Card,
InputBox,

View File

@@ -32,14 +32,21 @@ class ModelBuilderImpl implements sqlops.ModelBuilder {
navContainer(): sqlops.ContainerBuilder<sqlops.NavContainer, any, any> {
let id = this.getNextComponentId();
let container: ContainerBuilderImpl<sqlops.NavContainer, any, any> = new ContainerBuilderImpl(this._proxy, this._handle, ModelComponentTypes.NavContainer, id);
let container: GenericContainerBuilder<sqlops.NavContainer, any, any> = 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<sqlops.FlexContainer, any, any> = new ContainerBuilderImpl<sqlops.FlexContainer, sqlops.FlexLayout, sqlops.FlexItemLayout>(this._proxy, this._handle, ModelComponentTypes.FlexContainer, id);
let container: GenericContainerBuilder<sqlops.FlexContainer, any, any> = new GenericContainerBuilder<sqlops.FlexContainer, sqlops.FlexLayout, sqlops.FlexItemLayout>(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<sqlops.GroupContainer, any, any> = new ContainerBuilderImpl<sqlops.GroupContainer, sqlops.GroupLayout, sqlops.GroupItemLayout>(this._proxy, this._handle, ModelComponentTypes.Group, id);
let container: GenericContainerBuilder<sqlops.GroupContainer, any, any> = new GenericContainerBuilder<sqlops.GroupContainer, sqlops.GroupLayout, sqlops.GroupItemLayout>(this._proxy, this._handle, ModelComponentTypes.Group, id);
this._componentBuilders.set(id, container);
return container;
}
@@ -241,17 +248,9 @@ class ComponentBuilderImpl<T extends sqlops.Component> implements sqlops.Compone
}
}
class GenericComponentBuilder<T extends sqlops.Component> extends ComponentBuilderImpl<T> {
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) {
super(new ComponentWrapper(proxy, handle, type, id));
}
}
class ContainerBuilderImpl<T extends sqlops.Component, TLayout, TItemLayout> extends ComponentBuilderImpl<T> implements sqlops.ContainerBuilder<T, TLayout, TItemLayout> {
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<T, TLayout, TItemLayout> {
@@ -268,7 +267,19 @@ class ContainerBuilderImpl<T extends sqlops.Component, TLayout, TItemLayout> ext
}
}
class FormContainerBuilder extends ContainerBuilderImpl<sqlops.FormContainer, sqlops.FormLayout, sqlops.FormItemLayout> implements sqlops.FormBuilder {
class GenericContainerBuilder<T extends sqlops.Component, TLayout, TItemLayout> extends ContainerBuilderImpl<T, TLayout, TItemLayout> {
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) {
super(new ComponentWrapper(proxy, handle, type, id));
}
}
class DivContainerBuilder extends ContainerBuilderImpl<sqlops.DivContainer, sqlops.DivLayout, sqlops.DivItemLayout> {
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) {
super(new DivContainerWrapper(proxy, handle, type, id));
}
}
class FormContainerBuilder extends GenericContainerBuilder<sqlops.FormContainer, sqlops.FormLayout, sqlops.FormItemLayout> 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<sqlops.FormContainer, sq
}
}
class ToolbarContainerBuilder extends ContainerBuilderImpl<sqlops.ToolbarContainer, sqlops.ToolbarLayout, any> implements sqlops.ToolbarBuilder {
class ToolbarContainerBuilder extends GenericContainerBuilder<sqlops.ToolbarContainer, sqlops.ToolbarLayout, any> implements sqlops.ToolbarBuilder {
withToolbarItems(components: sqlops.ToolbarComponent[]): sqlops.ContainerBuilder<sqlops.ToolbarContainer, any, any> {
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<T> extends ComponentWrapper implements sqlops.TreeComponent<T> {
constructor(