diff --git a/src/sql/parts/notebook/notebook.component.html b/src/sql/parts/notebook/notebook.component.html
new file mode 100644
index 0000000000..cb770cb285
--- /dev/null
+++ b/src/sql/parts/notebook/notebook.component.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Place Holder for cell list
+
+
diff --git a/src/sql/parts/notebook/notebook.component.ts b/src/sql/parts/notebook/notebook.component.ts
new file mode 100644
index 0000000000..484126f784
--- /dev/null
+++ b/src/sql/parts/notebook/notebook.component.ts
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------------------------------
+* 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!./notebook';
+
+import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core';
+
+import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
+import { AngularDisposable } from 'sql/base/common/lifecycle';
+
+import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
+import * as themeColors from 'vs/workbench/common/theme';
+
+export const NOTEBOOK_SELECTOR: string = 'notebook-component';
+
+@Component({
+ selector: NOTEBOOK_SELECTOR,
+ templateUrl: decodeURI(require.toUrl('./notebook.component.html'))
+})
+export class NotebookComponent extends AngularDisposable implements OnInit {
+ @ViewChild('header', { read: ElementRef }) private header: ElementRef;
+ constructor(
+ @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
+ @Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
+ @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
+ ) {
+ super();
+ }
+
+ ngOnInit() {
+ this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
+ this.updateTheme(this.themeService.getColorTheme());
+ }
+
+ private updateTheme(theme: IColorTheme): void {
+ let headerEl = this.header.nativeElement;
+ headerEl.style.borderBottomColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();
+ headerEl.style.borderBottomWidth = '1px';
+ headerEl.style.borderBottomStyle = 'solid';
+ }
+}
diff --git a/src/sql/parts/notebook/notebook.contribution.ts b/src/sql/parts/notebook/notebook.contribution.ts
new file mode 100644
index 0000000000..69546dd9f3
--- /dev/null
+++ b/src/sql/parts/notebook/notebook.contribution.ts
@@ -0,0 +1,64 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+import { Registry } from 'vs/platform/registry/common/platform';
+import { EditorDescriptor, IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
+import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
+import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
+import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
+import { Action } from 'vs/base/common/actions';
+import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
+import { TPromise } from 'vs/base/common/winjs.base';
+import * as nls from 'vs/nls';
+
+import { NotebookInput, NotebookInputModel } from 'sql/parts/notebook/notebookInput';
+import { NotebookEditor } from 'sql/parts/notebook/notebookEditor';
+
+/**
+ * todo: Will remove this code.
+ * This is the entry point to open the new Notebook
+ */
+export class OpenNotebookAction extends Action {
+
+ public static ID = 'OpenNotebookAction';
+ public static LABEL = nls.localize('OpenNotebookAction', 'Open Notebook editor');
+
+ constructor(
+ id: string,
+ label: string,
+ @IEditorService private _editorService: IEditorService
+ ) {
+ super(id, label);
+ }
+
+ public run(): TPromise {
+ return new TPromise((resolve, reject) => {
+ let model = new NotebookInputModel('modelViewId', undefined, undefined);
+ let input = new NotebookInput('modelViewId', model);
+ this._editorService.openEditor(input, { pinned: true });
+ });
+ }
+}
+
+// Model View editor registration
+const viewModelEditorDescriptor = new EditorDescriptor(
+ NotebookEditor,
+ NotebookEditor.ID,
+ 'Notebook'
+);
+
+Registry.as(EditorExtensions.Editors)
+ .registerEditor(viewModelEditorDescriptor, [new SyncDescriptor(NotebookInput)]);
+
+// todo: Will remove this code.
+// this is the entry point to open the new Notebook
+let actionRegistry = Registry.as(Extensions.WorkbenchActions);
+actionRegistry.registerWorkbenchAction(
+ new SyncActionDescriptor(
+ OpenNotebookAction,
+ OpenNotebookAction.ID,
+ OpenNotebookAction.LABEL
+ ),
+ OpenNotebookAction.LABEL
+);
\ No newline at end of file
diff --git a/src/sql/parts/notebook/notebook.css b/src/sql/parts/notebook/notebook.css
new file mode 100644
index 0000000000..b5cae2d434
--- /dev/null
+++ b/src/sql/parts/notebook/notebook.css
@@ -0,0 +1,17 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+/*
+.notebookEditor .header .monaco-action-bar .action-label {
+ padding: 8px;
+}
+
+.notebookEditor .header .monaco-action-bar .action-item {
+ margin-right: 5px;
+}
+
+.notebookEditor .monaco-action-bar {
+ overflow: visible;
+}
+*/
\ No newline at end of file
diff --git a/src/sql/parts/notebook/notebook.module.ts b/src/sql/parts/notebook/notebook.module.ts
new file mode 100644
index 0000000000..94ba37d12d
--- /dev/null
+++ b/src/sql/parts/notebook/notebook.module.ts
@@ -0,0 +1,67 @@
+/*---------------------------------------------------------------------------------------------
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the Source EULA. See License.txt in the project root for license information.
+*--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import { forwardRef, NgModule, ComponentFactoryResolver, Inject, ApplicationRef } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { CommonModule, APP_BASE_HREF } from '@angular/common';
+import { BrowserModule } from '@angular/platform-browser';
+
+
+import { Extensions, IComponentRegistry } from 'sql/platform/dashboard/common/modelComponentRegistry';
+import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
+import { IBootstrapParams, ISelector, providerIterator } from 'sql/services/bootstrap/bootstrapService';
+import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
+import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component';
+import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component';
+import { EditableDropDown } from 'sql/base/browser/ui/editableDropdown/editableDropdown.component';
+import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox.component';
+import { NotebookComponent } from 'sql/parts/notebook/notebook.component';
+
+import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
+import { Registry } from 'vs/platform/registry/common/platform';
+
+export const NotebookModule = (params, selector: string, instantiationService: IInstantiationService): any => {
+ @NgModule({
+ declarations: [
+ Checkbox,
+ SelectBox,
+ EditableDropDown,
+ InputBox,
+ NotebookComponent,
+ ComponentHostDirective
+ ],
+ entryComponents: [NotebookComponent],
+ imports: [
+ FormsModule,
+ CommonModule,
+ BrowserModule
+ ],
+ providers: [
+ { provide: APP_BASE_HREF, useValue: '/' },
+ CommonServiceInterface,
+ { provide: IBootstrapParams, useValue: params },
+ { provide: ISelector, useValue: selector },
+ ...providerIterator(instantiationService)
+ ]
+ })
+ class ModuleClass {
+
+ constructor(
+ @Inject(forwardRef(() => ComponentFactoryResolver)) private _resolver: ComponentFactoryResolver,
+ @Inject(ISelector) private selector: string
+ ) {
+ }
+
+ ngDoBootstrap(appRef: ApplicationRef) {
+ const factoryWrapper: any = this._resolver.resolveComponentFactory(NotebookComponent);
+ factoryWrapper.factory.selector = this.selector;
+ appRef.bootstrap(factoryWrapper);
+ }
+ }
+
+ return ModuleClass;
+};
diff --git a/src/sql/parts/notebook/notebookEditor.ts b/src/sql/parts/notebook/notebookEditor.ts
new file mode 100644
index 0000000000..eb89f73fcf
--- /dev/null
+++ b/src/sql/parts/notebook/notebookEditor.ts
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+import { TPromise } from 'vs/base/common/winjs.base';
+import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
+import { IThemeService } from 'vs/platform/theme/common/themeService';
+import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
+import { EditorOptions } from 'vs/workbench/common/editor';
+import * as DOM from 'vs/base/browser/dom';
+import { $ } from 'vs/base/browser/builder';
+import { bootstrapAngular } from 'sql/services/bootstrap/bootstrapService';
+import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
+
+import { CancellationToken } from 'vs/base/common/cancellation';
+import { NotebookInput } from 'sql/parts/notebook/notebookInput';
+import { NotebookModule } from 'sql/parts/notebook/notebook.module';
+import { NOTEBOOK_SELECTOR } from 'sql/parts/notebook/notebook.component';
+
+export class NotebookEditor extends BaseEditor {
+
+ public static ID: string = 'workbench.editor.notebookEditor';
+ private _notebookContainer: HTMLElement;
+ protected _input: NotebookInput;
+
+ constructor(
+ @ITelemetryService telemetryService: ITelemetryService,
+ @IThemeService themeService: IThemeService,
+ @IInstantiationService private instantiationService: IInstantiationService,
+ ) {
+ super(NotebookEditor.ID, telemetryService, themeService);
+ }
+
+ public get input(): NotebookInput {
+ return this._input;
+ }
+
+ /**
+ * Called to create the editor in the parent element.
+ */
+ public createEditor(parent: HTMLElement): void {
+ }
+
+ /**
+ * Sets focus on this editor. Specifically, it sets the focus on the hosted text editor.
+ */
+ public focus(): void {
+ }
+
+ /**
+ * Updates the internal variable keeping track of the editor's size, and re-calculates the sash position.
+ * To be called when the container of this editor changes size.
+ */
+ public layout(dimension: DOM.Dimension): void {
+ }
+
+ public setInput(input: NotebookInput, options: EditorOptions): TPromise {
+ if (this.input && this.input.matches(input)) {
+ return TPromise.as(undefined);
+ }
+
+ const parentElement = this.getContainer();
+
+ super.setInput(input, options, CancellationToken.None);
+
+ $(parentElement).clearChildren();
+
+ if (!input.hasBootstrapped) {
+ let container = DOM.$('.notebookEditor');
+ container.style.height = '100%';
+ this._notebookContainer = DOM.append(parentElement, container);
+ this.input.container = this._notebookContainer;
+ return TPromise.wrap(this.bootstrapAngular(input));
+ } else {
+ this._notebookContainer = DOM.append(parentElement, this.input.container);
+ return TPromise.wrap(null);
+ }
+ }
+
+ /**
+ * Load the angular components and record for this input that we have done so
+ */
+ private bootstrapAngular(input: NotebookInput): void {
+ // Get the bootstrap params and perform the bootstrap
+ input.hasBootstrapped = true;
+ bootstrapAngular(this.instantiationService,
+ NotebookModule,
+ this._notebookContainer,
+ NOTEBOOK_SELECTOR,
+ undefined,
+ undefined
+ );
+ }
+}
+
diff --git a/src/sql/parts/notebook/notebookInput.ts b/src/sql/parts/notebook/notebookInput.ts
new file mode 100644
index 0000000000..a2d6b4dc87
--- /dev/null
+++ b/src/sql/parts/notebook/notebookInput.ts
@@ -0,0 +1,124 @@
+import { TPromise } from 'vs/base/common/winjs.base';
+import { IEditorModel } from 'vs/platform/editor/common/editor';
+import { EditorInput, EditorModel, ConfirmResult } from 'vs/workbench/common/editor';
+
+import { Emitter, Event } from 'vs/base/common/event';
+
+export type ModeViewSaveHandler = (handle: number) => Thenable;
+
+export class NotebookInputModel extends EditorModel {
+ private dirty: boolean;
+ private readonly _onDidChangeDirty: Emitter = this._register(new Emitter());
+ get onDidChangeDirty(): Event { return this._onDidChangeDirty.event; }
+
+ constructor(public readonly modelViewId, private readonly handle: number, private saveHandler?: ModeViewSaveHandler) {
+ super();
+ this.dirty = false;
+ }
+
+ get isDirty(): boolean {
+ return this.dirty;
+ }
+
+ public setDirty(dirty: boolean): void {
+ if (this.dirty === dirty) {
+ return;
+ }
+
+ this.dirty = dirty;
+ this._onDidChangeDirty.fire();
+ }
+
+ save(): TPromise {
+ if (this.saveHandler) {
+ return TPromise.wrap(this.saveHandler(this.handle));
+ }
+ return TPromise.wrap(true);
+ }
+}
+export class NotebookInput extends EditorInput {
+
+ public static ID: string = 'workbench.editorinputs.notebookInput';
+
+ public hasBootstrapped = false;
+ // Holds the HTML content for the editor when the editor discards this input and loads another
+ private _parentContainer: HTMLElement;
+
+ constructor(private _title: string, private _model: NotebookInputModel,
+ ) {
+ super();
+ this._model.onDidChangeDirty(() => this._onDidChangeDirty.fire());
+
+ }
+
+ public get title(): string {
+ return this._title;
+ }
+
+ public get modelViewId(): string {
+ return this._model.modelViewId;
+ }
+
+ public getTypeId(): string {
+ return NotebookInput.ID;
+ }
+
+ public resolve(refresh?: boolean): TPromise {
+ return undefined;
+ }
+
+ public getName(): string {
+ return this._title;
+ }
+
+ public dispose(): void {
+ this._disposeContainer();
+ super.dispose();
+ }
+
+ private _disposeContainer() {
+ if (!this._parentContainer) {
+ return;
+ }
+
+ let parentNode = this._parentContainer.parentNode;
+ if (parentNode) {
+ parentNode.removeChild(this._parentContainer);
+ this._parentContainer = null;
+ }
+ }
+
+ set container(container: HTMLElement) {
+ this._disposeContainer();
+ this._parentContainer = container;
+ }
+
+ get container(): HTMLElement {
+ return this._parentContainer;
+ }
+
+ /**
+ * An editor that is dirty will be asked to be saved once it closes.
+ */
+ isDirty(): boolean {
+ return this._model.isDirty;
+ }
+
+ /**
+ * Subclasses should bring up a proper dialog for the user if the editor is dirty and return the result.
+ */
+ confirmSave(): TPromise {
+ // TODO #2530 support save on close / confirm save. This is significantly more work
+ // as we need to either integrate with textFileService (seems like this isn't viable)
+ // or register our own complimentary service that handles the lifecycle operations such
+ // as close all, auto save etc.
+ return TPromise.wrap(ConfirmResult.DONT_SAVE);
+ }
+
+ /**
+ * Saves the editor if it is dirty. Subclasses return a promise with a boolean indicating the success of the operation.
+ */
+ save(): TPromise {
+ return this._model.save();
+ }
+}
\ No newline at end of file
diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts
index 2faf5ef1a5..8e4307b613 100644
--- a/src/vs/workbench/workbench.main.ts
+++ b/src/vs/workbench/workbench.main.ts
@@ -189,6 +189,8 @@ import 'sql/parts/dashboard/dashboardConfig.contribution';
import 'sql/parts/modelComponents/components.contribution';
/* View Model Editor */
import 'sql/parts/modelComponents/modelEditor/modelViewEditor.contribution';
+/* Notebook Editor */
+import 'sql/parts/notebook/notebook.contribution';
/* Containers */
import 'sql/parts/dashboard/containers/dashboardWebviewContainer.contribution';
import 'sql/parts/dashboard/containers/dashboardControlHostContainer.contribution';