Books/navigation (#6280)

* added previous and next buttons

* previous and next notebook API

* links for prev/next notebooks

* fixed first and last pages

* made code more readable

* addressed Kevin's comments

* moved logic over to BookTreeItem

* show buttons in dev mode only

* added BookTreeItemFormat interface

* added interface and enum

* removed localize call
This commit is contained in:
Lucy Zhang
2019-07-12 10:18:46 -07:00
committed by GitHub
parent 6606be998b
commit a706ff4d5b
13 changed files with 347 additions and 37 deletions

View File

@@ -13,6 +13,7 @@ import { Disposable } from 'vs/workbench/api/common/extHostTypes';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { IMainContext } from 'vs/workbench/api/common/extHost.protocol';
import { ok } from 'vs/base/common/assert';
import { localize } from 'vs/nls';
import {
SqlMainContext, INotebookDocumentsAndEditorsDelta, ExtHostNotebookDocumentsAndEditorsShape,
@@ -21,10 +22,13 @@ import {
import { ExtHostNotebookDocumentData } from 'sql/workbench/api/node/extHostNotebookDocumentData';
import { ExtHostNotebookEditor } from 'sql/workbench/api/node/extHostNotebookEditor';
type Adapter = azdata.nb.NavigationProvider;
export class ExtHostNotebookDocumentsAndEditors implements ExtHostNotebookDocumentsAndEditorsShape {
private static _handlePool: number = 0;
private _disposables: Disposable[] = [];
private _adapters = new Map<number, Adapter>();
private _activeEditorId: string;
private _proxy: MainThreadNotebookDocumentsAndEditorsShape;
@@ -152,6 +156,33 @@ export class ExtHostNotebookDocumentsAndEditors implements ExtHostNotebookDocume
}
}
private _nextHandle(): number {
return ExtHostNotebookDocumentsAndEditors._handlePool++;
}
private _addNewAdapter(adapter: Adapter): number {
const handle = this._nextHandle();
this._adapters.set(handle, adapter);
return handle;
}
private _getAdapter<T>(id: number): T {
let adapter = <T><any>this._adapters.get(id);
if (adapter === undefined) {
throw new Error('No adapter found');
}
return adapter;
}
$getNavigation(handle: number, notebookUri: UriComponents): Thenable<azdata.nb.NavigationResult> {
let navProvider = this._getAdapter<azdata.nb.NavigationProvider>(handle);
if (navProvider) {
let uri = URI.revive(notebookUri);
return navProvider.getNavigation(uri);
}
throw new Error('No navigation provider found for handle ${handle}');
}
//#endregion
//#region Extension accessible methods
@@ -212,5 +243,17 @@ export class ExtHostNotebookDocumentsAndEditors implements ExtHostNotebookDocume
this._editors.forEach(data => result.push(data));
return result;
}
registerNavigationProvider(provider: azdata.nb.NavigationProvider): vscode.Disposable {
if (!provider || !provider.providerId) {
throw new Error(localize('providerRequired', 'A NotebookProvider with valid providerId must be passed to this method'));
}
const handle = this._addNewAdapter(provider);
this._proxy.$registerNavigationProvider(provider.providerId, handle);
return new Disposable(() => {
this._adapters.delete(handle);
});
}
//#endregion
}

View File

@@ -327,7 +327,8 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
@IInstantiationService private _instantiationService: IInstantiationService,
@IEditorService private _editorService: IEditorService,
@IEditorGroupsService private _editorGroupService: IEditorGroupsService,
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService,
@INotebookService private readonly _notebookService: INotebookService
) {
super();
if (extHostContext) {
@@ -685,4 +686,22 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
this._modelToDisposeMap.set(editor.id, listeners);
});
}
$registerNavigationProvider(providerId: string, handle: number): void {
this._notebookService.registerNavigationProvider({
providerId: providerId,
onNext: async (uri) => {
let result = await this._proxy.$getNavigation(handle, uri);
if (result) {
this.doOpenEditor(result.next, {});
}
},
onPrevious: async (uri) => {
let result = await this._proxy.$getNavigation(handle, uri);
if (result) {
this.doOpenEditor(result.previous, {});
}
}
});
}
}

View File

@@ -501,6 +501,9 @@ export function createApiFactory(
registerNotebookProvider(provider: azdata.nb.NotebookProvider): vscode.Disposable {
return extHostNotebook.registerNotebookProvider(provider);
},
registerNavigationProvider(provider: azdata.nb.NavigationProvider): vscode.Disposable {
return extHostNotebookDocumentsAndEditors.registerNavigationProvider(provider);
},
CellRange: sqlExtHostTypes.CellRange,
NotebookChangeKind: sqlExtHostTypes.NotebookChangeKind
};

View File

@@ -913,6 +913,7 @@ export interface INotebookShowOptions {
export interface ExtHostNotebookDocumentsAndEditorsShape {
$acceptDocumentsAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta): void;
$acceptModelChanged(strURL: UriComponents, e: INotebookModelChangedData);
$getNavigation(handle: number, uri: vscode.Uri): Thenable<azdata.nb.NavigationResult>;
}
export interface MainThreadNotebookDocumentsAndEditorsShape extends IDisposable {
@@ -924,6 +925,7 @@ export interface MainThreadNotebookDocumentsAndEditorsShape extends IDisposable
$clearOutput(id: string, cellUri: UriComponents): Promise<boolean>;
$clearAllOutputs(id: string): Promise<boolean>;
$changeKernel(id: string, kernel: azdata.nb.IKernelInfo): Promise<boolean>;
$registerNavigationProvider(providerId: string, handle: number);
}
export interface ExtHostExtensionManagementShape {