diff --git a/src/sql/parts/notebook/cellViews/code.component.html b/src/sql/parts/notebook/cellViews/code.component.html new file mode 100644 index 0000000000..421f9416e3 --- /dev/null +++ b/src/sql/parts/notebook/cellViews/code.component.html @@ -0,0 +1,13 @@ + +
+
+ Toolbar +
+
+
+
diff --git a/src/sql/parts/notebook/cellViews/code.component.ts b/src/sql/parts/notebook/cellViews/code.component.ts new file mode 100644 index 0000000000..3a8d34fc32 --- /dev/null +++ b/src/sql/parts/notebook/cellViews/code.component.ts @@ -0,0 +1,130 @@ +/*--------------------------------------------------------------------------------------------- +* 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!./code'; + +import { OnInit, Component, Input, 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 { ComponentBase } from 'sql/parts/modelComponents/componentBase'; +import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces'; +import { QueryTextEditor } from 'sql/parts/modelComponents/queryTextEditor'; + +import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import * as themeColors from 'vs/workbench/common/theme'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { SimpleProgressService } from 'vs/editor/standalone/browser/simpleServices'; +import { IProgressService } from 'vs/platform/progress/common/progress'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ITextModel } from 'vs/editor/common/model'; +import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput'; +import URI from 'vs/base/common/uri'; +import { Schemas } from 'vs/base/common/network'; +import * as DOM from 'vs/base/browser/dom'; +import { IModeService } from 'vs/editor/common/services/modeService'; +import { IModelService } from 'vs/editor/common/services/modelService'; + + +export const CODE_SELECTOR: string = 'code-component'; + +@Component({ + selector: CODE_SELECTOR, + templateUrl: decodeURI(require.toUrl('./code.component.html')) +}) +export class CodeComponent extends AngularDisposable implements OnInit { + @ViewChild('toolbar', { read: ElementRef }) private toolbarElement: ElementRef; + @ViewChild('editor', { read: ElementRef }) private codeElement: ElementRef; + @Input() id: string; + @Input() content: string; + @Input() language: string; + + private _editor: QueryTextEditor; + private _editorInput: UntitledEditorInput; + private _editorModel: ITextModel; + private _uri: string; + + constructor( + @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface, + @Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef, + @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService, + @Inject(IInstantiationService) private _instantiationService: IInstantiationService, + @Inject(IModelService) private _modelService: IModelService, + @Inject(IModeService) private _modeService: IModeService + ) { + super(); + } + + ngOnInit() { + this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this)); + this.updateTheme(this.themeService.getColorTheme()); + } + + ngOnChanges() { + this.updateLanguageMode(); + this.updateModel(); + } + + ngAfterContentInit(): void { + this.createEditor(); + this._register(DOM.addDisposableListener(window, DOM.EventType.RESIZE, e => { + this.layout(); + })); + } + + private createEditor(): void { + let instantiationService = this._instantiationService.createChild(new ServiceCollection([IProgressService, new SimpleProgressService()])); + this._editor = instantiationService.createInstance(QueryTextEditor); + this._editor.create(this.codeElement.nativeElement); + this._editor.setVisible(true); + let uri = this.createUri(); + this._editorInput = instantiationService.createInstance(UntitledEditorInput, uri, false, this.language, '', ''); + this._editor.setInput(this._editorInput, undefined); + this._editorInput.resolve().then(model => { + this._editorModel = model.textEditorModel; + this._modelService.updateModel(this._editorModel, this.content); + }); + + this._register(this._editor); + this._register(this._editorInput); + this._register(this._editorModel.onDidChangeContent(e => { + this.content = this._editorModel.getValue(); + this._editor.setHeightToScrollHeight(); + })); + this.layout(); + } + + public layout(): void { + this._editor.layout(new DOM.Dimension( + DOM.getContentWidth(this.codeElement.nativeElement), + DOM.getContentHeight(this.codeElement.nativeElement))); + } + + private createUri(): URI { + let uri = URI.from({ scheme: Schemas.untitled, path: `notebook-editor-${this.id}` }); + // Use this to set the internal (immutable) and public (shared with extension) uri properties + this._uri = uri.toString(); + return uri; + } + + /// Editor Functions + private updateModel() { + if (this._editorModel) { + this._modelService.updateModel(this._editorModel, this.content); + } + } + + private updateLanguageMode() { + if (this._editorModel && this._editor) { + this._modeService.getOrCreateMode(this.language).then((modeValue) => { + this._modelService.setMode(this._editorModel, modeValue); + }); + } + } + + private updateTheme(theme: IColorTheme): void { + let toolbarEl = this.toolbarElement.nativeElement; + toolbarEl.style.borderRightColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString(); + } +} diff --git a/src/sql/parts/notebook/cellViews/code.css b/src/sql/parts/notebook/cellViews/code.css new file mode 100644 index 0000000000..e8cadbfbd0 --- /dev/null +++ b/src/sql/parts/notebook/cellViews/code.css @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +code-component { + height: 100%; + width: 100%; + display: block; +} + +code-component .toolbar { + border-right-width: 1px; + border-right-style: solid; +} diff --git a/src/sql/parts/notebook/cellViews/codeCell.component.html b/src/sql/parts/notebook/cellViews/codeCell.component.html new file mode 100644 index 0000000000..b72bbd632d --- /dev/null +++ b/src/sql/parts/notebook/cellViews/codeCell.component.html @@ -0,0 +1,14 @@ + +
+
+ +
+
+ Place Holder for output area +
+
diff --git a/src/sql/parts/notebook/cellViews/codeCell.component.ts b/src/sql/parts/notebook/cellViews/codeCell.component.ts new file mode 100644 index 0000000000..23e7bd21eb --- /dev/null +++ b/src/sql/parts/notebook/cellViews/codeCell.component.ts @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- +* 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!./codeCell'; + +import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core'; + +import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; +import { CellView, ICellModel } from 'sql/parts/notebook/cellViews/interfaces'; + +import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import * as themeColors from 'vs/workbench/common/theme'; + + +export const CODE_SELECTOR: string = 'code-cell-component'; + +@Component({ + selector: CODE_SELECTOR, + templateUrl: decodeURI(require.toUrl('./codeCell.component.html')) +}) +export class CodeCellComponent extends CellView implements OnInit { + @Input() cellModel: ICellModel; + constructor( + @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface, + @Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef, + @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService + ) { + super(); + } + + ngOnInit() { + + } + + // Todo: implement layout + public layout() { + + } +} diff --git a/src/sql/parts/notebook/cellViews/codeCell.css b/src/sql/parts/notebook/cellViews/codeCell.css new file mode 100644 index 0000000000..6386355eda --- /dev/null +++ b/src/sql/parts/notebook/cellViews/codeCell.css @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +code-cell-component { + height: 100%; + width: 100%; + display: block; +} diff --git a/src/sql/parts/notebook/cellViews/interfaces.ts b/src/sql/parts/notebook/cellViews/interfaces.ts new file mode 100644 index 0000000000..78fbe50b14 --- /dev/null +++ b/src/sql/parts/notebook/cellViews/interfaces.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { OnDestroy } from '@angular/core'; +import { AngularDisposable } from 'sql/base/common/lifecycle'; + + +export abstract class CellView extends AngularDisposable implements OnDestroy { + constructor() { + super(); + } + + public abstract layout(): void; +} + +export interface ICellModel { + id: string; + language: string; + source: string; + cellType: CellType; +} + +export type CellType = 'code' | 'markdown' | 'raw'; + +export class CellTypes { + public static readonly Code = 'code'; + public static readonly Markdown = 'markdown'; + public static readonly Raw = 'raw'; +} diff --git a/src/sql/parts/notebook/notebook.component.html b/src/sql/parts/notebook/notebook.component.html index cb770cb285..659773a60e 100644 --- a/src/sql/parts/notebook/notebook.component.html +++ b/src/sql/parts/notebook/notebook.component.html @@ -5,12 +5,13 @@ *--------------------------------------------------------------------------------------------*/ -->
-
+
PlaceHolder for Toolbar
- Place Holder for cell list + +
diff --git a/src/sql/parts/notebook/notebook.component.ts b/src/sql/parts/notebook/notebook.component.ts index 484126f784..ed6c78e1f8 100644 --- a/src/sql/parts/notebook/notebook.component.ts +++ b/src/sql/parts/notebook/notebook.component.ts @@ -12,6 +12,7 @@ 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'; +import { ICellModel, CellTypes } from 'sql/parts/notebook/cellViews/interfaces'; export const NOTEBOOK_SELECTOR: string = 'notebook-component'; @@ -20,13 +21,23 @@ export const NOTEBOOK_SELECTOR: string = 'notebook-component'; templateUrl: decodeURI(require.toUrl('./notebook.component.html')) }) export class NotebookComponent extends AngularDisposable implements OnInit { - @ViewChild('header', { read: ElementRef }) private header: ElementRef; + @ViewChild('toolbar', { read: ElementRef }) private toolbar: ElementRef; + protected cells: Array = []; constructor( @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface, @Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef, @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService ) { super(); + + // Todo: This is mock data for cells. Will remove this code when we have a service + let cell1 : ICellModel = { + id: '1', language: 'sql', source: 'select * from sys.tables', cellType: CellTypes.Code + }; + let cell2 : ICellModel = { + id: '2', language: 'sql', source: 'select 1', cellType: CellTypes.Code + }; + this.cells.push(cell1, cell2); } ngOnInit() { @@ -35,9 +46,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit { } 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'; + let toolbarEl = this.toolbar.nativeElement; + toolbarEl.style.borderBottomColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString(); } } diff --git a/src/sql/parts/notebook/notebook.css b/src/sql/parts/notebook/notebook.css index b5cae2d434..402aa4e0b5 100644 --- a/src/sql/parts/notebook/notebook.css +++ b/src/sql/parts/notebook/notebook.css @@ -2,16 +2,7 @@ * 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 .editor-toolbar { + border-bottom-width: 1px; + border-bottom-style: solid; } - -.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 index 94ba37d12d..ce4237d300 100644 --- a/src/sql/parts/notebook/notebook.module.ts +++ b/src/sql/parts/notebook/notebook.module.ts @@ -23,6 +23,8 @@ import { NotebookComponent } from 'sql/parts/notebook/notebook.component'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Registry } from 'vs/platform/registry/common/platform'; +import { CodeComponent } from 'sql/parts/notebook/cellViews/code.component'; +import { CodeCellComponent } from 'sql/parts/notebook/cellViews/codeCell.component'; export const NotebookModule = (params, selector: string, instantiationService: IInstantiationService): any => { @NgModule({ @@ -31,6 +33,8 @@ export const NotebookModule = (params, selector: string, instantiationService: I SelectBox, EditableDropDown, InputBox, + CodeComponent, + CodeCellComponent, NotebookComponent, ComponentHostDirective ],