diff --git a/jupyter/jupyter-base/src/jvmMain/kotlin/JupyterPluginBase.kt b/jupyter/jupyter-base/src/jvmMain/kotlin/JupyterPluginBase.kt index b0422516..4eb4c9f7 100644 --- a/jupyter/jupyter-base/src/jvmMain/kotlin/JupyterPluginBase.kt +++ b/jupyter/jupyter-base/src/jvmMain/kotlin/JupyterPluginBase.kt @@ -1,6 +1,8 @@ package space.kscience.visionforge.jupyter +import kotlinx.html.p import kotlinx.html.stream.createHTML +import kotlinx.html.style import org.jetbrains.kotlinx.jupyter.api.HTML import org.jetbrains.kotlinx.jupyter.api.declare import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration @@ -8,22 +10,19 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.Vision -import space.kscience.visionforge.html.HtmlFormFragment -import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.Page -import space.kscience.visionforge.html.fragment +import space.kscience.visionforge.html.* @DFExperimental public abstract class JupyterPluginBase(final override val context: Context) : JupyterIntegration(), ContextAware { - protected val handler: VisionForgeServerHandler = VisionForgeServerHandler(context) + protected val handler: VisionForgeForNotebook = VisionForgeForNotebook(context) protected abstract fun Builder.afterLoaded() final override fun Builder.onLoaded() { onLoaded { - declare("visionForge" to handler) + declare("VisionForge" to handler, "vf" to handler) } onShutdown { @@ -35,6 +34,9 @@ public abstract class JupyterPluginBase(final override val context: Context) : J "space.kscience.visionforge.html.*" ) + render { fragment -> + handler.produceHtml(fragment = fragment) + } render { fragment -> handler.produceHtml(fragment = fragment) @@ -53,10 +55,17 @@ public abstract class JupyterPluginBase(final override val context: Context) : J render { fragment -> handler.produceHtml { + if (!handler.isServerRunning()) { + p { + style = "color: red;" + +"The server is not running. Forms are not interactive. Start server with `VisionForge.startServer()." + } + } fragment(fragment.formBody) vision(fragment.vision) } } + afterLoaded() } -} +} \ No newline at end of file diff --git a/jupyter/jupyter-base/src/jvmMain/kotlin/VisionForgeServerHandler.kt b/jupyter/jupyter-base/src/jvmMain/kotlin/VisionForgeForNotebook.kt similarity index 78% rename from jupyter/jupyter-base/src/jvmMain/kotlin/VisionForgeServerHandler.kt rename to jupyter/jupyter-base/src/jvmMain/kotlin/VisionForgeForNotebook.kt index a01bdc43..8b17bc82 100644 --- a/jupyter/jupyter-base/src/jvmMain/kotlin/VisionForgeServerHandler.kt +++ b/jupyter/jupyter-base/src/jvmMain/kotlin/VisionForgeForNotebook.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.jupyter import io.ktor.server.engine.ApplicationEngine import kotlinx.html.FORM +import kotlinx.html.TagConsumer import kotlinx.html.p import kotlinx.html.stream.createHTML import kotlinx.html.style @@ -15,14 +16,16 @@ import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.string import space.kscience.visionforge.html.HtmlFormFragment -import space.kscience.visionforge.html.HtmlFragment import space.kscience.visionforge.html.HtmlVisionFragment import space.kscience.visionforge.html.visionFragment import space.kscience.visionforge.three.server.VisionServer import space.kscience.visionforge.three.server.serve import space.kscience.visionforge.visionManager -public class VisionForgeServerHandler(override val context: Context) : ContextAware { +/** + * A handler class that includes a server and common utilities + */ +public class VisionForgeForNotebook(override val context: Context) : ContextAware { private var counter = 0 private var engine: ApplicationEngine? = null @@ -34,27 +37,31 @@ public class VisionForgeServerHandler(override val context: Context) : ContextAw isolateFragments = true } + public fun isServerRunning(): Boolean = server != null + + public fun html(block: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(createHTML().apply(block).finalize()) + public fun startServer( host: String = context.properties["visionforge.host"].string ?: "localhost", port: Int = context.properties["visionforge.port"].int ?: VisionServer.DEFAULT_PORT, configuration: VisionServer.() -> Unit = {}, - ): HtmlFragment { + ): MimeTypedResult = html { + if (server != null) { + p { + style = "color: red;" + +"Stopping current VisionForge server" + } + } + engine?.stop(1000, 2000) engine = context.visionManager.serve(host, port) { configuration() server = this }.start() - return { - if(server!= null){ - p { - style = "color: red;" - +"Stopping current VisionForge server" - } - } - p { - style = "color: blue;" - +"Starting VisionForge server on http://$host:$port" - } + + p { + style = "color: blue;" + +"Starting VisionForge server on http://$host:$port" } } @@ -77,5 +84,6 @@ public class VisionForgeServerHandler(override val context: Context) : ContextAw public fun fragment(body: HtmlVisionFragment): MimeTypedResult = produceHtml(fragment = body) public fun page(body: HtmlVisionFragment): MimeTypedResult = produceHtml(true, body) - public fun form(builder: FORM.() -> Unit): HtmlFormFragment = HtmlFormFragment("form[${counter++}]", builder = builder) + public fun form(builder: FORM.() -> Unit): HtmlFormFragment = + HtmlFormFragment("form[${counter++}]", builder = builder) } \ No newline at end of file diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index 98a474ec..bfe711c8 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -14,10 +14,4 @@ kotlin { } } } -} - -//tasks{ -// val jsBrowserWebpack by getting(KotlinWebpack::class) { -// sourceMaps = false -// } -//} \ No newline at end of file +} \ No newline at end of file