Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions src/document/factory.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { IThemeManager } from '@jupyterlab/apputils';
import { ABCWidgetFactory, DocumentRegistry } from '@jupyterlab/docregistry';
import { INotebookModel } from '@jupyterlab/notebook';
import { ReactWidget } from '@jupyterlab/ui-components';
import { Panel } from '@lumino/widgets';
import * as React from 'react';

import { SpectaWidgetFactory } from '../specta_widget_factory';
import { ISpectaLayoutRegistry, ISpectaShell } from '../token';
import {
ISpectaLayoutRegistry,
ISpectaShell,
ISpectaTopbarWidget
} from '../token';
import { isSpectaApp, readSpectaConfig } from '../tool';
import { TopbarElement } from '../topbar/widget';
import { MenuComponent } from '../topbar/menuComponent';
import { TitleComponent } from '../topbar/titleComponent';
import { TopbarWidget } from '../topbar/topbarWidget';
import { NotebookSpectaDocWidget } from './widget';

interface IOptions extends DocumentRegistry.IWidgetFactoryOptions {
Expand All @@ -17,6 +22,7 @@ interface IOptions extends DocumentRegistry.IWidgetFactoryOptions {
themeManager?: IThemeManager;
shell: ISpectaShell;
spectaLayoutRegistry: ISpectaLayoutRegistry;
spectaTopbar: ISpectaTopbarWidget;
}

export class NotebookGridWidgetFactory extends ABCWidgetFactory<
Expand All @@ -28,7 +34,7 @@ export class NotebookGridWidgetFactory extends ABCWidgetFactory<
this._spectaWidgetFactory = options.spectaWidgetFactory;
this._shell = options.shell;
this._themeManager = options.themeManager;
this._layoutRegistry = options.spectaLayoutRegistry;
this._spectaTopbar = options.spectaTopbar;
}

protected createNewWidget(
Expand All @@ -45,21 +51,26 @@ export class NotebookGridWidgetFactory extends ABCWidgetFactory<
});
const isSpecta = isSpectaApp();
if (!spectaConfig.hideTopbar) {
const topbar = ReactWidget.create(
<TopbarElement
const title = <TitleComponent config={spectaConfig.topBar} />;
const menu = (
<MenuComponent
config={spectaConfig.topBar}
themeManager={this._themeManager}
layoutRegistry={this._layoutRegistry}
/>
);
topbar.addClass('specta-topbar-element');
if (!isSpecta) {
// Not a specta app, add topbar to document widget
const topbar = new TopbarWidget({
config: spectaConfig.topBar
});
topbar.addReactWidget(title, 'left', 0);
topbar.addReactWidget(menu, 'right', 10000);
content.addWidget(topbar);
} else {
// Specta app, add topbar to layout
topbar.id = 'specta-topbar-widget';
this._shell.add(topbar, 'top', { rank: 100 });
if (this._spectaTopbar.addReactWidget) {
this._spectaTopbar.addReactWidget(title, 'left', 0);
this._spectaTopbar.addReactWidget(menu, 'right', 10000);
}
}
} else if (isSpecta) {
this._shell.hideTopBar();
Expand All @@ -85,5 +96,5 @@ export class NotebookGridWidgetFactory extends ABCWidgetFactory<
private _spectaWidgetFactory: SpectaWidgetFactory;
private _shell: ISpectaShell;
private _themeManager?: IThemeManager;
private _layoutRegistry: ISpectaLayoutRegistry;
private _spectaTopbar: ISpectaTopbarWidget;
}
19 changes: 14 additions & 5 deletions src/document/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
ISpectaDocTracker,
ISpectaLayoutRegistry,
ISpectaShell,
ISpectaTopbarWidget,
ISpectaTopbarWidgetToken,
ISpectaUrlFactory,
ISpectaUrlFactoryToken
} from '../token';
Expand All @@ -40,7 +42,9 @@ const activate = (
editorServices: IEditorServices,
contentFactory: NotebookPanel.IContentFactory,
spectaLayoutRegistry: ISpectaLayoutRegistry,
themeManager: IThemeManager
themeManager: IThemeManager,
spectaTopbar: ISpectaTopbarWidget,
kernelSpecManager: KernelSpec.IManager
): IWidgetTracker => {
const namespace = 'specta';
const spectaTracker = new WidgetTracker<Widget>({ namespace });
Expand All @@ -54,7 +58,9 @@ const activate = (
contentFactory,
spectaTracker,
spectaLayoutRegistry,
themeManager
themeManager,
spectaTopbar,
kernelSpecManager
});

