diff --git a/samples/sqlservices/src/controllers/mainController.ts b/samples/sqlservices/src/controllers/mainController.ts
index c7c17a135e..9990cc9c3c 100644
--- a/samples/sqlservices/src/controllers/mainController.ts
+++ b/samples/sqlservices/src/controllers/mainController.ts
@@ -259,18 +259,52 @@ export default class MainController implements vscode.Disposable {
let editor = sqlops.workspace.createModelViewEditor('Editor webview2', { retainContextWhenHidden: true });
editor.registerContent(async view => {
+ let inputBox = view.modelBuilder.inputBox().component();
+ let dropdown = view.modelBuilder.dropDown()
+ .withProperties({
+ value: 'aa',
+ values: ['aa', 'bb', 'cc']
+ })
+ .component();
+ let button = view.modelBuilder.button()
+ .withProperties({
+ label: 'Run'
+ }).component();
+ let toolbarModel = view.modelBuilder.toolbarContainer()
+ .withToolbarItems([{
+ component: inputBox,
+ title: 'User name:'
+ }, {
+ component: dropdown,
+ title: 'favorite:'
+ }, {
+ component: button
+ }]).component();
+
+
let webview = view.modelBuilder.webView()
.component();
+
let flexModel = view.modelBuilder.flexContainer()
.withLayout({
flexFlow: 'column',
alignItems: 'stretch',
height: '100%'
}).withItems([
- webview
- ], { flex: '1 1 50%' })
+ toolbarModel, webview
+ ], { flex: '1' })
.component();
+ // bug: #1531
+ // let flexModel = view.modelBuilder.flexContainer().component();
+ // flexModel.addItem(toolbarModel, { flex: '0' });
+ // flexModel.addItem(webview, { flex: '1' });
+ // flexModel.setLayout({
+ // flexFlow: 'column',
+ // alignItems: 'stretch',
+ // height: '100%'
+ // });
+
let templateValues = {url: 'http://whoisactive.com/docs/'};
Utils.renderTemplateHtml(path.join(__dirname, '..'), 'templateTab.html', templateValues)
.then(html => {
diff --git a/src/sql/parts/modelComponents/components.contribution.ts b/src/sql/parts/modelComponents/components.contribution.ts
index 249dd1c3d2..79da46f03d 100644
--- a/src/sql/parts/modelComponents/components.contribution.ts
+++ b/src/sql/parts/modelComponents/components.contribution.ts
@@ -5,6 +5,7 @@
import FlexContainer from './flexContainer.component';
import FormContainer from './formContainer.component';
+import ToolbarContainer from './toolbarContainer.component';
import GroupContainer from './groupContainer.component';
import CardComponent from './card.component';
import InputBoxComponent from './inputbox.component';
@@ -23,6 +24,9 @@ registerComponentType(FLEX_CONTAINER, ModelComponentTypes.FlexContainer, FlexCon
export const FORM_CONTAINER = 'form-container';
registerComponentType(FORM_CONTAINER, ModelComponentTypes.Form, FormContainer);
+export const TOOLBAR_CONTAINER = 'toolbar-container';
+registerComponentType(TOOLBAR_CONTAINER, ModelComponentTypes.Toolbar, ToolbarContainer);
+
export const GROUP_CONTAINER = 'group-container';
registerComponentType(GROUP_CONTAINER, ModelComponentTypes.Group, GroupContainer);
diff --git a/src/sql/parts/modelComponents/toolbarContainer.component.ts b/src/sql/parts/modelComponents/toolbarContainer.component.ts
new file mode 100644
index 0000000000..792e3bdafa
--- /dev/null
+++ b/src/sql/parts/modelComponents/toolbarContainer.component.ts
@@ -0,0 +1,91 @@
+/*---------------------------------------------------------------------------------------------
+ * 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!./toolbarLayout';
+
+import {
+ Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
+ ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList, AfterViewInit
+} from '@angular/core';
+
+import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
+
+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 { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
+
+export interface ToolbarItemConfig {
+ title?: string;
+}
+
+class ToolbarItem {
+ constructor(public descriptor: IComponentDescriptor, public config: ToolbarItemConfig) { }
+}
+
+@Component({
+ selector: 'modelview-toolbarContainer',
+ template: `
+
+ `
+})
+export default class ToolbarContainer extends ContainerBase implements IComponent, OnDestroy, AfterViewInit {
+ @Input() descriptor: IComponentDescriptor;
+ @Input() modelStore: IModelStore;
+
+ @ViewChildren(ModelComponentWrapper) private _componentWrappers: QueryList;
+ @ViewChild('container', { read: ElementRef }) private _container: ElementRef;
+
+ constructor(
+ @Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
+ @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
+ super(changeRef);
+ }
+
+ ngOnInit(): void {
+ this.baseInit();
+ }
+
+ ngOnDestroy(): void {
+ this.baseDestroy();
+ }
+
+ ngAfterViewInit(): void {
+ }
+
+ /// IComponent implementation
+
+ public layout(): void {
+ if (this._componentWrappers) {
+ this._componentWrappers.forEach(wrapper => {
+ wrapper.layout();
+ });
+ }
+ }
+
+ public setLayout(layout: any): void {
+ this.layout();
+ }
+
+ private getItemTitle(item: ToolbarItem): string {
+ let itemConfig = item.config;
+ return itemConfig ? itemConfig.title : '';
+ }
+
+ private hasTitle(item: ToolbarItem): boolean {
+ return item && item.config && item.config.title !== undefined;
+ }
+}
diff --git a/src/sql/parts/modelComponents/toolbarLayout.css b/src/sql/parts/modelComponents/toolbarLayout.css
new file mode 100644
index 0000000000..ad6819e858
--- /dev/null
+++ b/src/sql/parts/modelComponents/toolbarLayout.css
@@ -0,0 +1,45 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+.modelview-toolbar-container {
+ display: flex;
+ padding: 15px;
+ justify-content: flex-start;
+ line-height: 1.4em;
+ white-space: nowrap;
+ flex-wrap: wrap;
+ border-bottom-width: .5px;
+ border-bottom-style: solid;
+ box-sizing: border-box;
+ border-bottom-color: rgba(128, 128, 128, 0.35);
+}
+
+.modelview-toolbar-container .modelview-toolbar-item {
+ flex: 0 0;
+ flex-direction: row;
+ display: flex;
+ padding-left: 10px;
+}
+
+.modelview-toolbar-container .modelview-toolbar-title {
+ padding-right: 5px;
+ font-size: 14px;
+ cursor: pointer;
+ margin: auto;
+}
+
+.modelview-toolbar-container .modelview-toolbar-component .select-box,
+.modelview-toolbar-container .modelview-toolbar-component .monaco-inputbox {
+ width: 200px;
+ height: 25px;
+}
+
+.modelview-toolbar-container .modelview-toolbar-component button {
+ height: 25px;
+}
+
+.modelview-toolbar-container .modelview-toolbar-component button .monaco-text-button {
+ padding: 0px
+}
\ No newline at end of file
diff --git a/src/sql/sqlops.proposed.d.ts b/src/sql/sqlops.proposed.d.ts
index 689f584165..196cc163e2 100644
--- a/src/sql/sqlops.proposed.d.ts
+++ b/src/sql/sqlops.proposed.d.ts
@@ -30,6 +30,7 @@ declare module 'sqlops' {
dashboardWebview(webviewId: string): ComponentBuilder;
formContainer(): FormBuilder;
groupContainer(): GroupBuilder;
+ toolbarContainer(): ToolbarBuilder;
}
export interface ComponentBuilder {
@@ -49,6 +50,24 @@ declare module 'sqlops' {
export interface GroupBuilder extends ContainerBuilder {
}
+ export interface ToolbarBuilder extends ContainerBuilder {
+ withToolbarItems(components: ToolbarComponent[]): ContainerBuilder;
+
+ /**
+ * Creates a collection of child components and adds them all to this container
+ *
+ * @param toolbarComponents the definitions
+ */
+ addToolbarItems(toolbarComponents: Array): void;
+
+ /**
+ * Creates a child component and adds it to this container.
+ *
+ * @param toolbarComponent the component to be added
+ */
+ addToolbarItem(toolbarComponent: ToolbarComponent): void;
+ }
+
export interface FormBuilder extends ContainerBuilder {
withFormItems(components: FormComponent[], itemLayout?: FormItemLayout): ContainerBuilder;
@@ -104,6 +123,11 @@ declare module 'sqlops' {
actions?: Component[];
}
+ export interface ToolbarComponent {
+ component: Component;
+ title?: string;
+ }
+
/**
* A component that contains other components
*/
@@ -212,6 +236,9 @@ declare module 'sqlops' {
export interface GroupContainer extends Container {
}
+ export interface ToolbarContainer extends Container {
+ }
+
/**
* Describes an action to be shown in the UI, with a user-readable label
* and a callback to execute the action
diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts
index ca6fa2aa60..ba7239d209 100644
--- a/src/sql/workbench/api/common/sqlExtHostTypes.ts
+++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts
@@ -77,7 +77,8 @@ export enum ModelComponentTypes {
DashboardWidget,
DashboardWebview,
Form,
- Group
+ Group,
+ Toolbar
}
export interface IComponentShape {
diff --git a/src/sql/workbench/api/node/extHostModelView.ts b/src/sql/workbench/api/node/extHostModelView.ts
index 84013d9b96..3d3a804a07 100644
--- a/src/sql/workbench/api/node/extHostModelView.ts
+++ b/src/sql/workbench/api/node/extHostModelView.ts
@@ -45,6 +45,13 @@ class ModelBuilderImpl implements sqlops.ModelBuilder {
return container;
}
+ toolbarContainer(): sqlops.ToolbarBuilder {
+ let id = this.getNextComponentId();
+ let container = new ToolbarContainerBuilder(this._proxy, this._handle, ModelComponentTypes.Toolbar, id);
+ this._componentBuilders.set(id, container);
+ return container;
+ }
+
groupContainer(): sqlops.GroupBuilder {
let id = this.getNextComponentId();
let container: ContainerBuilderImpl = new ContainerBuilderImpl(this._proxy, this._handle, ModelComponentTypes.Group, id);
@@ -256,6 +263,34 @@ class FormContainerBuilder extends ContainerBuilderImpl implements sqlops.ToolbarBuilder {
+ withToolbarItems(components: sqlops.ToolbarComponent[]): sqlops.ContainerBuilder {
+ this._component.itemConfigs = components.map(item => {
+ return this.convertToItemConfig(item);
+ });
+ return this;
+ }
+
+ private convertToItemConfig(toolbarComponent: sqlops.ToolbarComponent): InternalItemConfig {
+ let componentWrapper = toolbarComponent.component as ComponentWrapper;
+
+ return new InternalItemConfig(componentWrapper, {
+ title: toolbarComponent.title
+ });
+ }
+
+ addToolbarItems(toolbarComponent: Array): void {
+ toolbarComponent.forEach(toolbarComponent => {
+ this.addToolbarItem(toolbarComponent);
+ });
+ }
+
+ addToolbarItem(toolbarComponent: sqlops.ToolbarComponent): void {
+ let itemImpl = this.convertToItemConfig(toolbarComponent);
+ this._component.addItem(toolbarComponent.component as ComponentWrapper, itemImpl.config);
+ }
+}
+
class InternalItemConfig {
constructor(private _component: ComponentWrapper, public config: any) { }