Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extendable voila #1290

Merged
merged 4 commits into from
Feb 21, 2023
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
6 changes: 2 additions & 4 deletions packages/voila/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,5 @@
export * from './app';
export * from './manager';
export * from './shell';

import * as plugins from './plugins';

export { plugins };
export * from './output';
export * from './plugins';
3 changes: 2 additions & 1 deletion packages/voila/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils';

import { VoilaApp } from './app';
import { VoilaShell } from './shell';
import plugins from './plugins';

function loadScript(url: string): Promise<any> {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -68,7 +69,7 @@ async function main() {
// This would also need the theme manager plugin and settings
// require('@jupyterlab/theme-light-extension'),
// require('@jupyterlab/theme-dark-extension'),
require('./plugins')
plugins
];

const mimeExtensions = [require('@jupyterlab/json-extension')];
Expand Down
14 changes: 7 additions & 7 deletions packages/voila/src/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { WidgetManager as VoilaWidgetManager } from './manager';
/**
* The default paths.
*/
const paths: JupyterFrontEndPlugin<JupyterFrontEnd.IPaths> = {
export const pathsPlugin: JupyterFrontEndPlugin<JupyterFrontEnd.IPaths> = {
id: '@voila-dashboards/voila:paths',
activate: (
app: JupyterFrontEnd<JupyterFrontEnd.IShell>
Expand All @@ -51,7 +51,7 @@ const paths: JupyterFrontEndPlugin<JupyterFrontEnd.IPaths> = {
* TODO: a cleaner solution would involve a custom ServiceManager to the VoilaApp
* to prevent the default behavior of polling the /api endpoints.
*/
const stopPolling: JupyterFrontEndPlugin<void> = {
export const stopPollingPlugin: JupyterFrontEndPlugin<void> = {
id: '@voila-dashboards/voila:stop-polling',
autoStart: true,
activate: (app: JupyterFrontEnd): void => {
Expand All @@ -69,7 +69,7 @@ const stopPolling: JupyterFrontEndPlugin<void> = {
/**
* A simplified Translator
*/
const translator: JupyterFrontEndPlugin<ITranslator> = {
export const translatorPlugin: JupyterFrontEndPlugin<ITranslator> = {
id: '@voila-dashboards/voila:translator',
activate: (app: JupyterFrontEnd<JupyterFrontEnd.IShell>): ITranslator => {
const translationManager = new TranslationManager();
Expand All @@ -82,7 +82,7 @@ const translator: JupyterFrontEndPlugin<ITranslator> = {
/**
* The Voila widgets manager plugin.
*/
const widgetManager: JupyterFrontEndPlugin<IJupyterWidgetRegistry> = {
export const widgetManager: JupyterFrontEndPlugin<IJupyterWidgetRegistry> = {
id: '@voila-dashboards/voila:widget-manager',
autoStart: true,
requires: [IRenderMimeRegistry],
Expand Down Expand Up @@ -135,9 +135,9 @@ const widgetManager: JupyterFrontEndPlugin<IJupyterWidgetRegistry> = {
* Export the plugins as default.
*/
const plugins: JupyterFrontEndPlugin<any>[] = [
paths,
stopPolling,
translator,
pathsPlugin,
stopPollingPlugin,
translatorPlugin,
widgetManager
];

Expand Down
3 changes: 1 addition & 2 deletions share/jupyter/voila/templates/base/spinner.macro.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@
{% endmacro %}

{% macro html() %}
<div id="loading">
<div id="loading" style="display: none;">
<div class="spinner-container">
<svg class="spinner" data-name="c1" version="1.1" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title>voila</dc:title></cc:Work></rdf:RDF></metadata><title>spin</title><path class="voila-spinner-color1" d="m250 405c-85.47 0-155-69.53-155-155s69.53-155 155-155 155 69.53 155 155-69.53 155-155 155zm0-275.5a120.5 120.5 0 1 0 120.5 120.5 120.6 120.6 0 0 0-120.5-120.5z"/><path class="voila-spinner-color2" d="m250 405c-85.47 0-155-69.53-155-155a17.26 17.26 0 1 1 34.51 0 120.6 120.6 0 0 0 120.5 120.5 17.26 17.26 0 1 1 0 34.51z"/></svg>
</div>
<h2 id="loading_text">Running {{nb_title}}...</h2>
</div>
{% endmacro %}

38 changes: 30 additions & 8 deletions share/jupyter/voila/templates/base/voila_setup.macro.html.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{%- macro voila_setup_labextensions(base_url, labextensions) -%}
<script src="{{ page_config['fullStaticUrl'] | e }}/voila.js"></script>
<script src="{{ page_config['fullStaticUrl'] | e }}/{{ main_js }}"></script>
{%- endmacro %}

{# For backward compatibility #}
Expand All @@ -10,12 +10,34 @@
{# Helper functions for updating the loading text #}
{%- macro voila_setup_helper_functions() -%}
<script>
var voila_process = function(cell_index, cell_count) {
var el = document.getElementById("loading_text");
el.innerHTML = `Executing ${cell_index} of ${cell_count}`;
}
var voila_heartbeat = function() {
console.log('Ok, voila is still executing...');
}
window.voila_heartbeat = function() {
console.log('Ok, voila is still executing...');
}
window.update_loading_text = function(cell_index, cell_count, text) {
const spinner = document.getElementById("loading")
if(spinner && spinner.style.display === "none"){
spinner.style.display="flex";
}
var el = document.getElementById("loading_text");
innterText = text ?? `Executing ${cell_index} of ${cell_count}`
if(el){
el.innerHTML = innterText;
}
}
window.display_cells = function() {
// remove the loading element
var el = document.getElementById("loading");
if(el){
el.parentNode.removeChild(el);
}
// show the cell output
el = document.getElementById("rendered_cells");
if(el){
el.style.display = '';
}
}

window.voila_process = {{ voila_process | default("window.update_loading_text") }};
window.voila_finish = {{ voila_finish | default("window.display_cells") }};
</script>
{%- endmacro %}
26 changes: 25 additions & 1 deletion share/jupyter/voila/templates/classic/index.html.j2
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{%- extends 'nbconvert/templates/classic/index.html.j2' -%}
{% import "log.macro.html.j2" as log %}
{% from 'voila_setup.macro.html.j2' import voila_setup with context %}
{% import "spinner.macro.html.j2" as spinner %}
{% from 'voila_setup.macro.html.j2' import voila_setup_helper_functions, voila_setup with context %}

{%- block html_head_js -%}
{%- block html_head_js_logs -%}
Expand Down Expand Up @@ -32,6 +33,7 @@
{%- block html_head_css -%}
{{ resources.include_css("static/materialcolors.css") }}
{{ resources.include_css("static/labvariables.css") }}
{{ spinner.css() }}
<style>
/*Hide empty cells*/
.jp-mod-noOutputs.jp-mod-noInput {
Expand All @@ -44,10 +46,32 @@

{% block body_header %}
<body data-base-url="{{resources.base_url}}voila/">
{{ spinner.html() }}
{{ voila_setup_helper_functions() }}
<div tabindex="-1" id="notebook" class="border-box-sizing">
<div class="container" id="notebook-container">
<div id="rendered_cells" style="display: none">
{% endblock body_header %}

{%- block body_loop -%}
{%- for cell in nb.cells -%}
{% set cellloop = loop %}
{%- block any_cell scoped -%}
<div cell-index={{cellloop.index}}>
{{ super() }}
</div>
{%- endblock any_cell -%}
{%- endfor -%}
{%- endblock body_loop -%}

{%- block body_footer -%}
</div>
<script type="text/javascript">
window.voila_finish();
</script>
{{ super() }}
{%- endblock body_footer -%}

{%- block footer %}
{% block footer_js %}
{{ voila_setup(resources.base_url, resources.labextensions) }}
Expand Down
19 changes: 7 additions & 12 deletions share/jupyter/voila/templates/lab/index.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,12 @@
{%- for cell in cell_generator(nb, kernel_id) -%}
{% set cellloop = loop %}
{%- block any_cell scoped -%}
<script>
voila_process({{ cellloop.index }}, {{ cell_count }})
</script>
{{ super() }}
<div cell-index={{cellloop.index}}>
<script>
voila_process({{ cellloop.index }}, {{ cell_count }})
</script>
{{ super() }}
</div>
{%- endblock any_cell -%}
{%- endfor -%}
{% endwith %}
Expand All @@ -95,14 +97,7 @@
</div>
</div>
<script type="text/javascript">
(function() {
// remove the loading element
var el = document.getElementById("loading");
el.parentNode.removeChild(el);
// show the cell output
el = document.getElementById("rendered_cells");
el.style.display = '';
})();
window.voila_finish();
</script>
{{ voila_setup_labextensions(resources.base_url, resources.labextensions) }}
{{ super() }}
Expand Down
55 changes: 38 additions & 17 deletions share/jupyter/voila/templates/lab/tree.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,45 @@
{% endblock %}

{% block body %}
<div class="list-header">
<div class="list-header-text">
Select items to open with Voilà.
</div>
</div>

<ul class="voila-notebooks">
{% if breadcrumbs|length > 1: %}
<li><a href="{{ breadcrumbs[-2][0] }}?{{ query }}"><i class="fa fa-folder"></i>..</a></li>
<!-- TODO Remove this condition. This is a temporary workaround for Voici
to support dynamic theming, but we should allow this for all Voila front-ends -->
{% if frontend == 'voici' %}
{% set openInNewTab = 'target=_blank' %}
<script id="jupyter-config-data" type="application/json">
{{ page_config | tojson }}
</script>
{% if (theme != 'dark' and theme != 'light') %}
<script src="{{ page_config['fullStaticUrl'] | e }}/treepage.js"></script>
<div id="voila-tree-main" style="display: None;">
{% set mainStyle = 'style="display: None;"' %}
{% else %}
{% set mainStyle = '' %}
{% endif %}
{% else %}
{% set openInNewTab = '' %}
{% set mainStyle = '' %}
{% endif %}

{% for content in contents.content %}
{% if content.type in ['notebook', 'file'] %}
<li><a href="{{ base_url }}voila/render/{{ content.path }}?{{ query }}"><i class="fa fa-book"></i>{{content.name}}</a></li>
{% endif %}
{% if content.type == 'directory' %}
<li><a href="{{ base_url }}voila/tree/{{ content.path }}?{{ query }}"><i class="fa fa-folder"></i>{{content.name}}</a></li>
<div id="voila-tree-main" {{mainStyle}}>
<div class="list-header">
<div class="list-header-text">
Select items to open with Voilà.
</div>
</div>

<ul class="voila-notebooks">
{% if breadcrumbs|length > 1: %}
<li><a href="{{ breadcrumbs[-2][0] }}?{{ query }}"><i class="fa fa-folder"></i>..</a></li>
{% endif %}
{% endfor %}
</ul>

{% for content in contents.content %}
{% if content.type in ['notebook', 'file'] %}
<li><a href="{{ base_url }}voila/render/{{ content.path }}?{{ query }}" {{openInNewTab}}><i class="fa fa-book"></i>{{content.name}}</a></li>
{% endif %}
{% if content.type == 'directory' %}
<li><a href="{{ base_url }}voila/tree/{{ content.path }}?{{ query }}"><i class="fa fa-folder"></i>{{content.name}}</a></li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endblock %}
52 changes: 50 additions & 2 deletions share/jupyter/voila/templates/reveal/index.html.j2
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{%- extends 'nbconvert/templates/reveal/index.html.j2' -%}
{% import "log.macro.html.j2" as log %}
{% from 'voila_setup.macro.html.j2' import voila_setup with context %}
{% import "spinner.macro.html.j2" as spinner %}
{% from 'voila_setup.macro.html.j2' import voila_setup_helper_functions, voila_setup with context %}

{%- block html_head_js -%}
{%- block html_head_js_requirejs -%}
<script
src="{{resources.base_url}}voila/static/require.min.js"
src="{{resources.base_url}}voila/templates/reveal/static/require.min.js"
integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA="
crossorigin="anonymous">
</script>
Expand Down Expand Up @@ -42,6 +43,13 @@
{{ resources.include_css("static/materialcolors.css") }}
{{ resources.include_css("static/labvariables.css") }}
{{ super() }}
{{ spinner.css() }}
<style>
/*Hide empty cells*/
.jp-mod-noOutputs.jp-mod-noInput {
display: none;
}
</style>
{%- endblock html_head_css -%}

{% block body_header %}
Expand All @@ -50,10 +58,50 @@
{% else %}
<body class="jp-Notebook" data-base-url="{{resources.base_url}}voila/" data-jp-theme-light="true" data-jp-theme-name="JupyterLab Light">
{% endif %}
{{ spinner.html() }}
{{ voila_setup_helper_functions() }}
<div id="rendered_cells" style="display: none; height:100vh">
<div class="reveal">
<div class="slides">
{% endblock body_header %}

{%- block codecell -%}
<div cell-index={{cellloop.index}}>
{{ super() }}
</div>
{%- endblock codecell -%}

{%- block markdowncell -%}
<div cell-index={{cellloop.index}}>
{{ super() }}
</div>
{%- endblock markdowncell -%}

{%- block rawcell -%}
<div cell-index={{cellloop.index}}>
{{ super() }}
</div>
{%- endblock rawcell -%}

{%- block body_loop -%}
{%- for cell in nb.cells -%}
{% set cellloop = loop %}
{%- block any_cell scoped -%}
{{ super() }}
{%- endblock any_cell -%}
{%- endfor -%}
{%- endblock body_loop -%}

{%- block body_footer -%}
</div>
</div>
</div>
</body>
<script type="text/javascript">
window.voila_finish();
</script>
{%- endblock body_footer -%}

{% block footer_js %}
{{ voila_setup(resources.base_url, resources.labextensions) }}
{{ super() }}
Expand Down
2 changes: 1 addition & 1 deletion voila/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def time_out():
can be used in a template to give feedback to a user
"""

return '<script>voila_heartbeat()</script>\n'
return '<script>window.voila_heartbeat()</script>\n'

kernel_env = {**os.environ, **request_info}
kernel_env[ENV_VARIABLE.VOILA_PREHEAT] = 'False'
Expand Down
2 changes: 2 additions & 0 deletions voila/notebook_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ def inner_cell_generator(nb, kernel_id):
# notebook_executer cell_generator to implement progressive cell rendering

extra_context = {
'frontend': 'voila',
'main_js': 'voila.js',
'kernel_start': inner_kernel_start,
'cell_generator': inner_cell_generator,
'notebook_execute': self._jinja_notebook_execute
Expand Down
2 changes: 2 additions & 0 deletions voila/treehandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ def allowed_content(content):

self.write(self.render_template(
'tree.html',
frontend='voila',
main_js='voila.js',
page_title=page_title,
notebook_path=path,
breadcrumbs=breadcrumbs,
Expand Down
Loading