Adding back save api (#4407)

* #4339: Kernel change event occurs after model load

* #4347: Code cleanup - Notebooks Save

* Remove save method from sqlops

* Adding save method to api's

* Adding save method to ext host

* Misc change
This commit is contained in:
Raj
2019-03-12 13:07:10 -07:00
committed by GitHub
parent 2db83b3892
commit 6a7df2f1ae
10 changed files with 5 additions and 161 deletions

View File

@@ -18,12 +18,6 @@ import { IAction, Action, IActionItem } from 'vs/base/common/actions';
import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { fillInActions, LabeledMenuItemActionItem } from 'vs/platform/actions/browser/menuItemActionItem';
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 { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { VIEWLET_ID, IExtensionsViewlet } from 'vs/workbench/parts/extensions/common/extensions';
@@ -32,7 +26,7 @@ import { AngularDisposable } from 'sql/base/node/lifecycle';
import { CellTypes, CellType } from 'sql/parts/notebook/models/contracts';
import { ICellModel, IModelFactory, INotebookModel, NotebookContentChange, notebookConstants } from 'sql/parts/notebook/models/modelInterfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { INotebookService, INotebookParams, INotebookManager, INotebookEditor, DEFAULT_NOTEBOOK_FILETYPE, DEFAULT_NOTEBOOK_PROVIDER, SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/common/notebookService';
import { INotebookService, INotebookParams, INotebookManager, INotebookEditor, DEFAULT_NOTEBOOK_PROVIDER, SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/common/notebookService';
import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
import { NotebookModel } from 'sql/parts/notebook/models/notebookModel';
import { ModelFactory } from 'sql/parts/notebook/models/modelFactory';
@@ -40,11 +34,10 @@ import * as notebookUtils from 'sql/parts/notebook/notebookUtils';
import { Deferred } from 'sql/base/common/promise';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
import { KernelsDropdown, AttachToDropdown, AddCellAction, TrustedAction, SaveNotebookAction } from 'sql/parts/notebook/notebookActions';
import { KernelsDropdown, AttachToDropdown, AddCellAction, TrustedAction } from 'sql/parts/notebook/notebookActions';
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
import { IResourceInput } from 'vs/platform/editor/common/editor';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
import { IConnectionDialogService } from 'sql/workbench/services/connection/common/connectionDialogService';
@@ -90,11 +83,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
@Inject(IContextKeyService) private contextKeyService: IContextKeyService,
@Inject(IMenuService) private menuService: IMenuService,
@Inject(IKeybindingService) private keybindingService: IKeybindingService,
@Inject(IHistoryService) private historyService: IHistoryService,
@Inject(IWindowService) private windowService: IWindowService,
@Inject(IViewletService) private viewletService: IViewletService,
@Inject(IUntitledEditorService) private untitledEditorService: IUntitledEditorService,
@Inject(IEditorGroupsService) private editorGroupService: IEditorGroupsService,
@Inject(ICapabilitiesService) private capabilitiesService: ICapabilitiesService
) {
super();
@@ -316,6 +305,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
}
return this._notebookParams.modelFactory;
}
private handleModelError(notification: INotification): void {
this.notificationService.notify(notification);
}
@@ -367,8 +357,6 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
this._trustedAction = this.instantiationService.createInstance(TrustedAction, 'notebook.Trusted');
this._trustedAction.enabled = false;
let saveNotebookButton = this.instantiationService.createInstance(SaveNotebookAction, 'notebook.SaveNotebook', localize('save', 'Save'), 'notebook-button icon-save');
let taskbar = <HTMLElement>this.toolbar.nativeElement;
this._actionBar = new Taskbar(taskbar, this.contextMenuService, { actionItemProvider: action => this.actionItemProvider(action as Action) });
this._actionBar.context = this;
@@ -377,101 +365,11 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
{ element: attachToContainer },
{ action: addCodeCellButton },
{ action: addTextCellButton },
{ action: saveNotebookButton },
{ action: this._trustedAction }
]);
}
// 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(Schemas.file);
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: defaultPath,
filters: [{ name: localize('notebookFile', 'Notebook'), extensions: ['ipynb'] }]
});
}
// 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.file(path);
let resource = self._model.notebookUri;
self._model.notebookUri = target;
this.saveNotebook().then(result => {
if (result) {
return this.replaceUntitledNotebookEditor(resource, target);
}
return result;
});
}
return false; // User clicks cancel
});
}
else {
return await this.saveNotebook();
}
}
// Replaces untitled notebook editor with the saved file name
private async replaceUntitledNotebookEditor(resource: URI, target: URI): Promise<boolean> {
let encodingOfSource = this.untitledEditorService.getEncoding(resource);
const replacement: IResourceInput = {
resource: target,
encoding: encodingOfSource,
options: {
pinned: true
}
};
return TPromise.join(this.editorGroupService.groups.map(g =>
this.editorService.replaceEditors([{
editor: { resource },
replacement
}], g))).then(() => {
this.notebookService.renameNotebookEditor(resource, target, this);
return true;
});
}
private async saveNotebook(): Promise<boolean> {
try {
let saved = await this._model.saveModel();
if (saved) {
this.setDirty(false);
}
return saved;
} catch (err) {
this.notificationService.error(localize('saveFailed', 'Failed to save notebook: {0}', notebookUtils.getErrorMessage(err)));
return false;
}
}
private setDirty(isDirty: boolean): void {
if (this._notebookParams.input) {
this._notebookParams.input.setDirty(isDirty);
}
}
private actionItemProvider(action: Action): IActionItem {
// Check extensions to create ActionItem; otherwise, return undefined
// This is similar behavior that exists in MenuItemActionItem