diff --git a/frontend/src/lib/components/Path.svelte b/frontend/src/lib/components/Path.svelte
index 85f9df1ec5..dafd4320af 100644
--- a/frontend/src/lib/components/Path.svelte
+++ b/frontend/src/lib/components/Path.svelte
@@ -138,7 +138,7 @@
}
export async function reset() {
- if (path == '' || path == 'u//') {
+ if (path == '' || path == 'u//' || path?.startsWith('tmp/')) {
if ($lastMetaUsed == undefined || $lastMetaUsed.owner != $userStore?.username) {
meta = {
ownerKind: hideUser ? 'folder' : 'user',
@@ -323,12 +323,12 @@
async function initPath() {
await tick()
- if (path != undefined && path != '') {
+ if (path != undefined && path != '' && !path?.startsWith('tmp/')) {
meta = pathToMeta(path, hideUser)
onMetaChange()
return
}
- if (initialPath == undefined || initialPath == '') {
+ if (initialPath == undefined || initialPath == '' || initialPath?.startsWith('tmp/')) {
reset()
} else {
meta = pathToMeta(initialPath, hideUser)
diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte
index fa817b4058..4b386aa363 100644
--- a/frontend/src/lib/components/ScriptBuilder.svelte
+++ b/frontend/src/lib/components/ScriptBuilder.svelte
@@ -379,7 +379,7 @@
if (templateScript) {
script.content += '\r\n' + templateScript
}
- scriptEditor?.inferSchema(script.content, language, true)
+ scriptEditor?.inferSchema(script.content, { nlang: language, resetArgs: true })
if (script.content != editor?.getCode()) {
setCode(script.content)
}
@@ -567,7 +567,7 @@
if (!disableHistoryChange) {
history.replaceState(history.state, '', `/scripts/edit/${script.path}`)
}
- if (stay || script.kind !== 'script' || script.no_main_func) {
+ if (stay || (script.no_main_func && script.kind !== 'preprocessor')) {
script.parent_hash = newHash
sendUserToast('Deployed')
} else {
diff --git a/frontend/src/lib/components/ScriptEditor.svelte b/frontend/src/lib/components/ScriptEditor.svelte
index a9fcdc5cba..cd9356e34b 100644
--- a/frontend/src/lib/components/ScriptEditor.svelte
+++ b/frontend/src/lib/components/ScriptEditor.svelte
@@ -123,6 +123,8 @@
enablePreprocessorSnippet = false
}: Props = $props()
+ let initialArgs = structuredClone($state.snapshot(args))
+
$effect.pre(() => {
if (schema == undefined) {
schema = emptySchema()
@@ -269,7 +271,18 @@
})
}
- export async function inferSchema(code: string, nlang?: SupportedLanguage, resetArgs = false) {
+ export async function inferSchema(
+ code: string,
+ {
+ nlang,
+ resetArgs = false,
+ applyInitialArgs = false
+ }: {
+ nlang?: SupportedLanguage
+ resetArgs?: boolean
+ applyInitialArgs?: boolean
+ } = {}
+ ) {
let nschema = schema ?? emptySchema()
try {
@@ -297,6 +310,10 @@
if (resetArgs) {
args = {}
}
+ if (applyInitialArgs) {
+ // we reapply initial args as the schema form might have cleared them between mount and the schema inference
+ args = initialArgs
+ }
schema = nschema
} catch (e) {
validCode = false
@@ -338,7 +355,7 @@
}
onMount(() => {
- inferSchema(code)
+ inferSchema(code, { applyInitialArgs: true })
loadPastTests()
aiChatManager.saveAndClear()
aiChatManager.changeMode(AIMode.SCRIPT)
diff --git a/frontend/src/lib/components/ScriptEditorSkeleton.svelte b/frontend/src/lib/components/ScriptEditorSkeleton.svelte
new file mode 100644
index 0000000000..031b8c9ee9
--- /dev/null
+++ b/frontend/src/lib/components/ScriptEditorSkeleton.svelte
@@ -0,0 +1,55 @@
+
diff --git a/frontend/src/lib/components/TagsToListenTo.svelte b/frontend/src/lib/components/TagsToListenTo.svelte
index 76c7fe15d6..e99c67223b 100644
--- a/frontend/src/lib/components/TagsToListenTo.svelte
+++ b/frontend/src/lib/components/TagsToListenTo.svelte
@@ -29,6 +29,9 @@
{disabled}
class={disabled ? 'border-0' : ''}
allowClear={!disabled}
- onCreateItem={(c) => worker_tags.push(c)}
+ onCreateItem={(c) => {
+ worker_tags.push(c)
+ dispatch('dirty')
+ }}
createText="Press Enter to use this tag"
/>
diff --git a/frontend/src/lib/components/common/table/ScriptRow.svelte b/frontend/src/lib/components/common/table/ScriptRow.svelte
index 840bac9526..1fa78d86cd 100644
--- a/frontend/src/lib/components/common/table/ScriptRow.svelte
+++ b/frontend/src/lib/components/common/table/ScriptRow.svelte
@@ -112,7 +112,7 @@
- import { type NewScript, ScriptService, type Script } from '$lib/gen'
+ import { type NewScript, ScriptService, type ScriptLang } from '$lib/gen'
import { page } from '$app/stores'
import { defaultScripts, initialArgsStore, workspaceStore } from '$lib/stores'
import ScriptBuilder from '$lib/components/ScriptBuilder.svelte'
import type { Schema } from '$lib/common'
- import { decodeState, emptySchema, emptyString } from '$lib/utils'
+ import { decodeState, emptySchema, emptyString, sendUserToast } from '$lib/utils'
import { goto } from '$lib/navigation'
import { replaceState } from '$app/navigation'
import UnsavedConfirmationModal from '$lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte'
@@ -13,6 +13,13 @@
import type { Trigger } from '$lib/components/triggers/utils'
import { get } from 'svelte/store'
import { untrack } from 'svelte'
+ import ScriptEditorSkeleton from '$lib/components/ScriptEditorSkeleton.svelte'
+
+ type Script = NewScript & {
+ draft_triggers?: Trigger[]
+ hash?: string
+ extra_perms?: Record
+ }
// Default
let schema: Schema = emptySchema()
@@ -20,8 +27,9 @@
const templatePath = $page.url.searchParams.get('template')
const hubPath = $page.url.searchParams.get('hub')
const showMeta = /true|1/i.test($page.url.searchParams.get('show_meta') ?? '0')
+ const urlArgs = $page.url.searchParams.get('initial_args')
- let initialArgs = get(initialArgsStore) ?? {}
+ let initialArgs = urlArgs ? decodeState(urlArgs) : (get(initialArgsStore) ?? {})
if (get(initialArgsStore)) $initialArgsStore = undefined
const path = $page.url.searchParams.get('path')
@@ -40,54 +48,74 @@
}
}
- function defaultScript() {
+ function defaultScript(): Script {
return {
hash: '',
path: path ?? '',
summary: '',
content: '',
+ description: '',
schema: schema,
is_template: false,
extra_perms: {},
- language:
- $defaultScripts?.order?.filter(
- (x) => $defaultScripts?.hidden == undefined || !$defaultScripts.hidden.includes(x)
- )?.[0] ?? 'bun',
+ language: ($defaultScripts?.order?.filter(
+ (x) => $defaultScripts?.hidden == undefined || !$defaultScripts.hidden.includes(x)
+ )?.[0] ?? 'bun') as ScriptLang,
kind: 'script'
}
}
- let script: NewScript & { draft_triggers: Trigger[] } = $state(
- !path && initialState != undefined ? decodeStateAndHandleError(initialState) : defaultScript()
+ let script: Script | undefined = $state(
+ templatePath || hubPath
+ ? undefined
+ : !path && initialState != undefined
+ ? decodeStateAndHandleError(initialState)
+ : defaultScript()
)
async function loadTemplate(): Promise {
if (templatePath) {
- const template = await ScriptService.getScriptByPath({
- workspace: $workspaceStore!,
- path: templatePath
- })
-
- // Only copy the summary if it's not empty
- script.summary = !emptyString(template.summary) ? `Copy of ${template.summary}` : ''
- script.description = template.description
- script.content = template.content
- script.schema = template.schema
- script.language = template.language
- scriptBuilder?.setCode(script.content)
+ try {
+ const template = await ScriptService.getScriptByPath({
+ workspace: $workspaceStore!,
+ path: templatePath
+ })
+ script = {
+ ...defaultScript(),
+ summary: !emptyString(template.summary) ? `Copy of ${template.summary}` : '',
+ description: template.description,
+ content: template.content,
+ schema: template.schema,
+ language: template.language,
+ path: template.path + '_fork'
+ }
+ } catch (err) {
+ script = defaultScript()
+ console.error('Error loading template', err)
+ sendUserToast('Error loading template: ' + err.message, true)
+ }
}
}
async function loadHub(): Promise {
if (hubPath) {
- const { content, language, summary } = await ScriptService.getHubScriptByPath({
- path: hubPath
- })
- script.description = `Fork of ${hubPath}`
- script.content = replaceScriptPlaceholderWithItsValues(hubPath, content)
- script.summary = summary ?? ''
- script.language = language as Script['language']
- scriptBuilder?.setCode(script.content)
+ try {
+ const { content, language, summary } = await ScriptService.getHubScriptByPath({
+ path: hubPath
+ })
+ script = {
+ ...defaultScript(),
+ description: `Fork of ${hubPath}`,
+ content: replaceScriptPlaceholderWithItsValues(hubPath, content),
+ summary: summary ?? '',
+ language: language as Script['language'],
+ path: hubPath + '_fork'
+ }
+ } catch (err) {
+ script = defaultScript()
+ console.error('Error loading script from hub', err)
+ sendUserToast('Error loading script from hub: ' + err.message, true)
+ }
}
}
@@ -100,22 +128,26 @@
})
- {
- goto(`/scripts/get/${e.hash}?workspace=${$workspaceStore}`)
- }}
- onSaveInitial={(e) => {
- goto(`/scripts/edit/${e.path}`)
- }}
- searchParams={$page.url.searchParams}
- bind:script
- {showMeta}
- replaceStateFn={(path) => replaceState(path, $page.state)}
->
-
-
+{#if script}
+ {
+ goto(`/scripts/get/${e.hash}?workspace=${$workspaceStore}`)
+ }}
+ onSaveInitial={(e) => {
+ goto(`/scripts/edit/${e.path}`)
+ }}
+ searchParams={$page.url.searchParams}
+ bind:script
+ {showMeta}
+ replaceStateFn={(path) => replaceState(path, $page.state)}
+ >
+
+
+{:else}
+
+{/if}