mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-31 09:35:39 -05:00
Feature/input box component (#1190)
* Adding new view component for input box
This commit is contained in:
@@ -10,25 +10,29 @@ import { Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFacto
|
||||
|
||||
import * as types from 'vs/base/common/types';
|
||||
|
||||
import { IComponent, IComponentDescriptor, IModelStore } from 'sql/parts/modelComponents/interfaces';
|
||||
import { IComponent, IComponentDescriptor, IModelStore, IComponentEventArgs, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
|
||||
import { FlexLayout, FlexItemLayout } from 'sqlops';
|
||||
import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export class ItemDescriptor<T> {
|
||||
constructor(public descriptor: IComponentDescriptor, public config: T) {}
|
||||
}
|
||||
|
||||
export abstract class ComponentBase implements IComponent, OnDestroy, OnInit {
|
||||
export abstract class ComponentBase extends Disposable implements IComponent, OnDestroy, OnInit {
|
||||
protected properties: { [key: string]: any; } = {};
|
||||
constructor(
|
||||
constructor (
|
||||
protected _changeRef: ChangeDetectorRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
/// IComponent implementation
|
||||
|
||||
abstract descriptor: IComponentDescriptor;
|
||||
abstract modelStore: IModelStore;
|
||||
protected _onEventEmitter = new Emitter<IComponentEventArgs>();
|
||||
|
||||
public layout(): void {
|
||||
this._changeRef.detectChanges();
|
||||
@@ -48,7 +52,9 @@ export abstract class ComponentBase implements IComponent, OnDestroy, OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
abstract ngOnDestroy(): void;
|
||||
ngOnDestroy(): void {
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
abstract setLayout (layout: any): void;
|
||||
|
||||
@@ -68,6 +74,18 @@ export abstract class ComponentBase implements IComponent, OnDestroy, OnInit {
|
||||
let property = propertyGetter(this.getProperties<TPropertyBag>());
|
||||
return types.isUndefinedOrNull(property) ? defaultVal : property;
|
||||
}
|
||||
|
||||
protected setProperty<TPropertyBag, TValue>(propertySetter: (TPropertyBag, TValue) => void, value: TValue) {
|
||||
propertySetter(this.getProperties<TPropertyBag>(), value);
|
||||
this._onEventEmitter.fire({
|
||||
eventType: ComponentEventType.PropertiesChanged,
|
||||
args: this.getProperties()
|
||||
});
|
||||
}
|
||||
|
||||
public get onEvent(): Event<IComponentEventArgs> {
|
||||
return this._onEventEmitter.event;
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class ContainerBase<T> extends ComponentBase {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import FlexContainer from './flexContainer.component';
|
||||
import CardComponent from './card.component';
|
||||
import InputBoxComponent from './inputbox.component';
|
||||
import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry';
|
||||
import { ModelComponentTypes } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
|
||||
@@ -13,3 +14,6 @@ registerComponentType(FLEX_CONTAINER, ModelComponentTypes.FlexContainer, FlexCon
|
||||
|
||||
export const CARD_COMPONENT = 'card-component';
|
||||
registerComponentType(CARD_COMPONENT, ModelComponentTypes.Card, CardComponent);
|
||||
|
||||
export const INPUTBOX_COMPONENT = 'inputbox-component';
|
||||
registerComponentType(INPUTBOX_COMPONENT, ModelComponentTypes.InputBox, InputBoxComponent);
|
||||
|
||||
96
src/sql/parts/modelComponents/inputbox.component.ts
Normal file
96
src/sql/parts/modelComponents/inputbox.component.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { InputBox, IInputOptions } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { attachInputBoxStyler, attachListStyler } from 'vs/platform/theme/common/styler';
|
||||
|
||||
@Component({
|
||||
selector: 'inputBox',
|
||||
template: `
|
||||
<div #input style="width: 100%"></div>
|
||||
`
|
||||
})
|
||||
export default class InputBoxComponent extends ComponentBase implements IComponent, OnDestroy, AfterViewInit {
|
||||
@Input() descriptor: IComponentDescriptor;
|
||||
@Input() modelStore: IModelStore;
|
||||
private _input: InputBox;
|
||||
|
||||
@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: IInputOptions = {
|
||||
placeholder: '',
|
||||
ariaLabel: ''
|
||||
};
|
||||
|
||||
this._input = new InputBox(this._inputContainer.nativeElement, this._commonService.contextViewService, inputOptions);
|
||||
|
||||
this._register(this._input);
|
||||
this._register(attachInputBoxStyler(this._input, this._commonService.themeService));
|
||||
this._register(this._input.onDidChange(e => {
|
||||
this.value = this._input.value;
|
||||
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.value = this.value;
|
||||
}
|
||||
|
||||
// CSS-bound properties
|
||||
|
||||
public get value(): string {
|
||||
return this.getPropertyOrDefault<sqlops.InputBoxProperties, string>((props) => props.value, '');
|
||||
}
|
||||
|
||||
public set value(newValue: string) {
|
||||
this.setProperty<sqlops.InputBoxProperties, string>(this.setInputBoxProperties, newValue);
|
||||
}
|
||||
|
||||
private setInputBoxProperties(properties: sqlops.InputBoxProperties, value: string): void {
|
||||
properties.value = value;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
import { InjectionToken } from '@angular/core';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
|
||||
/**
|
||||
* An instance of a model-backed component. This will be a UI element
|
||||
@@ -20,6 +21,7 @@ export interface IComponent {
|
||||
addToContainer?: (componentDescriptor: IComponentDescriptor, config: any) => void;
|
||||
setLayout?: (layout: any) => void;
|
||||
setProperties?: (properties: { [key: string]: any; }) => void;
|
||||
onEvent?: Event<IComponentEventArgs>;
|
||||
}
|
||||
|
||||
export const COMPONENT_CONFIG = new InjectionToken<IComponentConfig>('component_config');
|
||||
@@ -48,6 +50,16 @@ export interface IComponentDescriptor {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface IComponentEventArgs {
|
||||
eventType: ComponentEventType;
|
||||
args: any;
|
||||
}
|
||||
|
||||
export enum ComponentEventType {
|
||||
PropertiesChanged,
|
||||
onDidChange
|
||||
}
|
||||
|
||||
export interface IModelStore {
|
||||
/**
|
||||
* Creates and saves the reference of a component descriptor.
|
||||
|
||||
@@ -16,6 +16,7 @@ import { IModelView } from 'sql/services/model/modelViewService';
|
||||
import { Extensions, IComponentRegistry } from 'sql/platform/dashboard/common/modelComponentRegistry';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { ModelStore } from 'sql/parts/modelComponents/modelStore';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
|
||||
const componentRegistry = <IComponentRegistry> Registry.as(Extensions.ComponentContribution);
|
||||
|
||||
@@ -35,6 +36,8 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
|
||||
abstract id: string;
|
||||
abstract connection: sqlops.connection.Connection;
|
||||
abstract serverInfo: sqlops.ServerInfo;
|
||||
private _onEventEmitter = new Emitter<any>();
|
||||
|
||||
|
||||
initializeModel(rootComponent: IComponentShape): void {
|
||||
let descriptor = this.defineComponent(rootComponent);
|
||||
@@ -52,11 +55,13 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
|
||||
let descriptor = this.modelStore.createComponentDescriptor(typeId, component.id);
|
||||
this.setProperties(component.id, component.properties);
|
||||
this.setLayout(component.id, component.layout);
|
||||
this.registerEvent(component.id);
|
||||
if (component.itemConfigs) {
|
||||
for(let item of component.itemConfigs) {
|
||||
this.addToContainer(component.id, item);
|
||||
}
|
||||
}
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@@ -91,4 +96,18 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
|
||||
// TODO add error handling
|
||||
});
|
||||
}
|
||||
|
||||
registerEvent(componentId: string) {
|
||||
this.queueAction(componentId, (component) => {
|
||||
if (component.onEvent) {
|
||||
this._register(component.onEvent(e => {
|
||||
this._onEventEmitter.fire(e);
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public get onEvent(): Event<any> {
|
||||
return this._onEventEmitter.event;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user