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
1 change: 1 addition & 0 deletions src/layout/article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class ArticleLayout implements ISpectaLayout {
}
}
}

host.addWidget(hostPanel);
await readyCallback();
}
Expand Down
9 changes: 9 additions & 0 deletions src/specta_model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
} from './create_notebook_panel';
import { SpectaCellOutput } from './specta_cell_output';
import { emitResizeEvent, readCellConfig } from './tool';
import { ISignal, Signal } from '@lumino/signaling';

export class AppModel {
constructor(private options: AppModel.IOptions) {
Expand All @@ -45,6 +46,9 @@ export class AppModel {
language: options.context.model.defaultKernelLanguage
};
this._manager = options.manager;
options.context.fileChanged.connect(e => {
this._fileChanged.emit(e.model.cells);
});
}
/**
* Whether the handler is disposed.
Expand All @@ -53,6 +57,10 @@ export class AppModel {
return this._isDisposed;
}

get fileChanged(): ISignal<this, CellList> {
return this._fileChanged;
}

dispose(): void {
if (this.isDisposed) {
return;
Expand Down Expand Up @@ -202,6 +210,7 @@ export class AppModel {
private _isDisposed = false;
private _manager: ServiceManager.IManager;
private _kernelPreference: ISessionContext.IKernelPreference;
private _fileChanged = new Signal<this, CellList>(this);
}

export namespace AppModel {
Expand Down
81 changes: 65 additions & 16 deletions src/specta_widget.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CellList } from '@jupyterlab/notebook';
import { PromiseDelegate } from '@lumino/coreutils';
import { Message } from '@lumino/messaging';
import { Panel, Widget } from '@lumino/widgets';
Expand Down Expand Up @@ -40,12 +41,16 @@ export class AppWidget extends Panel {
await new Promise(resolve =>
setTimeout(resolve, parseInt(waitTime + ''))
);
this.render().catch(console.error).then(emitResizeEvent);
await this.render();
emitResizeEvent();
});
this._layoutRegistry.selectedLayoutChanged.connect(
this._onSelectedLayoutChanged,
this
);
this._model.fileChanged.connect((_, newCells) => {
this.rerender(newCells);
});
}

/**
Expand All @@ -72,6 +77,17 @@ export class AppWidget extends Panel {
this.addWidget(loaderHost);
}

removeSpinner(): void {
if (this._loaderHost) {
this._loaderHost.node.style.opacity = '0';
setTimeout(() => {
this.layout?.removeWidget(this._loaderHost!);
}, 100);
} else {
hideAppLoadingIndicator();
}
}

dispose(): void {
if (this.isDisposed) {
return;
Expand All @@ -80,33 +96,39 @@ export class AppWidget extends Panel {
super.dispose();
}

async render(): Promise<void> {
const cellList = this._model.cells ?? [];

const layout = this._spectaAppConfig?.defaultLayout ?? 'default';
async generateOutputs(cellList?: CellList): Promise<SpectaCellOutput[]> {
const outs: SpectaCellOutput[] = [];
if (!cellList) {
return outs;
}
for (const cell of cellList) {
const src = cell.sharedModel.source;

if (src.length === 0) {
continue;
}
const el = this._model.createCell(cell);
this._model.executeCell(cell, el);

this._outputs.push(el);
outs.push(el);
}
const readyCallback = async () => {
if (this._loaderHost) {
this._loaderHost.node.style.opacity = '0';
setTimeout(() => {
this.layout?.removeWidget(this._loaderHost!);
}, 100);
} else {
hideAppLoadingIndicator();
}
};
return outs;
}

getLayout(): ISpectaLayout {
const layout = this._spectaAppConfig?.defaultLayout ?? 'default';
const spectaLayout =
this._layoutRegistry.get(layout) ??
this._layoutRegistry.getDefaultLayout();
return spectaLayout;
}

async render(): Promise<void> {
const cellList = this._model.cells;
this._outputs = await this.generateOutputs(cellList);
const spectaLayout = this.getLayout();
const readyCallback = async () => this.removeSpinner();

await spectaLayout.render({
host: this._host,
items: this._outputs,
Expand All @@ -116,6 +138,33 @@ export class AppWidget extends Panel {
});
}

async rerender(newCells: CellList): Promise<void> {
this.addSpinner();
for (const element of this._outputs) {
element.dispose();
}

const currentEls = [...this._host.widgets];
currentEls.forEach(el => {
this._host.layout?.removeWidget(el);
});

this._outputs = await this.generateOutputs(newCells);

const spectaLayout = this.getLayout();

await spectaLayout.render({
host: this._host,
items: this._outputs,
notebook: this._model.context?.model.toJSON() as any,
readyCallback: async () => {},
spectaConfig: this._spectaAppConfig
});

emitResizeEvent();
this.removeSpinner();
}

protected onCloseRequest(msg: Message): void {
this._model.dispose();
super.onCloseRequest(msg);
Expand Down