-
+
+
+
+
@@ -81,6 +90,11 @@
{{ t("safe") }}
+
+ {{ t("share") }}
+
+
+
{{ t("run") }}
@@ -133,8 +147,6 @@ export default {
const tabStore = useTabStore();
const route = useRoute();
- console.log("params:", route.query)
-
const { t } = useI18n() // call `useI18n`, and spread `t` from `useI18n` returning
@@ -200,6 +212,22 @@ export default {
}
}
+ function shareScript(){
+ if (!route.query.key) {
+ console.error("Cant share without an opened tab!");
+ return;
+ }
+
+ let _url = window.location.origin+"/#"+"/runner/"+route.query.key;
+
+ console.log(import.meta.env.MODE)
+ if (import.meta.env.MODE === "production")
+ _url = window.location.origin+"/scriptor/index.html"+"#"+"/runner/"+route.query.key;
+
+ messageStore.addMessage("success", "The shared link got copied into the clipboard.", "")
+ navigator.clipboard.writeText(_url);
+ }
+
function runScript(){
if (tabStore.selectedTab) {
let content = tabStore.tabMap[tabStore.selectedTab];
@@ -225,7 +253,6 @@ export default {
for (let index in data.modules) {
let moduleEntry = data.modules[index];
- console.log("index", index, "moduleEntry", moduleEntry)
modules.value.push(
{
name: index,
@@ -254,6 +281,7 @@ export default {
onChangeCode,
manager,
saveScript,
+ shareScript,
runScript,
tree,
isLoading,
@@ -267,6 +295,9 @@ export default {
interruptCode,
showGeneralLogs,
pythonStore,
+ canShare: computed(function(){
+ return route.query.key;
+ }),
t
}
}
@@ -304,6 +335,7 @@ export default {
font-weight: 700;
z-index: 1;
padding: 10px 15px 15px 15px;
+ display: flex
}
.log-format {
@@ -605,4 +637,11 @@ div.cm-content {
}
+.logo {
+ width: 55px;
+ height: 55px;
+ background-color: transparent !important;
+}
+
+
diff --git a/src/components/Interaction/Alert.vue b/src/components/Interaction/Alert.vue
index ef1470b..f45bcbf 100644
--- a/src/components/Interaction/Alert.vue
+++ b/src/components/Interaction/Alert.vue
@@ -2,7 +2,7 @@
- {{ t('Alert') }}
+ {{ t('alert') }}
diff --git a/src/components/Interaction/Confirm.vue b/src/components/Interaction/Confirm.vue
index b02b294..cead519 100644
--- a/src/components/Interaction/Confirm.vue
+++ b/src/components/Interaction/Confirm.vue
@@ -13,7 +13,7 @@
confirm(0)">{{ t('no')}}
confirm(-1)">{{ t('cancel') }}
+ size="small" v-if="props.cancel" variant="neutral" :class="'accept-button ' + ((selectedValue != -1 && selectedValue !== undefined) ? 'selected-button' : '')" @click="() => confirm(-1)">{{ t('cancel') }}
confirm(1)">{{ t('yes') }}
diff --git a/src/components/Interaction/Input.vue b/src/components/Interaction/Input.vue
index b3c6865..a8c5558 100644
--- a/src/components/Interaction/Input.vue
+++ b/src/components/Interaction/Input.vue
@@ -9,7 +9,8 @@
{{ props.text }}
-
{{ error }}
+
{{ error }}
+
@@ -102,5 +103,8 @@ function send() {
font-size: var(--sl-font-size-medium);
}
+.error-message {
+ margin-bottom: 15px;
+}
diff --git a/src/components/Interaction/Select.vue b/src/components/Interaction/Select.vue
index 8b5027f..d976440 100644
--- a/src/components/Interaction/Select.vue
+++ b/src/components/Interaction/Select.vue
@@ -9,7 +9,7 @@
- selectOption(option)">
+ selectOption(option, index)">
{{ props.options[option] }}
@@ -50,7 +50,9 @@ const {t} = useI18n();
const entries = [];
-function selectOption(index: number) {
+const selectedOption = ref(-1);
+
+function selectOption(index: number, _index: number) {
if (!render.value)
return;
@@ -58,6 +60,8 @@ function selectOption(index: number) {
render.value = false;
props.select(index);
+
+ selectedOption.value = _index;
}
function selectRadioButton(event: UIEvent, index: string) {
diff --git a/src/components/Messaging/MessageDrawer.vue b/src/components/Messaging/MessageDrawer.vue
index d172c64..8e401d8 100644
--- a/src/components/Messaging/MessageDrawer.vue
+++ b/src/components/Messaging/MessageDrawer.vue
@@ -15,7 +15,7 @@
-
tag.startsWith('sl-');
app.provide("global", global)
diff --git a/src/router/index.js b/src/router/index.js
index ab08c4b..9a704cb 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,5 +1,7 @@
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../components/Home.vue'
+import Runner from '../views/Runner.vue'
+
import Interactions from '../views/Interactions.vue';
const routes = [
@@ -14,6 +16,12 @@ const routes = [
component: Home
},
+ {
+ path: '/runner/:key',
+ name: 'Runner',
+ component: Runner
+ },
+
{
path: '/interactions',
name: 'Interactions',
diff --git a/src/stores/PythonStore.ts b/src/stores/PythonStore.ts
index 6148c0a..4a9808b 100644
--- a/src/stores/PythonStore.ts
+++ b/src/stores/PythonStore.ts
@@ -3,6 +3,7 @@ import { ref } from 'vue';
import { defineStore } from 'pinia'
import { usePython} from "usepython";
import { useTabStore } from './TabStore';
+import { useRoute } from 'vue-router';
interface PyEvents
@@ -28,12 +29,10 @@ export const usePythonStore = defineStore('python', () => {
onLog(val.stdOut[entry]);
}
}
- console.log("LOG", val.stdOut);
// val.stdErr is also available
}
else
{
- console.log("Exception:", val.exception)
if (scriptRunnerTab.value) {
@@ -73,7 +72,6 @@ export const usePythonStore = defineStore('python', () => {
async function init(key: string, onLogCallback: Function, onErrorCallback: Function, onRunCallback: Function) {
- console.log("on init!")
eventMap.value[key] = {
logCallback: onLogCallback,
errorCallback: onErrorCallback,
@@ -88,8 +86,9 @@ export const usePythonStore = defineStore('python', () => {
}
const timer = ref();
+ const defaultCode = "#### scriptor ####\nfrom scriptor import dialog\n\nasync def main():\n await dialog.alert(\"Hello World\")";
- let runScript = function (code: string){
+ let runScript = function (code: string, name: string = undefined, key: string = undefined){
let extraCode = "from scriptor import print, init as __scriptor__init\nawait __scriptor__init()\n";
if (code.includes("async def main():"))
code += "\nawait main()"
@@ -97,8 +96,14 @@ export const usePythonStore = defineStore('python', () => {
if (py.isExecuting.get() === true)
return;
- let tabName = tabStore.tabMap[tabStore.selectedTab].name;
-
+
+ let tabName = "";
+
+ if (name)
+ tabName = name;
+ else
+ tabName = tabStore.tabMap[tabStore.selectedTab].name;
+
runningText.value = "Running " + tabName + " ";
if (timer.value)
@@ -116,11 +121,14 @@ export const usePythonStore = defineStore('python', () => {
}
}, 150)
- scriptRunnerTab.value = tabStore.selectedTab;
+ if (key)
+ scriptRunnerTab.value = key;
+ else
+ scriptRunnerTab.value = tabStore.selectedTab;
+
isExecuting.value = true;
if (scriptRunnerTab.value) {
- console.log(eventMap.value, scriptRunnerTab.value)
let onRun = eventMap.value[scriptRunnerTab.value].runCallback;
if (onRun)
onRun();
@@ -136,6 +144,8 @@ export const usePythonStore = defineStore('python', () => {
});
};
+ const route = useRoute();
+
async function loadPython() {
isLoading.value = true;
@@ -151,8 +161,6 @@ export const usePythonStore = defineStore('python', () => {
const zipUrl = new URL('../assets/scriptor.zip', import.meta.url).href
- console.log("zipUrl:", zipUrl);
-
// Loading scriptor library
await py.run(`
from pyodide.http import pyfetch
@@ -160,6 +168,29 @@ export const usePythonStore = defineStore('python', () => {
await response.unpack_archive()
`)
+ let object = {};
+
+
+ if (route.query["scriptor_params"]) {
+
+ if (typeof route.query.scriptor_params === 'string')
+ {
+ try {
+ let _string = route.query.scriptor_params.replace(/'/g, '"');;
+ object = JSON.parse(_string)
+ }
+ catch(error) {
+ console.error(error)
+ }
+ }
+ else
+ {
+ object = route.query.scriptor_params;
+ }
+ }
+
+ await py.sendParams(object)
+
isLoading.value = false;
}
@@ -186,5 +217,5 @@ export const usePythonStore = defineStore('python', () => {
}
- return { py, run, setCode, getCode, init, runScript, loadPython, reloadPyodide, isLoading, scriptRunnerTab, isExecuting, runningText }
+ return { py, run, setCode, getCode, init, runScript, loadPython, reloadPyodide, isLoading, scriptRunnerTab, isExecuting, runningText, defaultCode }
})
diff --git a/src/stores/TabStore.ts b/src/stores/TabStore.ts
index b9604d5..c42753f 100644
--- a/src/stores/TabStore.ts
+++ b/src/stores/TabStore.ts
@@ -47,7 +47,7 @@ export const useTabStore = defineStore('tab', () => {
let getTabCode = (key: string) => {
let code = tabMap.value[key].code;
- if (code.length > 1)
+ if (code.length > 1 && code[code.length-1] === '\n')
code = code.substring(0, code.length - 1);
return code;
@@ -64,13 +64,10 @@ export const useTabStore = defineStore('tab', () => {
let index = tabList.value.indexOf(item);
if (index-1>=0) {
item.leftNode = tabList.value[index-1];
- console.log("Adding index ", index, " leftNode ", index-1);
}
if (index + 1 < tabList.value.length){
item.rightNode = tabList.value[index+1];
- console.log("Adding index ", index, " rightNode ", index+1);
- console.log("Right node = ", item.rightNode);
}
});
}
@@ -82,7 +79,6 @@ export const useTabStore = defineStore('tab', () => {
return item.key !== key;
});
- console.log("Adding code", code)
tabMap.value[key] = {
name: name,
code: code,
@@ -106,7 +102,6 @@ export const useTabStore = defineStore('tab', () => {
}, 200);
- console.log("TabGroup SHow: ", key)
}
}
@@ -120,7 +115,6 @@ export const useTabStore = defineStore('tab', () => {
}
)
- console.log("Calling selectTab Tab", selectedTab.value);
}
}
@@ -140,7 +134,6 @@ export const useTabStore = defineStore('tab', () => {
}, 200);
- console.log("TabGroup SHow: ", key)
}
return true;
@@ -173,11 +166,9 @@ export const useTabStore = defineStore('tab', () => {
if (tabInstance.leftNode !== undefined) {
nextIndex = _keys.indexOf(tabInstance.leftNode.key);
- console.log("left node instance:", tabInstance.leftNode);
}
if (tabInstance.rightNode !== undefined) {
- console.log("right node instance:", tabInstance.rightNode);
if (nextIndex === -1)
nextIndex = _keys.indexOf(tabInstance.rightNode.key);
}
@@ -188,10 +179,6 @@ export const useTabStore = defineStore('tab', () => {
nextIndex = indexOfTab;
}
- console.log("NextIndex: ", nextIndex)
-
- console.log(tabMap.value);
-
selectedTab.value = "";
if (_keys.length > 0) {
if (nextIndex === -1)
@@ -209,6 +196,9 @@ export const useTabStore = defineStore('tab', () => {
}
}, 250);
}
+ else {
+ router.push({})
+ }
}
diff --git a/src/stores/log.ts b/src/stores/log.ts
index 11b99c6..a17a0a0 100644
--- a/src/stores/log.ts
+++ b/src/stores/log.ts
@@ -19,7 +19,6 @@ export const useLogStore = defineStore("log", () => {
function getThemeByLevel(level: string)
{
- console.log("level", level);
switch (level)
{
case "debug": return "neutral";
@@ -50,18 +49,13 @@ export const useLogStore = defineStore("log", () => {
if (!(pythonStore.scriptRunnerTab in logMap.value))
logMap.value[pythonStore.scriptRunnerTab] = ref([]);
- //console.log("Notify: python logging", val)
- //console.log("pythonStore.scriptRunnerTab:", pythonStore.scriptRunnerTab, " props.keyValue: ", props.keyValue);
{
- console.error("pythonStore.py.pyLogging");
for (let i = 0; i {
async function _dispatchEvent(id: string, data: Record) {
- console.log("Python process id recv", id, " data ", data);
switch (data.type) {
case "end":
{
@@ -466,13 +465,22 @@ const usePython = () => {
return new Promise((onSuccess) => {
//_callback = onSuccess;
- console.log("IM HERE!");
_pyodideWorker.postMessage({
id: "_sendDialogSignal",
...context,
});
});
}
+
+ function sendParams(params: object) {
+ return new Promise((onSuccess) => {
+ _callback = onSuccess;
+ _pyodideWorker.postMessage({
+ id: "setParams",
+ params
+ });
+ });
+ }
@@ -499,7 +507,8 @@ const usePython = () => {
interruptExecution,
destroyAndCreateWorker,
restoreFS,
- sendDialogResult
+ sendDialogResult,
+ sendParams
}
}
diff --git a/src/usepython/src/webworker.js b/src/usepython/src/webworker.js
index 5d828fe..2021c60 100644
--- a/src/usepython/src/webworker.js
+++ b/src/usepython/src/webworker.js
@@ -37,6 +37,7 @@ let manager = {
allocId: 0,
currentProcessId: 0,
tasks: {},
+ params: {},
resultValue: null,
copyResult: function() {
return structuredClone(this.resultValue);
@@ -105,12 +106,10 @@ async function runScript(python, id) {
//console.log("Load imports")
await self.pyodide.loadPackagesFromImports(python);
let empty_dict = await self.pyodide.runPythonAsync("{}");
- console.log("abc!!!");
//let results = await self.pyodide.globals.get("pyeval")(python, empty_dict)
//empty_dict.destroy();
manager.currentProcessId = ++manager.allocId;
- console.log("Ich bin hier!!!");
manager.tasks[manager.currentProcessId] = {
"promise": self.pyodide.globals.get("pyeval")(python, empty_dict),
"dict": empty_dict,
@@ -122,7 +121,6 @@ async function runScript(python, id) {
manager.tasks[processId]["promise"].then(() => {
manager.tasks[processId]["done"] = true;
manager.tasks[processId]["dict"].destroy();
- console.log("Task done!");
run_end(id);
}).catch((error) => {
@@ -134,8 +132,6 @@ async function runScript(python, id) {
err(id, error.message)
})
- console.log("End of file!");
-
} catch (error) {
console.log("PY RUN ERR", error)
err(id, error.message)
@@ -146,7 +142,6 @@ self.onmessageerror = e => {
}
self.onmessage = async (event) => {
const { id, python, ...context } = event.data;
- console.log("Recv message ", id, " python: ", python, " context:", context);
if (id === "_pyinstaller") {
await loadPyodideAndPackages(id, context.pyoPackages, context.packages, context.initCode, context.transformCode);
run_end(id)
@@ -156,9 +151,6 @@ self.onmessage = async (event) => {
if (context === undefined)
return;
- console.log("Starting ! name", context.name, " path:", context.path, " python: ", python)
-
-
let _path = context.path.substring(1);
let _dirs = _path.split("/");
let value = {};
@@ -170,34 +162,27 @@ self.onmessage = async (event) => {
value = self.pyodide.FS.analyzePath(_tmp_path);
_tmp_path.replaceAll("//", "/");
- console.log("Temp Path:", _tmp_path)
if (!value.exists) {
self.pyodide.FS.mkdir(_tmp_path);
}
}
- console.log("I'm here! Write!", context.name, python, "FileSystem:", self.pyodide.FS)
value = self.pyodide.FS.analyzePath(context.path);
if (!value.exists) {
self.pyodide.FS.mkdir(context.path);
- console.log("I'm here2! Creating Path:", context.path)
}
let file_path = context.path+context.name;
file_path.replaceAll("//", "/");
- console.log(`Path for writing! ${file_path}`)
value = self.pyodide.FS.analyzePath(file_path);
if (value.exists) {
self.pyodide.FS.unlink(file_path);
//self.pyodide.FS.ftruncate(file_path, 0);
- console.log(`[SEARCHING] Path exists: ${file_path}`)
}
self.pyodide.FS.writeFile(file_path, python, {encoding: "utf-8"})
- console.log("I'm here3! Write!", context.name, python)
- console.log("I'm here4! Write!", context.name, python)
end(id);
}
@@ -272,13 +257,14 @@ self.onmessage = async (event) => {
{
manager.resultValue = context.handle;
}
- else if (id === "_sendDialogSignal") {
-
- manager.resultValue = context.data;
- console.log("_sendDialogSignal recv", manager.resultValue);
- end(id);
-
-}
+ else if (id === "_sendDialogSignal") {
+ manager.resultValue = context.data;
+ end(id);
+ }
+ else if (id === "setParams") {
+ manager.params = context.params;
+ end(id);
+ }
else {
// The worker copies the context in its own "memory" (an object mapping name to values)
@@ -292,8 +278,6 @@ self.onmessage = async (event) => {
throw new Error("Python is not loaded")
}
- console.log("Functions:", context.showSaveFilePicker, " other", context.showDirectoryPicker)
-
manager.resultValue = null;
await self.pyodide.registerJsModule("manager", manager);
diff --git a/src/views/Interactions.vue b/src/views/Interactions.vue
index d3e34f5..00ad404 100644
--- a/src/views/Interactions.vue
+++ b/src/views/Interactions.vue
@@ -13,7 +13,7 @@
- {{ "result = await alert('Hey')" }}
+ {{ "await alert('Das ist eine Nachricht')" }}
@@ -25,18 +25,18 @@
Confirm
-
+
- result = await confirm("Artikel löschen", "Willst du wirklich alle Einträge löschen? Das Löschen kann nicht wieder rückgängig gemacht werden.", cancel=True)
+ result = await confirm("Willst du wirklich alle Einträge löschen? Das Löschen kann nicht wieder rückgängig gemacht werden.", allow_cancel=True)
-
+
- result = await confirm("Artikel löschen", "Willst du wirklich alle Einträge löschen? Das Löschen kann nicht wieder rückgängig gemacht werden.")
+ result = await confirm("Willst du wirklich alle Einträge löschen? Das Löschen kann nicht wieder rückgängig gemacht werden.")
@@ -46,41 +46,41 @@
Inputs
@@ -91,21 +91,21 @@
Selects
-
+
{{ 'choices = ["A", "B"]\n'
- + 'ret = await select("Select (not multiple)", "A oder B", choices)'}}
+ + 'ret = await select("Select (not multiple)", choices) '}}
-
+
{{ "choices = ['A', 'B', 'C', 'D', 'E', 'T', 'G']\n"
- + 'ret = await select("Select (multiple)", "A, B, C, D, ....", choices)'}}
+ + 'ret = await select("Select (multiple)", choices)'}}
@@ -121,7 +121,7 @@ import Input from "../components/Interaction/Input.vue";
import Select from "../components/Interaction/Select.vue";
function confirmValue(value: String) {
- console.log("confirmValue:", value)
+
}
diff --git a/src/views/Runner.vue b/src/views/Runner.vue
new file mode 100644
index 0000000..b7c0736
--- /dev/null
+++ b/src/views/Runner.vue
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vite.config.js b/vite.config.js
index 5365c74..b8ae9aa 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -9,11 +9,6 @@ import mv from "rollup-plugin-mv";
// https://vitejs.dev/config/
const APPNAME = "scriptor"
-console.log( path.join(__dirname, 'html'))
-console.log( path.join(__dirname, "scriptor.html"))
-console.log( path.join(path.dirname(require.resolve('@viur/viur-shoelace/dist/shoelace.js')), "assets"))
-console.log( path.join("..","..","deploy",'static',APPNAME,"*"))
-console.log( path.join(__dirname, 'public', "../", 'static', APPNAME, "viur-shoelace"))
export default defineConfig(({command, mode})=>{
let conf = {
css: {