Skip to content

Commit af3050f

Browse files
committed
all
1 parent b8e6d15 commit af3050f

File tree

4 files changed

+285
-39
lines changed

4 files changed

+285
-39
lines changed

frontend/src/lib/components/apps/editor/inlineScriptsPanel/RunButton.svelte

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
CancelablePromise,
77
InlineScript
88
} from '../../types'
9-
import { Button } from '$lib/components/common'
10-
import { CornerDownLeft, Loader2 } from 'lucide-svelte'
9+
10+
import RunButtonInner from './RunButtonInner.svelte'
1111
1212
export let id: string
1313
export let inlineScript: InlineScript | undefined = undefined
@@ -17,41 +17,20 @@
1717
const { runnableComponents } = getContext<AppViewerContext>('AppViewerContext')
1818
const { runnableJobEditorPanel } = getContext<AppEditorContext>('AppEditorContext')
1919
let cancelable: CancelablePromise<void>[] | undefined = undefined
20+
21+
const onRun = async () => {
22+
try {
23+
$runnableJobEditorPanel.focused = true
24+
cancelable = $runnableComponents[id]?.cb?.map((f) => f(inlineScript, true))
25+
await Promise.all(cancelable)
26+
} catch {}
27+
}
28+
29+
const onCancel = async () => {
30+
cancelable?.forEach((f) => f.cancel())
31+
}
2032
</script>
2133

