Add localContentManger and dummy sessionManager (#3130)

* - keyboard binding to arrow keys
- toggle markdown editor by double click

* Added localContentManger and dummpy sessionManager
This commit is contained in:
Yurong He
2018-11-05 17:55:13 -08:00
committed by GitHub
parent 3c785ae7d8
commit 5da89ac05b
7 changed files with 152 additions and 6 deletions

View File

@@ -6,8 +6,8 @@
-->
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
<div class="notebook-text" style="flex: 0 0 auto;">
<code-component [cellModel]="cellModel" (onContentChanged)="handleContentChanged()"></code-component>
<code-component *ngIf="isEditMode" [cellModel]="cellModel" (onContentChanged)="handleContentChanged()"></code-component>
</div>
<div #preview class="notebook-preview" style="flex: 0 0 auto;">
<div #preview class="notebook-preview" style="flex: 0 0 auto;" (dblclick)="toggleEditMode()">
</div>
</div>

View File

@@ -24,6 +24,7 @@ export class TextCellComponent extends CellView implements OnInit {
@ViewChild('preview', { read: ElementRef }) private output: ElementRef;
@Input() cellModel: ICellModel;
private _content: string;
private isEditMode: boolean;
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
@@ -31,6 +32,7 @@ export class TextCellComponent extends CellView implements OnInit {
@Inject(ICommandService) private _commandService: ICommandService
) {
super();
this.isEditMode = true;
}
ngOnChanges() {
@@ -41,7 +43,7 @@ export class TextCellComponent extends CellView implements OnInit {
if (this._content !== this.cellModel.source) {
this._content = this.cellModel.source;
// todo: pass in the notebook filename instead of undefined value
this._commandService.executeCommand('notebook.showPreview', undefined, this._content).then((htmlcontent) => {
this._commandService.executeCommand<string>('notebook.showPreview', undefined, this._content).then((htmlcontent) => {
let outputElement = <HTMLElement>this.output.nativeElement;
outputElement.innerHTML = htmlcontent;
});
@@ -65,4 +67,9 @@ export class TextCellComponent extends CellView implements OnInit {
public handleContentChanged(): void {
this.updatePreview();
}
public toggleEditMode(): void {
this.isEditMode = !this.isEditMode;
this._changeRef.detectChanges();
}
}

View File

@@ -11,7 +11,7 @@
</div>
</div>
<div style="flex: 1 1 auto; position: relative">
<div class="notebook-cell" *ngFor="let cell of cells" (click)="selectCell(cell)" [class.active]="cell.active" >
<div class="notebook-cell" *ngFor="let cell of cells" (click)="selectCell(cell)" [class.active]="cell.active" (keydown)="onKeyDown($event)">
<code-cell-component *ngIf="cell.cellType === 'code'" [cellModel]="cell">
</code-cell-component>
<text-cell-component *ngIf="cell.cellType === 'markdown'" [cellModel]="cell">

View File

@@ -89,4 +89,28 @@ export class NotebookComponent extends AngularDisposable implements OnInit {
this._changeRef.detectChanges();
}
}
public onKeyDown(event) {
switch (event.key) {
case 'ArrowDown':
case 'ArrowRight':
let nextIndex = (this.findCellIndex(this._activeCell) + 1)%this.cells.length;
this.selectCell(this.cells[nextIndex]);
break;
case 'ArrowUp':
case 'ArrowLeft':
let index = this.findCellIndex(this._activeCell);
if (index === 0) {
index = this.cells.length;
}
this.selectCell(this.cells[--index]);
break;
default:
break;
}
}
findCellIndex(cellModel: ICellModel): number {
return this.cells.findIndex((cell) => cell.id === cellModel.id);
}
}

View File

@@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------------------------
* 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 { nb } from 'sqlops';
import * as json from 'vs/base/common/json';
import * as pfs from 'vs/base/node/pfs';
import ContentManager = nb.ContentManager;
import INotebook = nb.INotebook;
export class LocalContentManager implements ContentManager {
public async getNotebookContents(path: string): Promise<INotebook> {
if (!path) {
return undefined;
}
// Note: intentionally letting caller handle exceptions
let notebookFileBuffer = await pfs.readFile(path);
return <INotebook>json.parse(notebookFileBuffer.toString());
}
public async save(path: string, notebook: INotebook): Promise<INotebook> {
// Convert to JSON with pretty-print functionality
let contents = JSON.stringify(notebook, undefined, ' ');
await pfs.writeFile(path, contents);
return notebook;
}
}

View File

@@ -7,8 +7,11 @@
import { nb } from 'sqlops';
import * as nls from 'vs/nls';
import { INotebookService, INotebookManager, INotebookProvider } from 'sql/services/notebook/notebookService';
import { INotebookService, INotebookManager, INotebookProvider, DEFAULT_NOTEBOOK_PROVIDER } from 'sql/services/notebook/notebookService';
import URI from 'vs/base/common/uri';
import { LocalContentManager } from 'sql/services/notebook/localContentManager';
import { session } from 'electron';
import { SessionManager } from 'sql/services/notebook/sessionManager';
export class NotebookService implements INotebookService {
_serviceBrand: any;
@@ -16,6 +19,11 @@ export class NotebookService implements INotebookService {
private _providers: Map<string, INotebookProvider> = new Map();
private _managers: Map<URI, INotebookManager> = new Map();
constructor() {
let defaultProvider = new BuiltinProvider();
this.registerProvider(defaultProvider.providerId, defaultProvider);
}
registerProvider(providerId: string, provider: INotebookProvider): void {
this._providers.set(providerId, provider);
}
@@ -57,4 +65,48 @@ export class NotebookService implements INotebookService {
return op(provider);
}
}
}
export class BuiltinProvider implements INotebookProvider {
private manager: BuiltInNotebookManager;
constructor() {
this.manager = new BuiltInNotebookManager();
}
public get providerId(): string {
return DEFAULT_NOTEBOOK_PROVIDER;
}
getNotebookManager(notebookUri: URI): Thenable<INotebookManager> {
return Promise.resolve(this.manager);
}
handleNotebookClosed(notebookUri: URI): void {
// No-op
}
}
export class BuiltInNotebookManager implements INotebookManager {
private _contentManager: nb.ContentManager;
private _sessionManager: nb.SessionManager;
constructor() {
this._contentManager = new LocalContentManager();
this._sessionManager = new SessionManager();
}
public get providerId(): string {
return DEFAULT_NOTEBOOK_PROVIDER;
}
public get contentManager(): nb.ContentManager {
return this._contentManager;
}
public get serverManager(): nb.ServerManager {
return undefined;
}
public get sessionManager(): nb.SessionManager {
return this._sessionManager;
}
}

View File

@@ -0,0 +1,31 @@
'use strict';
import { nb } from 'sqlops';
import { Session } from 'electron';
export class SessionManager implements nb.SessionManager {
private _sessionManager: nb.SessionManager;
constructor() {
}
public get isReady(): boolean {
return this._sessionManager.isReady;
}
public get ready(): Thenable<void> {
return this._sessionManager.ready;
}
public get specs(): nb.IAllKernels {
return this._sessionManager.specs;
}
startNew(options: nb.ISessionOptions): Thenable<nb.ISession> {
return this._sessionManager.startNew(options);
}
shutdown(id: string): Thenable<void> {
return this.shutdown(id);
}
}