diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 71f8cd193e..f7529a0ecd 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -33,6 +33,7 @@ "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^4.0.0", "openapi-typescript-codegen": "^0.23.0", + "path-browserify": "^1.0.1", "postcss": "^8.4.5", "postcss-load-config": "^4.0.1", "prettier": "^2.7.1", @@ -2886,6 +2887,12 @@ "tslib": "^2.0.3" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "node_modules/path-exists": { "version": "4.0.0", "dev": true, @@ -6585,6 +6592,12 @@ "tslib": "^2.0.3" } }, + "path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "path-exists": { "version": "4.0.0", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index 9f2e5cfca0..355dd332ca 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,6 +30,7 @@ "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^4.0.0", "openapi-typescript-codegen": "^0.23.0", + "path-browserify": "^1.0.1", "postcss": "^8.4.5", "postcss-load-config": "^4.0.1", "prettier": "^2.7.1", diff --git a/frontend/src/lib/components/EditorBar.svelte b/frontend/src/lib/components/EditorBar.svelte new file mode 100644 index 0000000000..d619947ac7 --- /dev/null +++ b/frontend/src/lib/components/EditorBar.svelte @@ -0,0 +1,213 @@ + + + + {@html github} + + + { + codeContent = ( + await ScriptService.getScriptByPath({ + workspace: $workspaceStore ?? '', + path + }) + ).content + codeViewer.openModal() + }} + closeOnClick={false} + itemName="script" + extraField="summary" + loadItems={loadScripts} +/> + + +
Code
+
+ {#if lang == 'python3'} + + {:else if lang == 'deno'} + + {/if} +
+ + { + if (!path) { + if (lang == 'deno') { + editor.insertAtCursor(`Deno.env.get('${name}')`) + } else { + if (!editor.getCode().includes('import os')) { + editor.insertAtBeginning('import os\n') + } + editor.insertAtCursor(`os.environ.get("${name}")`) + } + sendUserToast(`${name} inserted at cursor`) + } else { + if (lang == 'deno') { + if (!editor.getCode().includes('import * as wmill from')) { + editor.insertAtBeginning( + `import * as wmill from 'https://deno.land/x/windmill@v${__pkg__.version}/index.ts'\n` + ) + } + editor.insertAtCursor(`(await wmill.getVariable('${path}'))`) + } else { + if (!editor.getCode().includes('import wmill')) { + editor.insertAtBeginning('import wmill\n') + } + editor.insertAtCursor(`wmill.get_variable("${path}")`) + } + sendUserToast(`${name} inserted at cursor`) + } + }} + itemName="Variable" + extraField="name" + loadItems={loadVariables} +> +
+
+ The variable you were looking for does not exist yet? +
+ +
+
+ + { + if (lang == 'deno') { + if (!editor.getCode().includes('import * as wmill from')) { + editor.insertAtBeginning( + `import * as wmill from 'https://deno.land/x/windmill@v${__pkg__.version}/index.ts'\n` + ) + } + editor.insertAtCursor(`(await wmill.getResource('${path}'))`) + } else { + if (!editor.getCode().includes('import wmill')) { + editor.insertAtBeginning('import wmill\n') + } + editor.insertAtCursor(`wmill.get_resource("${path}")`) + } + sendUserToast(`${path} inserted at cursor`) + }} + itemName="Resource" + extraField="resource_type" + loadItems={async () => + await ResourceService.listResource({ workspace: $workspaceStore ?? 'NO_W' })} +> +
+
+ The resource you were looking for does not exist yet? +
+ +
+
+ + + + + +
+ + + + + + +
diff --git a/frontend/src/lib/components/ModuleStep.svelte b/frontend/src/lib/components/ModuleStep.svelte index c74d84db30..9aa6f490a3 100644 --- a/frontend/src/lib/components/ModuleStep.svelte +++ b/frontend/src/lib/components/ModuleStep.svelte @@ -5,6 +5,7 @@ import { faRobot } from '@fortawesome/free-solid-svg-icons' import Icon from 'svelte-awesome' import Editor from './Editor.svelte' + import EditorBar from './EditorBar.svelte' import FlowPreview from './FlowPreview.svelte' import FlowInputs from './flows/FlowInputs.svelte' import FlowModuleHeader from './flows/FlowModuleHeader.svelte' @@ -25,6 +26,9 @@ export let mod: FlowModule export let args: Record = {} + let editor: Editor + let websocketAlive = { pyright: false, black: false, deno: false } + $: schema = $schemasStore[i] $: shouldPick = mod.value.path === '' && mod.value.language === undefined $: previousSchema = i === 0 ? schemaToObject($flowStore?.schema) : $previewResults[i] @@ -78,7 +82,11 @@ /> {/if} {#if mod.value.type === FlowModuleValue.type.RAWSCRIPT} +
+ +
- import { - JobService, - Job, - CompletedJob, - VariableService, - ResourceService, - ScriptService - } from '$lib/gen' - import { sendUserToast, emptySchema, displayDate } from '$lib/utils' + import { JobService, Job, CompletedJob, VariableService, ScriptService } from '$lib/gen' + import { emptySchema, displayDate } from '$lib/utils' import type { Schema } from '$lib/common' import { fade } from 'svelte/transition' import Icon from 'svelte-awesome' @@ -17,7 +10,6 @@ faChevronUp, faExclamationTriangle, faMagic, - faSearch, faSpinner, faTimes } from '@fortawesome/free-solid-svg-icons' @@ -28,12 +20,7 @@ import TableCustom from './TableCustom.svelte' import { check } from 'svelte-awesome/icons' import Modal from './Modal.svelte' - import { Highlight } from 'svelte-highlight' - import { json, python, typescript } from 'svelte-highlight/languages' - import github from 'svelte-highlight/styles/github' - import ItemPicker from './ItemPicker.svelte' - import VariableEditor from './VariableEditor.svelte' - import ResourceEditor from './ResourceEditor.svelte' + import { inferArgs } from '$lib/infer' // @ts-ignore @@ -41,6 +28,9 @@ import SchemaForm from './SchemaForm.svelte' import DisplayResult from './DisplayResult.svelte' import type { Preview } from '$lib/gen/models/Preview' + import EditorBar from './EditorBar.svelte' + import { Highlight } from 'svelte-highlight' + import { json, python, typescript } from 'svelte-highlight/languages' // Exported export let schema: Schema = emptySchema() @@ -55,6 +45,10 @@ let websocketAlive = { pyright: false, black: false, deno: false } + let modalViewerTitle: string = '' + let modalViewerContent: any + let modalViewerMode: 'logs' | 'result' | 'code' = 'logs' + // Internal state let editor: Editor @@ -69,15 +63,6 @@ let pastPreviews: CompletedJob[] = [] let modalViewer: Modal - let modalViewerTitle: string = '' - let modalViewerContent: any - let modalViewerMode: 'logs' | 'result' | 'code' = 'logs' - - let variablePicker: ItemPicker - let resourcePicker: ItemPicker - let scriptPicker: ItemPicker - let variableEditor: VariableEditor - let resourceEditor: ResourceEditor let syncIteration: number = 0 let ITERATIONS_BEFORE_SLOW_REFRESH = 100 @@ -196,25 +181,6 @@ } } - async function loadVariables() { - let r: { name: string; path?: string; description?: string }[] = [] - const variables = ( - await VariableService.listVariable({ workspace: $workspaceStore ?? 'NO_W' }) - ).map((x) => { - return { name: x.path, ...x } - }) - - const rvariables = await VariableService.listContextualVariables({ - workspace: $workspaceStore ?? 'NO_W' - }) - r = r.concat(variables).concat(rvariables) - return r - } - - async function loadScripts(): Promise<{ path: string; summary?: string }[]> { - return await ScriptService.listScripts({ workspace: $workspaceStore ?? 'NO_W' }) - } - let syncCode: NodeJS.Timer onMount(() => { syncCode = setInterval(() => { @@ -237,29 +203,6 @@ }) - - {@html github} - - - { - modalViewerMode = 'code' - modalViewerTitle = 'Script ' + path - modalViewerContent = ( - await ScriptService.getScriptByPath({ - workspace: $workspaceStore ?? '', - path - }) - ).content - modalViewer.openModal() - }} - closeOnClick={false} - itemName="script" - extraField="summary" - loadItems={loadScripts} -/> -
{modalViewerTitle}
@@ -279,99 +222,6 @@
- { - if (!path) { - if (lang == 'deno') { - getEditor().insertAtCursor(`Deno.env.get('${name}')`) - } else { - if (!getEditor().getCode().includes('import os')) { - getEditor().insertAtBeginning('import os\n') - } - getEditor().insertAtCursor(`os.environ.get("${name}")`) - } - sendUserToast(`${name} inserted at cursor`) - } else { - if (lang == 'deno') { - if (!getEditor().getCode().includes('import * as wmill from')) { - getEditor().insertAtBeginning( - `import * as wmill from 'https://deno.land/x/windmill@v${__pkg__.version}/index.ts'\n` - ) - } - getEditor().insertAtCursor(`(await wmill.getVariable('${path}'))`) - } else { - if (!getEditor().getCode().includes('import wmill')) { - getEditor().insertAtBeginning('import wmill\n') - } - getEditor().insertAtCursor(`wmill.get_variable("${path}")`) - } - sendUserToast(`${name} inserted at cursor`) - } - }} - itemName="Variable" - extraField="name" - loadItems={loadVariables} -> -
-
- The variable you were looking for does not exist yet? -
- -
-
- - { - if (lang == 'deno') { - if (!getEditor().getCode().includes('import * as wmill from')) { - getEditor().insertAtBeginning( - `import * as wmill from 'https://deno.land/x/windmill@v${__pkg__.version}/index.ts'\n` - ) - } - getEditor().insertAtCursor(`(await wmill.getResource('${path}'))`) - } else { - if (!getEditor().getCode().includes('import wmill')) { - getEditor().insertAtBeginning('import wmill\n') - } - getEditor().insertAtCursor(`wmill.get_resource("${path}")`) - } - sendUserToast(`${path} inserted at cursor`) - }} - itemName="Resource" - extraField="resource_type" - loadItems={async () => - await ResourceService.listResource({ workspace: $workspaceStore ?? 'NO_W' })} -> -
-
- The resource you were looking for does not exist yet? -
- -
-
- - - - -
-
- - - - - - -
+
{ code = getEditor().getCode() localStorage.setItem(path ?? 'last_save', code) + lastSave = code }} class="h-full" deno={lang == 'deno'} diff --git a/frontend/src/routes/schedule/add.svelte b/frontend/src/routes/schedule/add.svelte index 7960663cb0..e41ce19422 100644 --- a/frontend/src/routes/schedule/add.svelte +++ b/frontend/src/routes/schedule/add.svelte @@ -183,7 +183,7 @@ {/if}

- ScheduleSchedules use CRON syntax. Milliseconds are mandatory. + ScheduleSchedules use CRON syntax. Milliseconds are mandatory.

{cronError}
diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 4ab84e7013..bffc736784 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -24,6 +24,11 @@ const config = { 'highlight.js/lib/core', ] }, + resolve: { + alias: { + path: "path-browserify", + }, + }, }; export default config;