2234
{#if runnableComponents && $runnableComponents[id] != undefined}
23-
{#if !runLoading}
24-
<Button
25-
loading={runLoading}
26-
size="xs"
27-
color="dark"
28-
btnClasses="!px-2 !py-1"
29-
on:click={async () => {
30-
runLoading = true
31-
$runnableJobEditorPanel.focused = true
32-
try {
33-
cancelable = $runnableComponents[id]?.cb?.map((f) => f(inlineScript, true))
34-
await Promise.all(cancelable)
35-
} catch {}
36-
runLoading = false
37-
}}
38-
shortCut={{ Icon: CornerDownLeft, hide: hideShortcut }}
39-
>
40-
Run
41-
</Button>
42-
{:else}
43-
<Button
44-
size="xs"
45-
color="red"
46-
variant="border"
47-
btnClasses="!px-2 !py-1.5"
48-
on:click={async () => {
49-
cancelable?.forEach((f) => f.cancel())
50-
runLoading = false
51-
}}
52-
>
53-
<Loader2 size={14} class="animate-spin mr-2" />
54-
Cancel
55-
</Button>
56-
{/if}
35+
<RunButtonInner bind:runLoading {hideShortcut} {onRun} {onCancel} />
5736
{/if}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<script lang="ts">
2+
import { Button } from '$lib/components/common'
3+
import { CornerDownLeft, Loader2 } from 'lucide-svelte'
4+
5+
export let runLoading = false
6+
export let hideShortcut = false
7+
export let onRun: () => Promise<void>
8+
export let onCancel: () => Promise<void>
9+
10+
</script>
11+
12+
{#if !runLoading}
13+
<Button
14+
loading={runLoading}
15+
size="xs"
16+
color="dark"
17+
btnClasses="!px-2 !py-1"
18+
on:click={async () => {
19+
runLoading = true
20+
await onRun()
21+
runLoading = false
22+
}}
23+
shortCut={{ Icon: CornerDownLeft, hide: hideShortcut }}
24+
>
25+
Run
26+
</Button>
27+
{:else}
28+
<Button
29+
size="xs"
30+
color="red"
31+
variant="border"
32+
btnClasses="!px-2 !py-1.5"
33+
on:click={async () => {
34+
await onCancel()
35+
runLoading = false
36+
}}
37+
>
38+
<Loader2 size={14} class="animate-spin mr-2" />
39+
Cancel
40+
</Button>
41+
{/if}

frontend/src/lib/components/raw_apps/RawAppInlineScripRunnable.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
import EmptyInlineScript from '../apps/editor/inlineScriptsPanel/EmptyInlineScript.svelte'
33
import InlineScriptRunnableByPath from '../apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte'
44
import type { RunnableWithFields, StaticAppInput } from '../apps/inputType'
5-
import InlineScriptEditor from '../apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte'
65
import { createEventDispatcher } from 'svelte'
6+
import RawAppInlineScriptEditor from './RawAppInlineScriptEditor.svelte'
77
88
export let runnable: RunnableWithFields | undefined
99
export let id: string
@@ -31,14 +31,14 @@
3131
{#if runnable.inlineScript.language == 'frontend'}
3232
<div class="text-sm text-tertiary">Frontend scripts not supported for raw apps</div>
3333
{:else}
34-
<InlineScriptEditor
34+
<RawAppInlineScriptEditor
3535
on:createScriptFromInlineScript={() => dispatch('createScriptFromInlineScript', runnable)}
3636
{id}
3737
bind:inlineScript={runnable.inlineScript}
3838
bind:name={runnable.name}
3939
bind:fields={runnable.fields}
40-
syncFields
4140
on:delete
41+
path={appPath}
4242
/>
4343
{/if}
4444
{:else if runnable?.type == 'runnableByPath'}
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
<script lang="ts">
2+
import Button from '$lib/components/common/button/Button.svelte'
3+
import type { Preview } from '$lib/gen'
4+
import { createEventDispatcher, onMount } from 'svelte'
5+
import { Maximize2, Trash2 } from 'lucide-svelte'
6+
import { inferArgs } from '$lib/infer'
7+
import type { Schema } from '$lib/common'
8+
import Editor from '$lib/components/Editor.svelte'
9+
import { emptySchema } from '$lib/utils'
10+
11+
import { scriptLangToEditorLang } from '$lib/scripts'
12+
import ScriptGen from '$lib/components/copilot/ScriptGen.svelte'
13+
import DiffEditor from '$lib/components/DiffEditor.svelte'
14+
import EditorSettings from '$lib/components/EditorSettings.svelte'
15+
import InlineScriptEditorDrawer from '../apps/editor/inlineScriptsPanel/InlineScriptEditorDrawer.svelte'
16+
import type { InlineScript } from '../apps/types'
17+
import type { AppInput } from '../apps/inputType'
18+
import CacheTtlPopup from '../apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte'
19+
import RunButtonInner from '../apps/editor/inlineScriptsPanel/RunButtonInner.svelte'
20+
21+
let inlineScriptEditorDrawer: InlineScriptEditorDrawer
22+
23+
export let inlineScript: InlineScript | undefined
24+
export let name: string | undefined = undefined
25+
export let id: string
26+
export let fields: Record<string, AppInput> = {}
27+
export let path: string
28+
29+
export let editor: Editor | undefined = undefined
30+
let diffEditor: DiffEditor
31+
let validCode = true
32+
33+
async function inferInlineScriptSchema(
34+
language: Preview['language'],
35+
content: string,
36+
schema: Schema
37+
): Promise<Schema> {
38+
try {
39+
await inferArgs(language, content, schema)
40+
validCode = true
41+
} catch (e) {
42+
console.error("Couldn't infer args", e)
43+
validCode = false
44+
}
45+
46+
return schema
47+
}
48+
49+
onMount(async () => {
50+
if (inlineScript && !inlineScript.schema) {
51+
if (inlineScript.language != 'frontend') {
52+
inlineScript.schema = await inferInlineScriptSchema(
53+
inlineScript?.language,
54+
inlineScript?.content,
55+
emptySchema()
56+
)
57+
}
58+
}
59+
})
60+
61+
const dispatch = createEventDispatcher()
62+
let runLoading = false
63+
64+
let drawerIsOpen: boolean | undefined = undefined
65+
66+
async function onRun() {
67+
console.log('onRun')
68+
}
69+
70+
async function onCancel() {
71+
console.log('onCancel')
72+
}
73+
</script>
74+
75+
{#if inlineScript}
76+
{#if inlineScript.language != 'frontend'}
77+
<InlineScriptEditorDrawer
78+
{id}
79+
appPath={path}
80+
bind:isOpen={drawerIsOpen}
81+
{editor}
82+
bind:this={inlineScriptEditorDrawer}
83+
bind:inlineScript
84+
on:createScriptFromInlineScript={() => {
85+
dispatch('createScriptFromInlineScript')
86+
drawerIsOpen = false
87+
}}
88+
/>
89+
{/if}
90+
<div class="h-full flex flex-col gap-1">
91+
<div class="flex justify-between w-full gap-2 px-2 pt-1 flex-row items-center">
92+
{#if name !== undefined}
93+
<div class="flex flex-row gap-2 w-full items-center">
94+
<input
95+
on:keydown|stopPropagation
96+
bind:value={name}
97+
placeholder="Inline script name"
98+
class="!text-xs !rounded-sm !shadow-none"
99+
on:keyup={() => {
100+
// $app = $app
101+
// if (stateId) {
102+
// $stateId++
103+
// }
104+
}}
105+
/>
106+
<div
107+
title={validCode ? 'Main function parsable' : 'Main function not parsable'}
108+
class="rounded-full !w-2 !h-2 {validCode ? 'bg-green-300' : 'bg-red-300'}"
109+
/>
110+
</div>
111+
{/if}
112+
<div class="flex w-full flex-row gap-1 items-center justify-end">
113+
{#if inlineScript}
114+
<CacheTtlPopup bind:cache_ttl={inlineScript.cache_ttl} />
115+
{/if}
116+
<ScriptGen
117+
lang={inlineScript?.language}
118+
{editor}
119+
{diffEditor}
120+
inlineScript
121+
args={Object.entries(fields).reduce((acc, [key, obj]) => {
122+
acc[key] = obj.type === 'static' ? obj.value : undefined
123+
return acc
124+
}, {})}
125+
/>
126+
<EditorSettings />
127+
128+
<Button
129+
title="Delete"
130+
size="xs2"
131+
color="light"
132+
variant="contained"
133+
aria-label="Delete"
134+
on:click={() => dispatch('delete')}
135+
endIcon={{ icon: Trash2 }}
136+
iconOnly
137+
/>
138+
{#if inlineScript.language != 'frontend'}
139+
<Button
140+
size="xs2"
141+
color="light"
142+
title="Full Editor"
143+
variant="contained"
144+
on:click={() => {
145+
inlineScriptEditorDrawer?.openDrawer()
146+
}}
147+
endIcon={{ icon: Maximize2 }}
148+
iconOnly
149+
/>
150+
{/if}
151+
152+
<Button
153+
variant="border"
154+
size="xs2"
155+
color="light"
156+
on:click={async () => {
157+
editor?.format()
158+
}}
159+
shortCut={{
160+
key: 'S'
161+
}}
162+
>
163+
Format
164+
</Button>
165+
<RunButtonInner {onRun} {onCancel} />
166+
</div>
167+
</div>
168+
169+
<!-- {inlineScript.content} -->
170+
171+
<div class="border-y h-full w-full">
172+
{#if !drawerIsOpen && inlineScript.language != 'frontend'}
173+
<Editor
174+
path={path + '/' + id}
175+
bind:this={editor}
176+
small
177+
class="flex flex-1 grow h-full"
178+
scriptLang={inlineScript.language}
179+
bind:code={inlineScript.content}
180+
fixedOverflowWidgets={true}
181+
cmdEnterAction={async () => {
182+
if (inlineScript) {
183+
inlineScript.content = editor?.getCode() ?? ''
184+
}
185+
try {
186+
runLoading = true
187+
// await Promise.all(
188+
// $runnableComponents[id]?.cb?.map((f) => f?.(inlineScript, true)) ?? []
189+
// )
190+
} catch {}
191+
runLoading = false
192+
}}
193+
on:change={async (e) => {
194+
if (inlineScript && inlineScript.language != 'frontend') {
195+
if (inlineScript.lock != undefined) {
196+
inlineScript.lock = undefined
197+
}
198+
const oldSchema = JSON.stringify(inlineScript.schema)
199+
if (inlineScript.schema == undefined) {
200+
inlineScript.schema = emptySchema()
201+
}
202+
await inferInlineScriptSchema(inlineScript?.language, e.detail, inlineScript.schema)
203+
if (JSON.stringify(inlineScript.schema) != oldSchema) {
204+
inlineScript = inlineScript
205+
}
206+
}
207+
// $app = $app
208+
}}
209+
args={Object.entries(fields).reduce((acc, [key, obj]) => {
210+
acc[key] = obj.type === 'static' ? obj.value : undefined
211+
return acc
212+
}, {})}
213+
/>
214+
215+
<DiffEditor
216+
open={false}
217+
bind:this={diffEditor}
218+
class="h-full"
219+
automaticLayout
220+
fixedOverflowWidgets
221+
defaultLang={scriptLangToEditorLang(inlineScript?.language)}
222+
/>
223+
{/if}
224+
</div>
225+
</div>
226+
{/if}

0 commit comments

Comments
 (0)