return spectaTracker;
Expand All @@ -72,7 +78,9 @@ export const spectaDocument: JupyterFrontEndPlugin<
IEditorServices,
NotebookPanel.IContentFactory,
ISpectaLayoutRegistry,
IThemeManager
IThemeManager,
ISpectaTopbarWidgetToken,
IKernelSpecManager
],
activate,
provides: ISpectaDocTracker
Expand All @@ -82,7 +90,7 @@ export const spectaUrlFactory: JupyterFrontEndPlugin<ISpectaUrlFactory> = {
id: 'specta/application-extension:urlFactory',
autoStart: true,
provides: ISpectaUrlFactoryToken,
activate() {
activate: () => {
const urlFactory = (path: string) => {
const baseUrl = PageConfig.getBaseUrl();
let appUrl = PageConfig.getOption('appUrl');
Expand Down Expand Up @@ -158,7 +166,8 @@ export const spectaOpener: JupyterFrontEndPlugin<void, ILabShell> = {
hideAppLoadingIndicator();
} else {
app.restored.then(async () => {
await new Promise(r => setTimeout(r, 200));
await new Promise(r => setTimeout(r, 100));
await kernelSpecManager.ready;
if (PathExt.extname(path) === '.ipynb') {
app.shell.addClass('specta-document-viewer');
const widget = docManager.openOrReveal(path, 'specta');
Expand Down
22 changes: 20 additions & 2 deletions src/specta_model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import {
} from '@jupyterlab/notebook';
import { OutputAreaModel, SimplifiedOutputArea } from '@jupyterlab/outputarea';
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
import { ServiceManager } from '@jupyterlab/services';
import { KernelSpec, ServiceManager } from '@jupyterlab/services';
import { IExecuteReplyMsg } from '@jupyterlab/services/lib/kernel/messages';
import { PartialJSONValue } from '@lumino/coreutils';
import { PartialJSONValue, PromiseDelegate } from '@lumino/coreutils';

import {
createNotebookContext,
Expand All @@ -50,6 +50,14 @@ export class AppModel {
options.context.fileChanged.connect(e => {
this._fileChanged.emit(e.model.cells);
});
this._kernelSpecManager = options.kernelSpecManager;
const specs = this._kernelSpecManager.specs;
this._kernelSpecManager.specsChanged.connect((_, b) => {
this._kernelReady.resolve();
});
if (specs && Object.keys(specs.kernelspecs).length !== 0) {
this._kernelReady.resolve();
}
}
/**
* Whether the handler is disposed.
Expand Down Expand Up @@ -195,6 +203,12 @@ export class AppModel {
if (cell.type !== 'code' || !this._context) {
return;
}
const specs = this._kernelSpecManager.specs;
if (specs && Object.keys(specs.kernelspecs).length !== 0) {
this._kernelReady.resolve();
} else {
await this._kernelReady.promise;
}
const output = outputWrapper.cellOutput as SimplifiedOutputArea;
const source = cell.sharedModel.source;
const rep = await SimplifiedOutputArea.execute(
Expand All @@ -209,6 +223,8 @@ export class AppModel {
return rep;
}

private _kernelReady = new PromiseDelegate<void>();

private _notebookPanel?: NotebookPanel;
private _context?: DocumentRegistry.IContext<INotebookModel>;
private _notebookModelJson: PartialJSONValue;
Expand All @@ -217,6 +233,7 @@ export class AppModel {
private _kernelPreference: ISessionContext.IKernelPreference;
private _fileChanged = new Signal<this, CellList>(this);
private _filePath: string;
private _kernelSpecManager: KernelSpec.IManager;
}

export namespace AppModel {
Expand All @@ -230,6 +247,7 @@ export namespace AppModel {
editorConfig: StaticNotebook.IEditorConfig;
notebookConfig: StaticNotebook.INotebookConfig;
editorServices: IEditorServices;
kernelSpecManager: KernelSpec.IManager;
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/specta_widget_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import {
INotebookModel
} from '@jupyterlab/notebook';
import { DocumentRegistry } from '@jupyterlab/docregistry';

import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
import { ServiceManager } from '@jupyterlab/services';
import { ServiceManager, KernelSpec } from '@jupyterlab/services';
import { AppModel } from './specta_model';
import { AppWidget } from './specta_widget';
import { UUID } from '@lumino/coreutils';
Expand Down Expand Up @@ -47,7 +46,8 @@ export class SpectaWidgetFactory {
mimeTypeService: this._options.mimeTypeService,
editorConfig: StaticNotebook.defaultEditorConfig,
notebookConfig: StaticNotebook.defaultNotebookConfig,
editorServices: this._options.editorServices
editorServices: this._options.editorServices,
kernelSpecManager: this._options.kernelSpecManager
});

// Create the specta pane
Expand All @@ -73,5 +73,6 @@ export namespace SpectaWidgetFactory {
mimeTypeService: IEditorMimeTypeService;
editorServices: IEditorServices;
spectaLayoutRegistry: ISpectaLayoutRegistry;
kernelSpecManager: KernelSpec.IManager;
}
}
17 changes: 17 additions & 0 deletions src/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface ITopbarConfig {
settingsButton?: boolean;
themeToggle?: boolean;
layoutToggle?: boolean;
link?: string;
}

export interface ISpectaAppConfig {
Expand Down Expand Up @@ -76,3 +77,19 @@ export const ISpectaDocTracker = new Token<IWidgetTracker<Widget>>(
export const ISpectaUrlFactoryToken = new Token<ISpectaUrlFactory>(
'specta:ISpectaUrlFactoryToken'
);

export interface ISpectaTopbarWidget {
addTopbarWidget?: (
widget: Widget,
side: 'left' | 'right',
rank: number
) => void;
addReactWidget?: (
widget: JSX.Element,
side: 'left' | 'right',
rank: number
) => void;
}
export const ISpectaTopbarWidgetToken = new Token<ISpectaTopbarWidget>(
'specta:ISpectaTopbarWidget'
);
15 changes: 11 additions & 4 deletions src/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { IDefaultFileBrowser } from '@jupyterlab/filebrowser';
import { ICell, INotebookMetadata } from '@jupyterlab/nbformat';
import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
import { Contents } from '@jupyterlab/services';
import { Contents, KernelSpec } from '@jupyterlab/services';
import { CommandRegistry } from '@lumino/commands';

import { NotebookGridWidgetFactory } from './document/factory';
Expand All @@ -16,6 +16,7 @@ import {
ISpectaCellConfig,
ISpectaLayoutRegistry,
ISpectaShell,
ISpectaTopbarWidget,
ISpectaUrlFactory
} from './token';

Expand All @@ -29,6 +30,8 @@ export function registerDocumentFactory(options: {
spectaTracker: WidgetTracker;
spectaLayoutRegistry: ISpectaLayoutRegistry;
themeManager?: IThemeManager;
spectaTopbar: ISpectaTopbarWidget;
kernelSpecManager: KernelSpec.IManager;
}) {
const {
factoryName,
Expand All @@ -39,7 +42,9 @@ export function registerDocumentFactory(options: {
contentFactory,
spectaTracker,
spectaLayoutRegistry,
themeManager
themeManager,
spectaTopbar,
kernelSpecManager
} = options;

const spectaWidgetFactory = new SpectaWidgetFactory({
Expand All @@ -49,7 +54,8 @@ export function registerDocumentFactory(options: {
contentFactory,
mimeTypeService: editorServices.mimeTypeService,
editorServices,
spectaLayoutRegistry
spectaLayoutRegistry,
kernelSpecManager
});
const widgetFactory = new NotebookGridWidgetFactory({
name: factoryName,
Expand All @@ -58,7 +64,8 @@ export function registerDocumentFactory(options: {
shell: app.shell,
spectaWidgetFactory,
themeManager,
spectaLayoutRegistry
spectaLayoutRegistry,
spectaTopbar
});

// Registering the widget factory
Expand Down
Loading