diff --git a/examples/loading/.gitignore b/examples/loading/.gitignore new file mode 100644 index 0000000..3f68feb --- /dev/null +++ b/examples/loading/.gitignore @@ -0,0 +1 @@ +loading \ No newline at end of file diff --git a/examples/loading/loading.py b/examples/loading/loading.py new file mode 100644 index 0000000..b554feb --- /dev/null +++ b/examples/loading/loading.py @@ -0,0 +1,25 @@ +import os +from trame.app import get_server +from trame.widgets import html +from trame.ui.html import DivLayout +import time + +server = get_server(client_type=os.environ.get("TRAME_CLIENT_TYPE", "vue3")) + +# ----------------------------------------------------------------------------- +# Only with Vue3 +# ----------------------------------------------------------------------------- +with DivLayout(server, template_name="error") as layout: + html.Div("App disconnected: {{ trame_error_report_msg }}") + +with DivLayout(server, template_name="error_reconnect") as layout: + html.Div("App disconnected but you can reconnect: {{ trame_error_report_msg }}") +# ----------------------------------------------------------------------------- + +with DivLayout(server) as layout: + html.Div("App is fully loaded") + +# Busy wait +time.sleep(5) + +server.start() diff --git a/examples/loading/loading_launcher.json b/examples/loading/loading_launcher.json new file mode 100644 index 0000000..59f7e4c --- /dev/null +++ b/examples/loading/loading_launcher.json @@ -0,0 +1,22 @@ + +{ + "configuration": { + "host" : "localhost", + "port" : 8080, + "endpoint": "paraview", + "content": "loading/loading_www", + "proxy_file" : "loading/proxy-mapping.txt", + "sessionURL" : "ws://${host}:${port}/ws", + "timeout" : 50, + "log_dir" : "loading", + "fields" : [] + }, + "resources" : [ { "host" : "localhost", "port_range" : [9001, 9020] } ], + "properties" : {}, + "apps" : { + "trame" : { + "cmd" : ["python", "loading.py", "--port", "$port", "--server", "--authKey", "${secret}"], + "ready_line" : "App running at" + } + } +} \ No newline at end of file diff --git a/examples/loading/run_loading.sh b/examples/loading/run_loading.sh new file mode 100755 index 0000000..e72ecf5 --- /dev/null +++ b/examples/loading/run_loading.sh @@ -0,0 +1,7 @@ +# export TRAME_CLIENT_TYPE=vue2 +export TRAME_CLIENT_TYPE=vue3 + +rm -rf ./loading/ +mkdir -p ./loading/loading_www +python -m trame.tools.www --client-type "$TRAME_CLIENT_TYPE" --output ./loading/loading_www +python -m wslink.launcher ./loading_launcher.json \ No newline at end of file diff --git a/vue2-app/public/index.html b/vue2-app/public/index.html index 11cef3c..b309873 100644 --- a/vue2-app/public/index.html +++ b/vue2-app/public/index.html @@ -12,106 +12,14 @@ trame is built by Kitware -
-
-
-
-
- Loading... -
-
+
diff --git a/vue2-app/public/loading/index.html b/vue2-app/public/loading/index.html new file mode 100644 index 0000000..46243a3 --- /dev/null +++ b/vue2-app/public/loading/index.html @@ -0,0 +1,101 @@ + + + + + + Loading... + + + +
+
+
Loading...
+
+ + diff --git a/vue3-app/index.html b/vue3-app/index.html index fd39c12..b526b54 100644 --- a/vue3-app/index.html +++ b/vue3-app/index.html @@ -11,103 +11,14 @@ trame is built by Kitware -
-
-
-
Loading...
-
+
diff --git a/vue3-app/public/loading/index.html b/vue3-app/public/loading/index.html new file mode 100644 index 0000000..46243a3 --- /dev/null +++ b/vue3-app/public/loading/index.html @@ -0,0 +1,101 @@ + + + + + + Loading... + + + +
+
+
Loading...
+
+ + diff --git a/vue3-app/src/main.js b/vue3-app/src/main.js index 0083827..53aaa02 100644 --- a/vue3-app/src/main.js +++ b/vue3-app/src/main.js @@ -1,3 +1,4 @@ +import "./style.css"; import vtkURLExtract from "@kitware/vtk.js/Common/Core/URLExtract"; import wslink from "./core/wslink"; import { handlePageResources } from "./core/trame/setup"; @@ -38,6 +39,7 @@ async function start() { function reportWsError(message) { if (trame) { console.log("about to replace template", message); + trame.state.set("trame_error_report_msg", message); let templateName = "trame__template_main"; if (vtkURLExtract.extractURLParameters().ui) { templateName = `trame__template_${ @@ -47,10 +49,15 @@ async function start() { if (config.reconnect) { trame.state.set( templateName, - `` + trame.state.get("trame__template_error_reconnect") || + `` ); } else { - trame.state.set(templateName, ``); + trame.state.set( + templateName, + trame.state.get("trame__template_error") || + `` + ); } console.log("template replaced", trame.state.get(templateName)); } else { diff --git a/vue3-app/src/style.css b/vue3-app/src/style.css new file mode 100644 index 0000000..3a9d9a1 --- /dev/null +++ b/vue3-app/src/style.css @@ -0,0 +1,85 @@ +.text-no-select { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + .trame__loader { + display: block; + position: relative; + left: 50%; + top: calc(50% - 50px); + width: 150px; + height: 150px; + margin: -75px 0 0 -75px; + border-radius: 50%; + border: 10px solid transparent; + border-top-color: #ac262c; + + -webkit-animation: spin 2s linear infinite; /* Chrome, Opera 15+, Safari 5+ */ + animation: spin 2s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */ + } + + .trame__loader:before { + content: ""; + position: absolute; + top: 5px; + left: 5px; + right: 5px; + bottom: 5px; + border-radius: 50%; + border: 10px solid transparent; + border-top-color: #258e44; + + -webkit-animation: spin 3s linear infinite; /* Chrome, Opera 15+, Safari 5+ */ + animation: spin 3s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */ + } + + .trame__loader:after { + content: ""; + position: absolute; + top: 20px; + left: 20px; + right: 20px; + bottom: 20px; + border-radius: 50%; + border: 10px solid transparent; + border-top-color: #1c4678; + + -webkit-animation: spin 1.5s linear infinite; /* Chrome, Opera 15+, Safari 5+ */ + animation: spin 1.5s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */ + } + + .trame__message { + position: absolute; + text-align: center; + width: 100%; + top: calc(50% + 50px); + font-size: 200%; + user-select: none; + } + + @-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */ + -ms-transform: rotate(0deg); /* IE 9 */ + transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */ + } + 100% { + -webkit-transform: rotate(360deg); /* Chrome, Opera 15+, Safari 3.1+ */ + -ms-transform: rotate(360deg); /* IE 9 */ + transform: rotate(360deg); /* Firefox 16+, IE 10+, Opera */ + } + } + @keyframes spin { + 0% { + -webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */ + -ms-transform: rotate(0deg); /* IE 9 */ + transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */ + } + 100% { + -webkit-transform: rotate(360deg); /* Chrome, Opera 15+, Safari 3.1+ */ + -ms-transform: rotate(360deg); /* IE 9 */ + transform: rotate(360deg); /* Firefox 16+, IE 10+, Opera */ + } + } \ No newline at end of file