mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Add code cell (#2909)
* initial work for addig code and code cell type * add cell model and create editor for each cell * formatting * fix resizing issue * small changes * address comment
This commit is contained in:
13
src/sql/parts/notebook/cellViews/code.component.html
Normal file
13
src/sql/parts/notebook/cellViews/code.component.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!--
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
-->
|
||||||
|
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: row">
|
||||||
|
<div #toolbar class="toolbar" style="flex: 0 0 auto;">
|
||||||
|
Toolbar
|
||||||
|
</div>
|
||||||
|
<div #editor class="editor" style="flex: 1 1 auto; overflow: hidden;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
130
src/sql/parts/notebook/cellViews/code.component.ts
Normal file
130
src/sql/parts/notebook/cellViews/code.component.ts
Normal file
@@ -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 = <HTMLElement>this.toolbarElement.nativeElement;
|
||||||
|
toolbarEl.style.borderRightColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/sql/parts/notebook/cellViews/code.css
Normal file
15
src/sql/parts/notebook/cellViews/code.css
Normal file
@@ -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;
|
||||||
|
}
|
||||||
14
src/sql/parts/notebook/cellViews/codeCell.component.html
Normal file
14
src/sql/parts/notebook/cellViews/codeCell.component.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!--
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
-->
|
||||||
|
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||||
|
<div class="notebook-code" style="flex: 0 0 auto;">
|
||||||
|
<code-component [id]="cellModel.id" [content]="cellModel.source" [language]="cellModel.language"></code-component>
|
||||||
|
</div>
|
||||||
|
<div class="notebook-output" style="flex: 0 0 auto;">
|
||||||
|
Place Holder for output area
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
40
src/sql/parts/notebook/cellViews/codeCell.component.ts
Normal file
40
src/sql/parts/notebook/cellViews/codeCell.component.ts
Normal file
@@ -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() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/sql/parts/notebook/cellViews/codeCell.css
Normal file
10
src/sql/parts/notebook/cellViews/codeCell.css
Normal file
@@ -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;
|
||||||
|
}
|
||||||
31
src/sql/parts/notebook/cellViews/interfaces.ts
Normal file
31
src/sql/parts/notebook/cellViews/interfaces.ts
Normal file
@@ -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';
|
||||||
|
}
|
||||||
@@ -5,12 +5,13 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
-->
|
-->
|
||||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||||
<div #header class="header" style="flex: 0 0 auto; display: flex; flex-flow: row; width: 100%; align-items: center">
|
<div #toolbar class="editor-toolbar" style="flex: 0 0 auto; display: flex; flex-flow: row; width: 100%; align-items: center">
|
||||||
<div style="flex: 1 1 auto">
|
<div style="flex: 1 1 auto">
|
||||||
PlaceHolder for Toolbar
|
PlaceHolder for Toolbar
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="flex: 1 1 auto; position: relative">
|
<div style="flex: 1 1 auto; position: relative">
|
||||||
Place Holder for cell list
|
<code-cell-component *ngFor="let cell of cells" [cellModel]="cell">
|
||||||
|
</code-cell-component>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { AngularDisposable } from 'sql/base/common/lifecycle';
|
|||||||
|
|
||||||
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||||
import * as themeColors from 'vs/workbench/common/theme';
|
import * as themeColors from 'vs/workbench/common/theme';
|
||||||
|
import { ICellModel, CellTypes } from 'sql/parts/notebook/cellViews/interfaces';
|
||||||
|
|
||||||
export const NOTEBOOK_SELECTOR: string = 'notebook-component';
|
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'))
|
templateUrl: decodeURI(require.toUrl('./notebook.component.html'))
|
||||||
})
|
})
|
||||||
export class NotebookComponent extends AngularDisposable implements OnInit {
|
export class NotebookComponent extends AngularDisposable implements OnInit {
|
||||||
@ViewChild('header', { read: ElementRef }) private header: ElementRef;
|
@ViewChild('toolbar', { read: ElementRef }) private toolbar: ElementRef;
|
||||||
|
protected cells: Array<ICellModel> = [];
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
|
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
|
||||||
) {
|
) {
|
||||||
super();
|
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() {
|
ngOnInit() {
|
||||||
@@ -35,9 +46,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateTheme(theme: IColorTheme): void {
|
private updateTheme(theme: IColorTheme): void {
|
||||||
let headerEl = <HTMLElement>this.header.nativeElement;
|
let toolbarEl = <HTMLElement>this.toolbar.nativeElement;
|
||||||
headerEl.style.borderBottomColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();
|
toolbarEl.style.borderBottomColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();
|
||||||
headerEl.style.borderBottomWidth = '1px';
|
|
||||||
headerEl.style.borderBottomStyle = 'solid';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,7 @@
|
|||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
/*
|
.notebookEditor .editor-toolbar {
|
||||||
.notebookEditor .header .monaco-action-bar .action-label {
|
border-bottom-width: 1px;
|
||||||
padding: 8px;
|
border-bottom-style: solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notebookEditor .header .monaco-action-bar .action-item {
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notebookEditor .monaco-action-bar {
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -23,6 +23,8 @@ import { NotebookComponent } from 'sql/parts/notebook/notebook.component';
|
|||||||
|
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
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 => {
|
export const NotebookModule = (params, selector: string, instantiationService: IInstantiationService): any => {
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -31,6 +33,8 @@ export const NotebookModule = (params, selector: string, instantiationService: I
|
|||||||
SelectBox,
|
SelectBox,
|
||||||
EditableDropDown,
|
EditableDropDown,
|
||||||
InputBox,
|
InputBox,
|
||||||
|
CodeComponent,
|
||||||
|
CodeCellComponent,
|
||||||
NotebookComponent,
|
NotebookComponent,
|
||||||
ComponentHostDirective
|
ComponentHostDirective
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user