This commit is contained in:
Ruben Fiszel
2023-02-07 19:13:56 +01:00
parent 3f8916cbc2
commit 56dd32b2f0
28 changed files with 4299 additions and 138 deletions
+1778
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
+840
View File
@@ -0,0 +1,840 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte + TS</title>
<link href="dist/style.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<script src="/dist/appviewer.iife.js">
</script>
<script src="/static/tailwind.js">
</script>
<script>
loadApp(document.getElementById("app"), {
"grid": [
{
"3": {
"h": 2,
"w": 1,
"x": 0,
"y": 0,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 5,
"w": 3,
"x": 0,
"y": 0,
"id": "a",
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "a",
"data": {
"id": "a",
"card": false,
"type": "htmlcomponent",
"softWrap": false,
"configuration": {},
"componentInput": {
"eval": "<img\n\tsrc=\"https://images.unsplash.com/photo-1554629947-334ff61d85dc?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;ixlib=rb-1.2.1&amp;auto=format&amp;fit=crop&amp;w=1024&amp;h=1280&amp;q=80\"\n>\n<div class=\"absolute top-4 left-2 text-white\">\n\tHello ${ctx.username}\n</div>\t\t\t\n",
"type": "template",
"value": "<img\n\tsrc=\"https://images.unsplash.com/photo-1554629947-334ff61d85dc?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;ixlib=rb-1.2.1&amp;auto=format&amp;fit=crop&amp;w=1024&amp;h=1280&amp;q=80\"\n>\n<div class=\"absolute top-4 left-2 text-white\">\n\tHello ${ctx.username}\n</div>\t\t\t\n",
"fieldType": "template"
}
}
},
{
"3": {
"h": 10,
"w": 3,
"x": 0,
"y": 2,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 10,
"w": 6,
"x": 3,
"y": 0,
"id": "b",
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "b",
"data": {
"id": "b",
"card": true,
"type": "tablecomponent",
"actionButtons": [],
"configuration": {
"search": {
"type": "static",
"value": "Disabled",
"fieldType": "select",
"onlyStatic": true,
"optionValuesKey": "tableSearchOptions"
}
},
"componentInput": {
"type": "static",
"value": [
{
"id": 1,
"age": 42,
"name": "A cell with a long name"
},
{
"id": 2,
"age": 84,
"name": "A briefer cell"
}
],
"fieldType": "array",
"subFieldType": "object"
}
}
},
{
"3": {
"h": 8,
"w": 2,
"x": 0,
"y": 12,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 8,
"w": 6,
"x": 0,
"y": 10,
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "c",
"data": {
"id": "c",
"card": true,
"type": "scatterchartcomponent",
"configuration": {
"pannable": {
"type": "static",
"value": false,
"fieldType": "boolean",
"onlyStatic": true
},
"zoomable": {
"type": "static",
"value": false,
"fieldType": "boolean",
"onlyStatic": true
}
},
"componentInput": {
"type": "static",
"value": [
{
"data": [
{
"x": 25,
"y": 50
},
{
"x": 23,
"y": 23
},
{
"x": 12,
"y": 37
}
],
"label": "foo",
"backgroundColor": "rgb(255, 12, 137)"
},
{
"data": [
{
"x": 32,
"y": 32
},
{
"x": 25,
"y": 42
},
{
"x": 3,
"y": 27
}
],
"label": "foobar",
"backgroundColor": "orange"
}
],
"fieldType": "array",
"subFieldType": "object"
}
}
},
{
"3": {
"h": 8,
"w": 2,
"x": 0,
"y": 20,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 8,
"w": 6,
"x": 6,
"y": 10,
"id": "d",
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "d",
"data": {
"id": "d",
"card": false,
"type": "displaycomponent",
"configuration": {},
"componentInput": {
"type": "connected",
"value": {
"foo": 42
},
"fields": {
"x": {
"type": "connected",
"value": "gooo",
"visible": true,
"fieldType": "string",
"connection": {
"path": "result",
"componentId": "e"
}
}
},
"runnable": {
"name": "Inline Script 1",
"type": "runnableByName",
"inlineScript": {
"path": "/inline-script/Inline Script 1",
"schema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"x"
],
"properties": {
"x": {
"type": "string",
"default": null,
"description": ""
}
}
},
"content": "// import * as wmill from \"https://deno.land/x/windmill@v1.57.1/mod.ts\"\n\nexport async function main(x: string) {\n return x\n}\n",
"language": "deno"
}
},
"fieldType": "object",
"connection": {
"path": "result",
"componentId": "e"
}
}
}
},
{
"3": {
"h": 1,
"w": 2,
"x": 1,
"y": 0,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 1,
"w": 3,
"x": 9,
"y": 0,
"id": "e",
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "e",
"data": {
"id": "e",
"card": false,
"type": "textinputcomponent",
"softWrap": true,
"configuration": {
"placeholder": {
"type": "static",
"value": "Type...",
"fieldType": "text",
"onlyStatic": true
}
},
"verticalAlignment": "center"
}
},
{
"3": {
"h": 1,
"w": 2,
"x": 1,
"y": 1,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 1,
"w": 3,
"x": 9,
"y": 1,
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "f",
"data": {
"id": "f",
"card": false,
"type": "passwordinputcomponent",
"softWrap": true,
"configuration": {
"placeholder": {
"type": "static",
"value": "Password",
"fieldType": "text",
"onlyStatic": true
}
},
"verticalAlignment": "center"
}
},
{
"3": {
"h": 1,
"w": 2,
"x": 0,
"y": 28,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 1,
"w": 3,
"x": 9,
"y": 2,
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "g",
"data": {
"id": "g",
"card": false,
"type": "dateinputcomponent",
"softWrap": true,
"configuration": {
"maxDate": {
"type": "static",
"value": "",
"fieldType": "date"
},
"minDate": {
"type": "static",
"value": "",
"fieldType": "date"
}
},
"verticalAlignment": "center"
}
},
{
"3": {
"h": 1,
"w": 1,
"x": 2,
"y": 12,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 1,
"w": 2,
"x": 9,
"y": 3,
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "h",
"data": {
"id": "h",
"card": false,
"type": "checkboxcomponent",
"softWrap": true,
"configuration": {
"label": {
"type": "static",
"value": "Label",
"fieldType": "text"
}
},
"verticalAlignment": "center",
"horizontalAlignment": "center"
}
},
{
"3": {
"h": 1,
"w": 2,
"x": 0,
"y": 29,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 1,
"w": 3,
"x": 9,
"y": 4,
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "i",
"data": {
"id": "i",
"card": false,
"type": "selectcomponent",
"softWrap": true,
"configuration": {
"items": {
"type": "static",
"value": [
{
"label": "Foo",
"value": "foo"
},
{
"label": "Bar",
"value": "bar"
}
],
"fieldType": "array",
"subFieldType": "object"
},
"itemKey": {
"type": "static",
"value": "value",
"fieldType": "text"
}
},
"verticalAlignment": "center"
}
},
{
"3": {
"h": 1,
"w": 1,
"x": 2,
"y": 13,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 1,
"w": 2,
"x": 0,
"y": 5,
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "j",
"data": {
"id": "j",
"card": false,
"type": "buttoncomponent",
"softWrap": true,
"configuration": {
"size": {
"type": "static",
"value": "xs",
"fieldType": "select",
"onlyStatic": true,
"optionValuesKey": "buttonSizeOptions"
},
"color": {
"type": "static",
"value": "blue",
"fieldType": "select",
"onlyStatic": true,
"optionValuesKey": "buttonColorOptions"
},
"label": {
"type": "static",
"value": "Press me",
"fieldType": "text"
}
},
"componentInput": {
"type": "runnable",
"fields": {},
"fieldType": "any"
},
"verticalAlignment": "center",
"horizontalAlignment": "center"
}
},
{
"3": {
"h": 5,
"w": 3,
"x": 0,
"y": 30,
"max": {
"h": 100,
"w": 3
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"12": {
"h": 5,
"w": 6,
"x": 0,
"y": 18,
"id": "k",
"max": {
"h": 100,
"w": 12
},
"min": {
"h": 1,
"w": 1
},
"fixed": false,
"draggable": true,
"resizable": true,
"customDragger": false,
"customResizer": false
},
"id": "k",
"data": {
"id": "k",
"card": true,
"type": "formcomponent",
"configuration": {
"size": {
"type": "static",
"value": "xs",
"fieldType": "select",
"onlyStatic": true,
"optionValuesKey": "buttonSizeOptions"
},
"color": {
"type": "static",
"value": "dark",
"fieldType": "select",
"onlyStatic": true,
"optionValuesKey": "buttonColorOptions"
},
"label": {
"type": "static",
"value": "Submit",
"fieldType": "text"
}
},
"componentInput": {
"type": "runnable",
"fields": {
"x": {
"type": "user",
"value": null,
"visible": true,
"fieldType": "string"
},
"y": {
"type": "user",
"value": null,
"visible": true,
"fieldType": "string"
}
},
"runnable": {
"name": "Inline Script 0",
"type": "runnableByName",
"inlineScript": {
"path": "/inline-script/Inline Script 0",
"schema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"x",
"y"
],
"properties": {
"x": {
"type": "string",
"default": null,
"description": ""
},
"y": {
"type": "string",
"default": null,
"description": ""
}
}
},
"content": "// import * as wmill from \"https://deno.land/x/windmill@v1.57.1/mod.ts\"\n\nexport async function main(x: string, y: string) {\n return x\n}\n",
"language": "deno"
}
},
"fieldType": "any"
},
"horizontalAlignment": "center"
}
}
],
"fullscreen": false,
"unusedInlineScripts": []
})
</script>
</body>
</html>
+689 -21
View File
File diff suppressed because it is too large Load Diff
+11 -4
View File
@@ -16,6 +16,11 @@
},
"devDependencies": {
"@playwright/test": "^1.29.2",
"@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-html": "^1.0.2",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-terser": "^0.4.0",
"@rollup/plugin-typescript": "^11.0.0",
"@sveltejs/adapter-static": "^1.0.0",
"@sveltejs/kit": "^1.0.0-next.589",
"@sveltejs/package": "^1.0.2",
@@ -34,15 +39,17 @@
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-svelte3": "^4.0.0",
"lucide-svelte": "^0.104.0",
"monaco-editor-workers": "0.33.0",
"openapi-typescript-codegen": "^0.23.0",
"path-browserify": "^1.0.1",
"postcss": "^8.4.18",
"postcss-load-config": "^4.0.1",
"prettier": "^2.8.3",
"prettier-plugin-svelte": "^2.9.0",
"rollup-plugin-svelte": "^7.1.0",
"simple-svelte-autocomplete": "^2.5.1",
"stylelint-config-recommended": "^9.0.0",
"svelte": "^3.53.1",
"svelte": "^3.55.1",
"svelte-awesome": "^3.0.0",
"svelte-check": "^3.0.2",
"svelte-dnd-action": "^0.9.22",
@@ -67,12 +74,11 @@
"@redocly/json-to-json-schema": "^0.0.1",
"@tanstack/svelte-table": "^8.7.6",
"async-mutex": "^0.4.0",
"chart.js": "3.8.2",
"chartjs-adapter-date-fns": "^3.0.0",
"chartjs-plugin-zoom": "^2.0.0",
"date-fns": "^2.29.3",
"highlight.js": "^11.7.0",
"monaco-editor": "0.33.0",
"monaco-editor-workers": "0.33.0",
"monaco-languageclient": "2.1.0",
"monaco-yaml": "^4.0.2",
"svelte-autosize": "^1.0.1",
@@ -83,5 +89,6 @@
},
"peerDependencies": {
"svelte": "^3.53.1"
}
},
"main": "index.js"
}
+42
View File
@@ -0,0 +1,42 @@
import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
import svelte from 'rollup-plugin-svelte'
import terser from '@rollup/plugin-terser'
import sveltePreprocess from 'svelte-preprocess'
const production = !process.env.ROLLUP_WATCH
export default {
// The file we created with our web component wrapper.
input: 'src/embed.js',
output: {
sourcemap: !production,
format: 'iife',
name: 'app',
// We output it to public. This way, our svelte kit
// app will also host the web components.
file: 'build/app.js'
},
// Normal rollup svelte configuration. Nothing fancy
// happening here.
plugins: [
typescript(),
svelte({
preprocess: sveltePreprocess({
sourceMap: !production,
postcss: true
}),
// We just make sure that no global CSS is injeced
// into the page that imports this script.
emitCss: false,
compilerOptions: {
dev: !production
// customElement: true,
}
}),
resolve({ browser: true, dedupe: ['svelte'] }),
commonjs()
]
}
+9
View File
@@ -0,0 +1,9 @@
import AppPreview from './lib/components/apps/editor/AppPreview.svelte'
globalThis.process = { env: { NODE_ENV: 'production' } }
globalThis.loadApp = (target, value) => {
new AppPreview({
target: target,
props: { app: value }
})
}
@@ -1,8 +1,6 @@
<script lang="ts">
import { truncate } from '$lib/utils'
import Tooltip from './Tooltip.svelte'
import json from 'svelte-highlight/languages/json'
import { Highlight } from 'svelte-highlight'
import { ResourceService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import Drawer from './common/drawer/Drawer.svelte'
+9 -8
View File
@@ -19,7 +19,6 @@
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
import { buildWorkerDefinition } from 'monaco-editor-workers'
import type {
Disposable,
DocumentUri,
@@ -90,13 +89,7 @@
const uri = `file:///tmp/monaco/${hash}.${langToExt(lang)}`
if (browser) {
if (dev) {
buildWorkerDefinition(
'../../../node_modules/monaco-editor-workers/dist/workers',
import.meta.url,
false
)
} else {
if (!dev) {
// @ts-ignore
self.MonacoEnvironment = {
getWorker: function (_moduleId: any, label: string) {
@@ -408,6 +401,14 @@
}
async function loadMonaco() {
if (dev) {
let { buildWorkerDefinition } = await import('monaco-editor-workers')
buildWorkerDefinition(
'../../../node_modules/monaco-editor-workers/dist/workers',
import.meta.url,
false
)
}
const model = meditor.createModel(code, lang, mUri.parse(uri))
model.updateOptions(updateOptions)
@@ -8,7 +8,6 @@
import DynamicInputHelpBox from './flows/content/DynamicInputHelpBox.svelte'
import type { PropPickerWrapperContext } from './flows/propPicker/PropPickerWrapper.svelte'
import { codeToStaticTemplate, getDefaultExpr, isCodeInjection } from './flows/utils'
import SimpleEditor from './SimpleEditor.svelte'
import { Button, ToggleButton, ToggleButtonGroup } from './common'
import { faCode } from '@fortawesome/free-solid-svg-icons'
import type VariableEditor from './VariableEditor.svelte'
@@ -17,6 +16,7 @@
import TemplateEditor from './TemplateEditor.svelte'
import Tooltip from './Tooltip.svelte'
import { setInputCat as computeInputCat } from '$lib/utils'
import JavascriptEditor from './JavascriptEditor.svelte'
export let schema: Schema
export let arg: InputTransform | any
@@ -29,7 +29,7 @@
export let itemPicker: ItemPicker | undefined = undefined
export let noDynamicToggle = false
let monaco: SimpleEditor | undefined = undefined
let monaco: JavascriptEditor | undefined = undefined
let monacoTemplate: TemplateEditor | undefined = undefined
let argInput: ArgInput | undefined = undefined
@@ -284,7 +284,7 @@
/>
{:else if arg.expr != undefined}
<div class="border rounded mt-2 border-gray-300">
<SimpleEditor
<JavascriptEditor
bind:this={monaco}
bind:code={arg.expr}
{extraLib}
@@ -0,0 +1,212 @@
<script lang="ts">
import { browser, dev } from '$app/environment'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
import { createHash, editorConfig, langToExt, updateOptions } from '$lib/editorUtils'
import { languages, editor as meditor, KeyCode, KeyMod, Uri as mUri } from 'monaco-editor'
import libStdContent from '$lib/es5.d.ts.txt?raw'
meditor.defineTheme('myTheme', {
base: 'vs',
inherit: true,
rules: [],
colors: {
'editorLineNumber.foreground': '#999',
'editorGutter.background': '#F9FAFB'
}
})
meditor.setTheme('myTheme')
languages.typescript.javascriptDefaults.setCompilerOptions({
target: languages.typescript.ScriptTarget.Latest,
allowNonTsExtensions: true,
noLib: true
})
let divEl: HTMLDivElement | null = null
let editor: meditor.IStandaloneCodeEditor
let model: meditor.ITextModel
export let lang: string
export let code: string = ''
export let hash: string = createHash()
export let cmdEnterAction: (() => void) | undefined = undefined
export let formatAction: (() => void) | undefined = undefined
export let automaticLayout = true
export let extraLib: string = ''
export let shouldBindKey: boolean = true
export let autoHeight = false
export let fixedOverflowWidgets = true
const dispatch = createEventDispatcher()
const uri = `file:///${hash}.${langToExt(lang)}`
if (browser) {
if (!dev) {
// @ts-ignore
self.MonacoEnvironment = {
getWorker: function (_moduleId: any, label: string) {
if (label === 'typescript' || label === 'javascript') {
return new tsWorker()
} else {
return new editorWorker()
}
}
}
}
}
export function getCode(): string {
return editor?.getValue() ?? ''
}
export function insertAtCursor(code: string): void {
if (editor) {
editor.trigger('keyboard', 'type', { text: code })
}
}
export function setCode(ncode: string): void {
code = ncode
if (editor) {
editor.setValue(ncode)
}
}
function format() {
if (editor) {
code = getCode()
editor.getAction('editor.action.formatDocument').run()
if (formatAction) {
formatAction()
code = getCode()
}
}
}
let width = 0
async function loadMonaco() {
if (dev) {
let { buildWorkerDefinition } = await import('monaco-editor-workers')
buildWorkerDefinition(
'../../../node_modules/monaco-editor-workers/dist/workers',
import.meta.url,
false
)
}
model = meditor.createModel(code, lang, mUri.parse(uri))
model.updateOptions(updateOptions)
editor = meditor.create(
divEl as HTMLDivElement,
editorConfig(model, code, lang, automaticLayout, fixedOverflowWidgets)
)
let timeoutModel: NodeJS.Timeout | undefined = undefined
editor.onDidChangeModelContent((event) => {
timeoutModel && clearTimeout(timeoutModel)
timeoutModel = setTimeout(() => {
code = getCode()
dispatch('change', { code })
}, 200)
})
editor.onDidFocusEditorText(() => {
dispatch('focus')
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyS, function () {
code = getCode()
shouldBindKey && format && format()
})
})
if (autoHeight) {
let ignoreEvent = false
const updateHeight = () => {
const contentHeight = Math.min(1000, editor.getContentHeight())
if (divEl) {
divEl.style.height = `${contentHeight}px`
}
try {
ignoreEvent = true
editor.layout({ width, height: contentHeight })
} finally {
ignoreEvent = false
}
}
editor.onDidContentSizeChange(updateHeight)
updateHeight()
}
editor.onDidFocusEditorText(() => {
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyS, function () {
code = getCode()
shouldBindKey && format && format()
})
editor.addCommand(KeyMod.CtrlCmd | KeyCode.Enter, function () {
code = getCode()
shouldBindKey && cmdEnterAction && cmdEnterAction()
})
dispatch('focus')
})
editor.onDidBlurEditorText(() => {
code = getCode()
dispatch('blur')
})
if (lang == 'javascript') {
const stdLib = { content: libStdContent, filePath: 'es5.d.ts' }
if (extraLib != '') {
languages.typescript.javascriptDefaults.setExtraLibs([
{
content: extraLib,
filePath: 'windmill.d.ts'
},
stdLib
])
} else {
languages.typescript.javascriptDefaults.setExtraLibs([stdLib])
}
}
}
onMount(() => {
if (browser) {
loadMonaco()
}
})
onDestroy(() => {
try {
model && model.dispose()
editor && editor.dispose()
} catch (err) {}
})
</script>
<div bind:this={divEl} class="{$$props.class} editor" bind:clientWidth={width} />
<style>
.editor {
@apply rounded-lg p-0;
}
.small-editor {
/* stylelint-disable-next-line unit-allowed-list */
height: 26vh;
}
.few-lines-editor {
/* stylelint-disable-next-line unit-allowed-list */
height: 100px;
}
</style>
+2 -24
View File
@@ -7,11 +7,9 @@
import { slide } from 'svelte/transition'
import ArgInput from './ArgInput.svelte'
import { Button } from './common'
import InputTransformForm from './InputTransformForm.svelte'
import ItemPicker from './ItemPicker.svelte'
import VariableEditor from './VariableEditor.svelte'
export let inputTransform = false
export let schema: Schema
export let args: Record<string, InputTransform | any> = {}
export let disabledArgs: string[] = []
@@ -19,16 +17,13 @@
export let editableSchema = false
export let isValid: boolean = true
export let extraLib: string = 'missing extraLib'
export let autofocus = false
export let previousModuleId: string | undefined = undefined
export let shouldHideNoInputs: boolean = false
export let compact = false
export let password: string | undefined = undefined
export let noVariablePicker = false
export let filter: string[] | undefined = undefined
export let noDynamicToggle = false
export let flexWrap = false
export let noDelete = false
@@ -71,20 +66,7 @@
{#each keys as argName, i (argName)}
{#if !filter || filter.includes(argName)}
<div transition:slide|local>
{#if inputTransform}
<InputTransformForm
{previousModuleId}
bind:arg={args[argName]}
bind:schema
bind:argName
bind:inputCheck={inputCheck[argName]}
bind:extraLib
{variableEditor}
{itemPicker}
bind:pickForField
{noDynamicToggle}
/>
{:else if typeof args == 'object'}
{#if typeof args == 'object'}
<ArgInput
autofocus={i == 0 && autofocus}
label={argName}
@@ -125,11 +107,7 @@
bind:this={itemPicker}
pickCallback={(path, _) => {
if (pickForField) {
if (inputTransform) {
args[pickForField].value = '$var:' + path
} else {
args[pickForField] = '$var:' + path
}
args[pickForField] = '$var:' + path
}
}}
itemName="Variable"
@@ -0,0 +1,120 @@
<script lang="ts">
import type { Schema } from '$lib/common'
import { VariableService, type InputTransform } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import { allTrue } from '$lib/utils'
import { faPlus } from '@fortawesome/free-solid-svg-icons'
import { slide } from 'svelte/transition'
import { Button } from './common'
import InputTransformForm from './InputTransformForm.svelte'
import ItemPicker from './ItemPicker.svelte'
import VariableEditor from './VariableEditor.svelte'
export let schema: Schema
export let args: Record<string, InputTransform | any> = {}
export let isValid: boolean = true
export let extraLib: string = 'missing extraLib'
export let previousModuleId: string | undefined = undefined
export let shouldHideNoInputs: boolean = false
export let noVariablePicker = false
export let filter: string[] | undefined = undefined
export let noDynamicToggle = false
export let flexWrap = false
export let noDelete = false
let clazz: string = ''
export { clazz as class }
let inputCheck: { [id: string]: boolean } = {}
$: isValid = allTrue(inputCheck) ?? false
$: if (args == undefined || typeof args !== 'object') {
args = {}
}
function removeExtraKey() {
Object.keys(args ?? {}).forEach((key) => {
if (!keys.includes(key)) {
delete args[key]
delete inputCheck[key]
}
})
}
let pickForField: string | undefined
let itemPicker: ItemPicker | undefined = undefined
let variableEditor: VariableEditor | undefined = undefined
let keys: string[] = []
$: {
let lkeys = Object.keys(schema?.properties ?? {})
if (schema?.properties && JSON.stringify(lkeys) != JSON.stringify(keys)) {
keys = lkeys
if (!noDelete) {
removeExtraKey()
}
}
}
</script>
<div class="w-full {clazz} {flexWrap ? 'flex flex-row flex-wrap gap-x-6 gap-y-2' : ''}">
{#if keys.length > 0}
{#each keys as argName, i (argName)}
{#if !filter || filter.includes(argName)}
<div transition:slide|local>
<InputTransformForm
{previousModuleId}
bind:arg={args[argName]}
bind:schema
bind:argName
bind:inputCheck={inputCheck[argName]}
bind:extraLib
{variableEditor}
{itemPicker}
bind:pickForField
{noDynamicToggle}
/>
</div>
{/if}
{/each}
{:else if !shouldHideNoInputs}
<div class="text-gray-500 text-sm">No inputs</div>
{/if}
</div>
{#if !noVariablePicker}
<ItemPicker
bind:this={itemPicker}
pickCallback={(path, _) => {
if (pickForField) {
args[pickForField].value = '$var:' + path
}
}}
itemName="Variable"
extraField="path"
loadItems={async () =>
(await VariableService.listVariable({ workspace: $workspaceStore ?? '' })).map((x) => ({
name: x.path,
...x
}))}
>
<div
slot="submission"
class="flex flex-row-reverse w-full bg-white border-t border-gray-200 rounded-bl-lg rounded-br-lg"
>
<Button
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faPlus }}
on:click={() => {
variableEditor?.initNew?.()
}}
>
New variable
</Button>
</div>
</ItemPicker>
<VariableEditor bind:this={variableEditor} />
{/if}
@@ -4,15 +4,16 @@
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import yamlWorker from 'monaco-yaml/yaml.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
import { buildWorkerDefinition } from 'monaco-editor-workers'
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
import { createHash, editorConfig, langToExt, updateOptions } from '$lib/editorUtils'
import { languages, editor as meditor, KeyCode, KeyMod, Uri as mUri } from 'monaco-editor'
import libStdContent from '$lib/es5.d.ts.txt?raw'
import {
languages,
editor as meditor,
KeyCode,
KeyMod,
Uri as mUri
} from 'monaco-editor/esm/vs/editor/editor.main'
meditor.defineTheme('myTheme', {
base: 'vs',
@@ -25,12 +26,6 @@
})
meditor.setTheme('myTheme')
languages.typescript.javascriptDefaults.setCompilerOptions({
target: languages.typescript.ScriptTarget.Latest,
allowNonTsExtensions: true,
noLib: true
})
languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
allowComments: false,
@@ -48,7 +43,6 @@
export let cmdEnterAction: (() => void) | undefined = undefined
export let formatAction: (() => void) | undefined = undefined
export let automaticLayout = true
export let extraLib: string = ''
export let shouldBindKey: boolean = true
export let autoHeight = false
export let fixedOverflowWidgets = true
@@ -58,13 +52,7 @@
const uri = `file:///${hash}.${langToExt(lang)}`
if (browser) {
if (dev) {
buildWorkerDefinition(
'../../../node_modules/monaco-editor-workers/dist/workers',
import.meta.url,
false
)
} else {
if (!dev) {
// @ts-ignore
self.MonacoEnvironment = {
getWorker: function (_moduleId: any, label: string) {
@@ -72,8 +60,6 @@
return new jsonWorker()
} else if (label === 'yaml') {
return new yamlWorker()
} else if (label === 'typescript' || label === 'javascript') {
return new tsWorker()
} else {
return new editorWorker()
}
@@ -174,21 +160,6 @@
code = getCode()
dispatch('blur')
})
if (lang == 'javascript') {
const stdLib = { content: libStdContent, filePath: 'es5.d.ts' }
if (extraLib != '') {
languages.typescript.javascriptDefaults.setExtraLibs([
{
content: extraLib,
filePath: 'windmill.d.ts'
},
stdLib
])
} else {
languages.typescript.javascriptDefaults.setExtraLibs([stdLib])
}
}
}
onMount(() => {
@@ -12,19 +12,24 @@
EditorMode
} from '../types'
import GridEditor from './GridEditor.svelte'
import { classNames } from '$lib/utils'
import { classNames } from '../../../utils'
import type { Policy } from '$lib/gen'
import Button from '../../common/button/Button.svelte'
import { Unlock } from 'lucide-svelte'
export let app: App
export let appPath: string
export let breakpoint: Writable<EditorBreakpoint>
export let policy: Policy
export let summary: string
export let workspace: string
export let isEditor: boolean
export let context: Record<string, any>
export let app: App = {
grid: [],
fullscreen: false,
unusedInlineScripts: [],
hiddenInlineScripts: []
}
export let appPath: string = ''
export let breakpoint: Writable<EditorBreakpoint> = writable('lg')
export let policy: Policy = {}
export let summary: string = ''
export let workspace: string = 'workspace'
export let isEditor: boolean = false
export let context: Record<string, any> = {}
export let noBackend: boolean = false
export let isLocked = false
@@ -3,8 +3,8 @@
import { getContext } from 'svelte'
import type { AppEditorContext } from '$lib/components/apps/types'
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
import { buildExtraLib } from '$lib/components/apps/utils'
import JavascriptEditor from '$lib/components/JavascriptEditor.svelte'
export let componentInput: EvalAppInput | undefined
export let id: string
@@ -22,7 +22,7 @@
{#if componentInput?.type === 'eval'}
<div class="border border-gray-300 ">
<SimpleEditor
<JavascriptEditor
lang="javascript"
bind:code={componentInput.expr}
shouldBindKey={false}
@@ -1,9 +1,9 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { classNames } from '$lib/utils'
import { classNames } from '../../../utils'
import Icon from 'svelte-awesome'
import { ButtonType } from './model'
import { goto } from '$app/navigation'
// import { goto } from '$app/navigation'
import { Loader2 } from 'lucide-svelte'
export let size: ButtonType.Size = 'md'
@@ -93,7 +93,7 @@
window.open(href, target)
} else {
loading = true
await goto(href)
// await goto(href)
loading = false
}
}
@@ -3,11 +3,11 @@
import { getContext } from 'svelte'
import { flowStore } from '../flowStore'
import PropPickerWrapper from '../propPicker/PropPickerWrapper.svelte'
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
import { flowStateStore } from '../flowState'
import { getStepPropPicker } from '../previousResults'
import type { FlowEditorContext } from '../types'
import JavascriptEditor from '$lib/components/JavascriptEditor.svelte'
export let branch: {
summary?: string
@@ -18,7 +18,7 @@
export let previousModule: FlowModule | undefined
const { previewArgs } = getContext<FlowEditorContext>('FlowEditorContext')
let editor: SimpleEditor | undefined = undefined
let editor: JavascriptEditor | undefined = undefined
$: stepPropPicker = getStepPropPicker(
$flowStateStore,
@@ -40,7 +40,7 @@
}}
>
<div class="border border-gray-400">
<SimpleEditor
<JavascriptEditor
bind:this={editor}
lang="javascript"
bind:code={branch.expr}
@@ -3,13 +3,13 @@
import FlowCard from '../common/FlowCard.svelte'
import { Alert, Badge } from '$lib/components/common'
import type { FlowModule, FlowModuleValue, InputTransform, PathScript, RawScript } from '$lib/gen'
import SchemaForm from '$lib/components/SchemaForm.svelte'
import { flowStateStore } from '../flowState'
import { setContext } from 'svelte'
import type { PropPickerWrapperContext } from '../propPicker/PropPickerWrapper.svelte'
import { writable } from 'svelte/store'
import { slide } from 'svelte/transition'
import Toggle from '../../Toggle.svelte'
import SchemaFormTransform from '$lib/components/SchemaFormTransform.svelte'
let hideOptional = false
@@ -37,7 +37,7 @@
] as [Record<string, InputTransform>, string[], FlowModule]
)
.filter(([i, f, m]) => f.length > 0)
setContext<PropPickerWrapperContext>('PropPickerWrapper', {
focusProp: () => {},
propPickerConfig: writable(undefined),
@@ -47,11 +47,7 @@
<div class="min-h-full">
<FlowCard title="All Static Inputs">
<Toggle
slot="header"
bind:checked={hideOptional}
options={{left: 'Hide optional inputs'}}
/>
<Toggle slot="header" bind:checked={hideOptional} options={{ left: 'Hide optional inputs' }} />
<div class="min-h-full flex-1">
<Alert type="info" title="Static Inputs" class="m-4"
>This page centralizes the static inputs of every steps. It is akin to a file containing all
@@ -80,9 +76,8 @@
<Badge large color="indigo">{m.id}</Badge>
</h2>
<SchemaForm
<SchemaFormTransform
noDynamicToggle
inputTransform
{filter}
class="mt-2"
schema={$flowStateStore[m.id]?.schema ?? {}}
@@ -3,7 +3,6 @@
import FlowCard from '../common/FlowCard.svelte'
import type { FlowEditorContext } from '../types'
import Toggle from '$lib/components/Toggle.svelte'
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
import Tooltip from '$lib/components/Tooltip.svelte'
import PropPickerWrapper from '../propPicker/PropPickerWrapper.svelte'
import FlowModuleEarlyStop from './FlowModuleEarlyStop.svelte'
@@ -16,6 +15,7 @@
import { flowStateStore } from '../flowState'
import { flowStore } from '../flowStore'
import FlowModuleSleep from './FlowModuleSleep.svelte'
import JavascriptEditor from '$lib/components/JavascriptEditor.svelte'
const { previewArgs } = getContext<FlowEditorContext>('FlowEditorContext')
@@ -23,7 +23,7 @@
export let parentModule: FlowModule | undefined
export let previousModule: FlowModule | undefined
let editor: SimpleEditor | undefined = undefined
let editor: JavascriptEditor | undefined = undefined
let selected: string = 'early-stop'
$: stepPropPicker = getStepPropPicker(
@@ -62,7 +62,7 @@
editor?.insertAtCursor(detail)
}}
>
<SimpleEditor
<JavascriptEditor
bind:this={editor}
lang="javascript"
bind:code={mod.value.iterator.expr}
@@ -7,7 +7,6 @@
import ModulePreview from '$lib/components/ModulePreview.svelte'
import { createScriptFromInlineScript, fork } from '$lib/components/flows/flowStateUtils'
import { flowStore } from '$lib/components/flows/flowStore'
import SchemaForm from '$lib/components/SchemaForm.svelte'
import { RawScript, type FlowModule, type PathFlow, type PathScript } from '$lib/gen'
import FlowCard from '../common/FlowCard.svelte'
import FlowModuleHeader from './FlowModuleHeader.svelte'
@@ -27,6 +26,7 @@
import Alert from '$lib/components/common/alert/Alert.svelte'
import FlowModuleSleep from './FlowModuleSleep.svelte'
import FlowPathViewer from './FlowPathViewer.svelte'
import SchemaFormTransform from '$lib/components/SchemaFormTransform.svelte'
const { selectedId, previewArgs } = getContext<FlowEditorContext>('FlowEditorContext')
@@ -211,9 +211,8 @@
pickableProperties={stepPropPicker.pickableProperties}
error={failureModule}
>
<SchemaForm
<SchemaFormTransform
schema={$flowStateStore[$selectedId]?.schema ?? {}}
inputTransform={true}
previousModuleId={previousModule?.id}
bind:args={value.input_transforms}
bind:extraLib={stepPropPicker.extraLib}
@@ -1,15 +1,15 @@
<script lang="ts">
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
import Toggle from '$lib/components/Toggle.svelte'
import PropPickerWrapper from '$lib/components/flows/propPicker/PropPickerWrapper.svelte'
import type { FlowModule } from '$lib/gen'
import { flowStateStore } from '../flowState'
import Tooltip from '$lib/components/Tooltip.svelte'
import { NEVER_TESTED_THIS_FAR } from '../utils'
import JavascriptEditor from '$lib/components/JavascriptEditor.svelte'
export let flowModule: FlowModule
let editor: SimpleEditor | undefined = undefined
let editor: JavascriptEditor | undefined = undefined
$: isStopAfterIfEnabled = Boolean(flowModule.stop_after_if)
@@ -59,7 +59,7 @@
editor?.insertAtCursor(detail)
}}
>
<SimpleEditor
<JavascriptEditor
bind:this={editor}
lang="javascript"
bind:code={flowModule.stop_after_if.expr}
+12
View File
@@ -0,0 +1,12 @@
import { readable } from 'svelte/store'
export async function goto(x) {
console.error('Goto not implemented')
}
export const browser = true
export const dev = true
export const page = readable({ url: document.URL }, function start(set) {
return function stop() {}
})
+1 -1
View File
@@ -9,7 +9,7 @@ import {
UserService,
type Flow,
type User
} from '$lib/gen'
} from '$lib/gen/index'
import { toast } from '@zerodevx/svelte-toast'
import type { Schema, SupportedLanguage } from './common'
import { hubScripts, workspaceStore, type UserExt } from './stores'
+31 -3
View File
@@ -1,6 +1,7 @@
import { sveltekit } from '@sveltejs/kit/vite'
// import { sveltekit } from '@sveltejs/kit/vite'
import { readFileSync } from 'fs'
import { fileURLToPath } from 'url'
import { svelte } from '@sveltejs/vite-plugin-svelte'
const file = fileURLToPath(new URL('package.json', import.meta.url))
const json = readFileSync(file, 'utf8')
@@ -14,7 +15,7 @@ const config = {
preview: {
port: 3000
},
plugins: [sveltekit()],
plugins: [svelte()],
define: {
__pkg__: version
},
@@ -23,8 +24,35 @@ const config = {
},
resolve: {
alias: {
path: 'path-browserify'
path: 'path-browserify',
$lib: ['/src/lib'],
'$lib/*': ['/src/lib/*'],
'$app/navigation': ['/src/lib/fakesvelte.js'],
'$app/stores': ['/src/lib/fakesvelte.js'],
'$app/environment': ['/src/lib/fakesvelte.js']
}
},
build: {
lib: {
// Could also be a dictionary or array of multiple entry points
entry: 'src/embed.js',
name: 'AppViewer',
// the proper extensions will be added
fileName: 'appviewer',
formats: ['iife']
}
// rollupOptions: {
// external: ['highlight.js'],
// input: 'src/embed.js',
// output: {
// format: 'esm',
// name: 'app',
// // We output it to public. This way, our svelte kit
// // app will also host the web components.
// dir: 'build'
// // file: 'build/app.js'
// }
// }
}
}