Notebook saves are broken #3432 (#3478)

* Notebook saves are broken #3432

* Misc change

* Save notebook uri to This

* Untitled notebook save including review comments #3432

* Cleanup

* Misc changes
This commit is contained in:
Raj
2018-12-07 16:27:23 -08:00
committed by Kevin Cunnane
parent 2d4fdcb661
commit 96fb618390
6 changed files with 90 additions and 6 deletions

View File

@@ -22,6 +22,7 @@ import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { NotebookConnection } from 'sql/parts/notebook/models/notebookConnection';
import { INotification, Severity } from 'vs/platform/notification/common/notification';
import { Schemas } from 'vs/base/common/network';
import URI from 'vs/base/common/uri';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
/*
@@ -97,6 +98,13 @@ export class NotebookModel extends Disposable implements INotebookModel {
return this.notebookOptions.notebookManager;
}
public get notebookUri() : URI {
return this.notebookOptions.notebookUri;
}
public set notebookUri(value : URI) {
this.notebookOptions.notebookUri = value;
}
public get hasServerManager(): boolean {
// If the service has a server manager, then we can show the start button
return !!this.notebookManager.serverManager;

View File

@@ -5,8 +5,6 @@
import './notebookStyles';
import { nb } from 'sqlops';
import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnDestroy } from '@angular/core';
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
@@ -20,7 +18,7 @@ import { AngularDisposable } from 'sql/base/common/lifecycle';
import { CellTypes, CellType } from 'sql/parts/notebook/models/contracts';
import { ICellModel, IModelFactory, notebookConstants } from 'sql/parts/notebook/models/modelInterfaces';
import { IConnectionManagementService, IConnectionDialogService } from 'sql/parts/connection/common/connectionManagement';
import { INotebookService, INotebookParams, INotebookManager, INotebookEditor } from 'sql/services/notebook/notebookService';
import { INotebookService, INotebookParams, INotebookManager, INotebookEditor, DEFAULT_NOTEBOOK_FILETYPE } from 'sql/services/notebook/notebookService';
import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
import { NotebookModel, NotebookContentChange } from 'sql/parts/notebook/models/notebookModel';
import { ModelFactory } from 'sql/parts/notebook/models/modelFactory';
@@ -40,6 +38,12 @@ import { fillInActions, LabeledMenuItemActionItem } from 'vs/platform/actions/br
import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { Schemas } from 'vs/base/common/network';
import URI from 'vs/base/common/uri';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import * as paths from 'vs/base/common/paths';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { TPromise } from 'vs/base/common/winjs.base';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
export const NOTEBOOK_SELECTOR: string = 'notebook-component';
@@ -81,7 +85,9 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
@Inject(IConnectionDialogService) private connectionDialogService: IConnectionDialogService,
@Inject(IContextKeyService) private contextKeyService: IContextKeyService,
@Inject(IMenuService) private menuService: IMenuService,
@Inject(IKeybindingService) private keybindingService: IKeybindingService
@Inject(IKeybindingService) private keybindingService: IKeybindingService,
@Inject(IHistoryService) private historyService: IHistoryService,
@Inject(IWindowService) private windowService: IWindowService,
) {
super();
this.updateProfile();
@@ -332,7 +338,54 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
}
}
// Gets file path from recent workspace in local
private getLastActiveFilePath(untitledResource: URI): string {
let fileName = untitledResource.path + '.' + DEFAULT_NOTEBOOK_FILETYPE.toLocaleLowerCase();
let lastActiveFile = this.historyService.getLastActiveFile();
if (lastActiveFile) {
return URI.file(paths.join(paths.dirname(lastActiveFile.fsPath), fileName)).fsPath;
}
let lastActiveFolder = this.historyService.getLastActiveWorkspaceRoot('file');
if (lastActiveFolder) {
return URI.file(paths.join(lastActiveFolder.fsPath, fileName)).fsPath;
}
return fileName;
}
promptForPath(defaultPath: string): TPromise<string> {
return this.windowService.showSaveDialog({ defaultPath });
}
// Entry point to save notebook
public async save(): Promise<boolean> {
let self = this;
let notebookUri = this.notebookParams.notebookUri;
if (notebookUri.scheme === Schemas.untitled) {
let dialogPath = this.getLastActiveFilePath(notebookUri);
return this.promptForPath(dialogPath).then(path => {
if (path) {
let target = URI.parse(path);
let resource = self._model.notebookUri;
self._model.notebookUri = target;
this.saveNotebook().then(result => {
if(result)
{
this.notebookService.renameNotebookEditor(resource, target, this);
}
return result;
});
}
return false; // User clicks cancel
});
}
else {
return await this.saveNotebook();
}
}
private async saveNotebook(): Promise<boolean> {
try {
let saved = await this._model.saveModel();
if (saved) {

View File

@@ -65,8 +65,6 @@ export class SaveNotebookAction extends Action {
let saved = await context.save();
if (saved) {
this._notificationService.notify({ severity: Severity.Info, message: SaveNotebookAction.notebookSavedMsg, actions });
} else {
this._notificationService.error(SaveNotebookAction.notebookFailedSaveMsg);
}
return saved;
}

View File

@@ -28,6 +28,7 @@ export interface INotebookService {
onNotebookEditorAdd: Event<INotebookEditor>;
onNotebookEditorRemove: Event<INotebookEditor>;
onNotebookEditorRename: Event<INotebookEditor>;
/**
* Register a metadata provider
@@ -57,6 +58,8 @@ export interface INotebookService {
shutdown(): void;
getMimeRegistry(): RenderMimeRegistry;
renameNotebookEditor(oldUri: URI, newUri: URI, currentEditor: INotebookEditor): void;
}
export interface INotebookProvider {

View File

@@ -29,6 +29,7 @@ export class NotebookService implements INotebookService {
private _managers: Map<string, INotebookManager> = new Map();
private _onNotebookEditorAdd = new Emitter<INotebookEditor>();
private _onNotebookEditorRemove = new Emitter<INotebookEditor>();
private _onNotebookEditorRename = new Emitter<INotebookEditor>();
private _editors = new Map<string, INotebookEditor>();
constructor() {
@@ -84,6 +85,10 @@ export class NotebookService implements INotebookService {
return this._onNotebookEditorRemove.event;
}
get onNotebookEditorRename(): Event<INotebookEditor> {
return this._onNotebookEditorRename.event;
}
addNotebookEditor(editor: INotebookEditor): void {
this._editors.set(editor.id, editor);
this._onNotebookEditorAdd.fire(editor);
@@ -103,6 +108,17 @@ export class NotebookService implements INotebookService {
return editors;
}
renameNotebookEditor(oldUri: URI, newUri: URI, currentEditor: INotebookEditor): void {
let oldUriKey = oldUri.toString();
if(this._editors.has(oldUriKey))
{
this._editors.delete(oldUriKey);
currentEditor.notebookParams.notebookUri = newUri;
this._editors.set(newUri.toString(), currentEditor);
this._onNotebookEditorRename.fire(currentEditor);
}
}
private sendNotebookCloseToProvider(editor: INotebookEditor) {
let notebookUri = editor.notebookParams.notebookUri;
let uriString = notebookUri.toString();

View File

@@ -206,6 +206,7 @@ class MainThreadNotebookDocumentAndEditorStateComputer extends Disposable {
this._register(this._editorService.onDidVisibleEditorsChange(this._updateState, this));
this._register(this._notebookService.onNotebookEditorAdd(this._onDidAddEditor, this));
this._register(this._notebookService.onNotebookEditorRemove(this._onDidRemoveEditor, this));
this._register(this._notebookService.onNotebookEditorRename(this._onDidRenameEditor, this));
this._updateState();
}
@@ -220,6 +221,11 @@ class MainThreadNotebookDocumentAndEditorStateComputer extends Disposable {
this._updateState();
}
private _onDidRenameEditor(e: INotebookEditor): void {
this._updateState();
//TODO: Close editor and open it
}
private _updateState(): void {
// editor
const editors = new Map<string, INotebookEditor>();