windmill-components 1.60.2 → 1.60.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/components/AppConnect.svelte +4 -0
  2. package/components/ArgInput.svelte +0 -1
  3. package/components/ArgInput.svelte.d.ts +0 -2
  4. package/components/DisplayResult.svelte +9 -6
  5. package/components/FlowMetadata.svelte +19 -3
  6. package/components/FlowPreviewContent.svelte +15 -9
  7. package/components/InputTransformForm.svelte +1 -2
  8. package/components/JobArgs.svelte +1 -1
  9. package/components/ModulePreview.svelte +2 -1
  10. package/components/Popover.model.d.ts +4 -0
  11. package/components/Popover.model.js +3 -0
  12. package/components/Popover.svelte +0 -2
  13. package/components/Popover.svelte.d.ts +2 -1
  14. package/components/ResourceEditor.svelte +11 -1
  15. package/components/ResourcePicker.svelte +10 -1
  16. package/components/RunForm.svelte +41 -37
  17. package/components/RunForm.svelte.d.ts +1 -0
  18. package/components/ScriptBuilder.svelte +3 -1
  19. package/components/ScriptEditor.svelte +1 -0
  20. package/components/TemplateEditor.svelte +14 -1
  21. package/components/TestJobLoader.svelte +1 -1
  22. package/components/Tooltip.svelte +8 -3
  23. package/components/Tooltip.svelte.d.ts +5 -0
  24. package/components/apps/components/buttons/AppButton.svelte +16 -0
  25. package/components/apps/components/dataDisplay/AppHtml.svelte +24 -12
  26. package/components/apps/components/dataDisplay/VegaLiteHtml.svelte +28 -0
  27. package/components/apps/components/dataDisplay/VegaLiteHtml.svelte.d.ts +23 -0
  28. package/components/apps/components/helpers/InputValue.svelte +24 -5
  29. package/components/apps/components/helpers/InputValue.svelte.d.ts +1 -0
  30. package/components/apps/components/helpers/RunnableComponent.svelte +5 -2
  31. package/components/apps/components/selectInputs/AppSelect.svelte +11 -3
  32. package/components/apps/components/table/AppTable.svelte +6 -12
  33. package/components/apps/editor/AppEditor.svelte +7 -2
  34. package/components/apps/editor/AppPreview.svelte +1 -1
  35. package/components/apps/editor/componentsPanel/data.js +5 -0
  36. package/components/apps/editor/contextPanel/ContextPanel.svelte +3 -2
  37. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +4 -1
  38. package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte +8 -56
  39. package/components/apps/editor/inlineScriptsPanel/utils.d.ts +15 -0
  40. package/components/apps/editor/inlineScriptsPanel/utils.js +28 -0
  41. package/components/apps/editor/settingsPanel/ComponentPanel.svelte +9 -14
  42. package/components/apps/editor/settingsPanel/ComponentPanel.svelte.d.ts +0 -3
  43. package/components/apps/editor/settingsPanel/InputsSpecEditor.svelte +6 -2
  44. package/components/apps/editor/settingsPanel/InputsSpecEditor.svelte.d.ts +4 -2
  45. package/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte +8 -7
  46. package/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte.d.ts +1 -1
  47. package/components/apps/editor/settingsPanel/Recompute.svelte +1 -1
  48. package/components/apps/editor/settingsPanel/TableActions.svelte +7 -2
  49. package/components/apps/editor/settingsPanel/common/PanelSection.svelte +10 -1
  50. package/components/apps/editor/settingsPanel/common/PanelSection.svelte.d.ts +1 -0
  51. package/components/apps/editor/settingsPanel/inputEditor/EvalInputEditor.svelte +25 -0
  52. package/components/apps/editor/settingsPanel/inputEditor/EvalInputEditor.svelte.d.ts +19 -0
  53. package/components/apps/inputType.d.ts +8 -1
  54. package/components/apps/types.d.ts +3 -2
  55. package/components/apps/utils.d.ts +2 -0
  56. package/components/apps/utils.js +11 -0
  57. package/components/common/button/Button.svelte +1 -1
  58. package/components/common/kbd/Kbd.svelte +6 -6
  59. package/components/common/table/Row.svelte +1 -1
  60. package/components/flows/content/CapturePayload.svelte +1 -1
  61. package/components/flows/content/FlowModuleComponent.svelte +4 -2
  62. package/components/flows/utils.js +1 -1
  63. package/components/propertyPicker/PropPicker.svelte +7 -1
  64. package/package.json +7 -3
  65. package/script_helpers.d.ts +3 -3
  66. package/script_helpers.js +18 -19
@@ -30,6 +30,10 @@ const apiTokenApps = {
30
30
  'Create an API key',
31
31
  'Copy your key'
32
32
  ]
33
+ },
34
+ supabase: {
35
+ img: '/supabase_connect.png',
36
+ instructions: ['Go to the API Settings of your app to find the project URL and key']
33
37
  }
34
38
  };
35
39
  </script>
@@ -132,7 +132,6 @@ $: {
132
132
  }
133
133
  }
134
134
  }
135
- export let inputCat = 'string';
136
135
  $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncoding);
137
136
  </script>
138
137
 
@@ -1,5 +1,4 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import { type InputCat } from '../utils';
3
2
  import type { SchemaProperty } from '../common';
4
3
  import SimpleEditor from './SimpleEditor.svelte';
5
4
  import type VariableEditor from './VariableEditor.svelte';
@@ -39,7 +38,6 @@ declare const __propDef: {
39
38
  editor?: SimpleEditor | undefined;
40
39
  evalValueToRaw?: (() => void) | undefined;
41
40
  focus?: (() => void) | undefined;
42
- inputCat?: InputCat | undefined;
43
41
  };
44
42
  events: {
45
43
  focus: CustomEvent<any>;
@@ -44,7 +44,7 @@ function inferResultKind(result) {
44
44
  else if (keys.length == 1 && keys[0] == 'file') {
45
45
  return 'file';
46
46
  }
47
- else if (keys.length == 1 && keys[0] == 'error' && typeof result['error'] == 'string') {
47
+ else if (keys.length == 1 && keys[0] == 'error') {
48
48
  return 'error';
49
49
  }
50
50
  else if (keys.length == 3 &&
@@ -81,7 +81,7 @@ let payload = '';
81
81
  </div>
82
82
  {#if Array.isArray(result[col])}
83
83
  {#each result[col] as item}
84
- <div class="px-12 text-left whitespace-nowrap">
84
+ <div class="px-12 text-left text-xs whitespace-nowrap">
85
85
  {typeof item === 'string' ? item : JSON.stringify(item)}
86
86
  </div>
87
87
  {/each}
@@ -90,14 +90,14 @@ let payload = '';
90
90
  {/each}
91
91
  </div>
92
92
  {:else if !forceJson && resultKind == 'table-row'}<div
93
- class="grid grid-flow-col-dense border border-gray-200 rounded-md "
93
+ class="grid grid-flow-col-dense border border-gray-200 "
94
94
  >
95
95
  <TableCustom>
96
96
  <tbody slot="body">
97
97
  {#each asListOfList(result) as row}
98
98
  <tr>
99
99
  {#each row as v}
100
- <td>{truncate(JSON.stringify(v), 200) ?? ''}</td>
100
+ <td class="!text-xs">{truncate(JSON.stringify(v), 200) ?? ''}</td>
101
101
  {/each}
102
102
  </tr>
103
103
  {/each}
@@ -126,8 +126,11 @@ let payload = '';
126
126
  >Download</a
127
127
  >
128
128
  </div>
129
- {:else if !forceJson && resultKind == 'error'}<div
130
- ><pre class="text-sm text-red-500 whitespace-pre-wrap">{result.error}</pre>
129
+ {:else if !forceJson && resultKind == 'error'}<div>
130
+ <span class="text-red-500 font-semibold text-sm"
131
+ >{result.error.name}: {result.error.message}</span
132
+ >
133
+ <pre class="text-sm whitespace-pre-wrap text-gray-900">{result.error.stack ?? ''}</pre>
131
134
  </div>
132
135
  {:else if !forceJson && resultKind == 'approval'}<div class="flex flex-col gap-1 mx-4">
133
136
  <Button
@@ -3,6 +3,17 @@ import Icon from 'svelte-awesome';
3
3
  import { displayDaysAgo } from '../utils';
4
4
  import { faCalendar, faClock, faRobot, faScroll, faUser, faBarsStaggered } from '@fortawesome/free-solid-svg-icons';
5
5
  import ScheduleEditor from './ScheduleEditor.svelte';
6
+ import { onDestroy, onMount } from 'svelte';
7
+ let time = Date.now();
8
+ let interval;
9
+ onMount(() => {
10
+ interval = setInterval(() => {
11
+ time = Date.now();
12
+ }, 1000);
13
+ });
14
+ onDestroy(() => {
15
+ interval && clearInterval(interval);
16
+ });
6
17
  export let job;
7
18
  const SMALL_ICON_SCALE = 0.7;
8
19
  let scheduleEditor;
@@ -13,14 +24,19 @@ let scheduleEditor;
13
24
  <div class="rounded-md p-3 bg-gray-50 shadow-sm sm:text-sm md:text-base" style="min-height: 150px;">
14
25
  <JobStatus {job} />
15
26
  <div>
16
- <Icon class="text-gray-700" data={faClock} scale={SMALL_ICON_SCALE} /><span class="mx-2">
17
- Created {displayDaysAgo(job.created_at ?? '')}</span
27
+ <Icon class="text-gray-700" data={faClock} scale={SMALL_ICON_SCALE} /><span
28
+ class="mx-2 text-2xs text-gray-600"
29
+ >
30
+ {#key time}
31
+ Received job {displayDaysAgo(job.created_at ?? '')}
32
+ {/key}</span
18
33
  >
19
34
  </div>
20
35
  {#if job && 'started_at' in job && job.started_at}
21
36
  <div>
22
37
  <Icon class="text-gray-700" data={faClock} scale={SMALL_ICON_SCALE} /><span class="mx-2">
23
- Started {displayDaysAgo(job.started_at ?? '')}</span
38
+ {#key time}
39
+ Started {displayDaysAgo(job.started_at ?? '')}{/key}</span
24
40
  >
25
41
  </div>
26
42
  {/if}
@@ -11,6 +11,7 @@ import FlowStatusViewer from '../components/FlowStatusViewer.svelte';
11
11
  import FlowProgressBar from './flows/FlowProgressBar.svelte';
12
12
  import { flowStateStore } from './flows/flowState';
13
13
  import CapturePayload from './flows/content/CapturePayload.svelte';
14
+ import { Loader2 } from 'lucide-svelte';
14
15
  let capturePayload;
15
16
  export let previewMode;
16
17
  export let open;
@@ -111,8 +112,9 @@ $: if (job?.type === 'CompletedJob') {
111
112
  jobId = undefined
112
113
  }}
113
114
  size="md"
114
- btnClasses="w-full"
115
+ btnClasses="w-full max-w-lg"
115
116
  >
117
+ <Loader2 class="animate-spin mr-2" />
116
118
  Cancel
117
119
  </Button>
118
120
  {:else}
@@ -121,7 +123,7 @@ $: if (job?.type === 'CompletedJob') {
121
123
  startIcon={{ icon: isRunning ? faRefresh : faPlay }}
122
124
  color="blue"
123
125
  size="sm"
124
- btnClasses="w-full"
126
+ btnClasses="w-full max-w-lg"
125
127
  disabled={!isValid}
126
128
  on:click={() => runPreview($previewArgs)}
127
129
  >
@@ -140,13 +142,17 @@ $: if (job?.type === 'CompletedJob') {
140
142
  <FlowProgressBar {job} bind:reset={jobProgressReset} />
141
143
 
142
144
  <div class="overflow-y-auto grow flex-col flex divide-y divide-gray-600 ">
143
- <SchemaForm
144
- compact
145
- class="py-4"
146
- schema={$flowStore.schema}
147
- bind:isValid
148
- bind:args={$previewArgs}
149
- />
145
+ <div class="max-h-1/2 overflow-auto">
146
+ <SchemaForm
147
+ noVariablePicker
148
+ compact
149
+ class="py-4 max-w-3xl"
150
+ schema={$flowStore.schema}
151
+ bind:isValid
152
+ bind:args={$previewArgs}
153
+ />
154
+ </div>
155
+
150
156
  <div class="h-full pt-4 grow">
151
157
  {#if jobId}
152
158
  <FlowStatusViewer bind:flowState={$flowStateStore} {jobId} bind:job />
@@ -22,7 +22,7 @@ export let noDynamicToggle = false;
22
22
  let monaco = undefined;
23
23
  let monacoTemplate = undefined;
24
24
  let argInput = undefined;
25
- let inputCat = computeInputCat(schema.properties[argName].type, schema.properties[argName].format, schema.properties[argName].items?.type, schema.properties[argName].enum, schema.properties[argName].contentEncoding);
25
+ $: inputCat = computeInputCat(schema.properties[argName].type, schema.properties[argName].format, schema.properties[argName].items?.type, schema.properties[argName].enum, schema.properties[argName].contentEncoding);
26
26
  let propertyType = getPropertyType(arg);
27
27
  function getPropertyType(arg) {
28
28
  let type = arg?.type ?? 'static';
@@ -246,7 +246,6 @@ $: schema.properties[argName].default &&
246
246
  bind:itemsType={schema.properties[argName].items}
247
247
  properties={schema.properties[argName].properties}
248
248
  displayHeader={false}
249
- bind:inputCat
250
249
  {variableEditor}
251
250
  {itemPicker}
252
251
  bind:pickForField
@@ -18,7 +18,7 @@ export let args;
18
18
  </tr>
19
19
  {/each}
20
20
  {:else if args}
21
- <tr>No arguments</tr>
21
+ <tr><div class="text-gray-600 pt-2 pl-1 text-sm">No arguments</div></tr>
22
22
  {:else}
23
23
  <tr>
24
24
  <td>
@@ -60,11 +60,12 @@ function jobDone() {
60
60
  {/if}
61
61
 
62
62
  <RunForm
63
+ noVariablePicker
63
64
  loading={testIsLoading}
64
65
  runnable={{ summary: mod.summary ?? '', schema, description: '' }}
65
66
  runAction={(_, args) => runTest(args)}
66
67
  schedulable={false}
67
- buttonText="Test just this step (Ctrl+Enter)"
68
+ buttonText="Test (Ctrl+Enter)"
68
69
  detailed={false}
69
70
  topButton
70
71
  bind:args={stepArgs}
@@ -0,0 +1,4 @@
1
+ declare const SIDE: readonly ["auto", "top", "bottom", "left", "right"];
2
+ declare const ALIGN: readonly ["start", "end"];
3
+ export type PopoverPlacement = `${typeof SIDE[number]}` | `${typeof SIDE[number]}-${typeof ALIGN[number]}`;
4
+ export {};
@@ -0,0 +1,3 @@
1
+ const SIDE = ['auto', 'top', 'bottom', 'left', 'right'];
2
+ const ALIGN = ['start', 'end'];
3
+ export {};
@@ -1,6 +1,4 @@
1
1
  <script>import { createPopperActions } from 'svelte-popperjs';
2
- const SIDE = ['auto', 'top', 'bottom', 'left', 'right'];
3
- const ALIGN = ['start', 'end'];
4
2
  export let placement = 'auto';
5
3
  export let notClickable = false;
6
4
  export let popupClass = '';
@@ -1,8 +1,9 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
+ import type { PopoverPlacement } from './Popover.model';
2
3
  declare const __propDef: {
3
4
  props: {
4
5
  [x: string]: any;
5
- placement?: "left" | "right" | "auto" | "top" | "bottom" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "auto-start" | "auto-end" | "right-start" | "right-end" | "left-start" | "left-end" | undefined;
6
+ placement?: PopoverPlacement | undefined;
6
7
  notClickable?: boolean | undefined;
7
8
  popupClass?: string | undefined;
8
9
  disapperTimoout?: number | undefined;
@@ -20,6 +20,7 @@ let resourceSchema;
20
20
  let args = {};
21
21
  let can_write = true;
22
22
  let loadingSchema = false;
23
+ let linkedVars = [];
23
24
  let drawer;
24
25
  let rawCode = undefined;
25
26
  const dispatch = createEventDispatcher();
@@ -38,6 +39,9 @@ export async function initEdit(p) {
38
39
  can_write =
39
40
  resourceToEdit.workspace_id == $workspaceStore &&
40
41
  canWrite(p, resourceToEdit.extra_perms ?? {}, $userStore);
42
+ linkedVars = Object.entries(args)
43
+ .filter(([_, v]) => typeof v == 'string' && v == `$var:${initialPath}`)
44
+ .map(([k, _]) => k);
41
45
  }
42
46
  async function editResource() {
43
47
  if (resourceToEdit) {
@@ -47,7 +51,7 @@ async function editResource() {
47
51
  requestBody: { path, value: args, description }
48
52
  });
49
53
  sendUserToast(`Updated resource at ${path}`);
50
- dispatch('refresh');
54
+ dispatch('refresh', path);
51
55
  drawer.closeDrawer?.();
52
56
  }
53
57
  else {
@@ -88,6 +92,12 @@ function parseJson() {
88
92
  jsonError = e.message;
89
93
  }
90
94
  }
95
+ $: linkedVars.length > 0 && path && updateArgsFromLinkedVars();
96
+ function updateArgsFromLinkedVars() {
97
+ linkedVars.forEach((k) => {
98
+ args[k] = `$var:${path}`;
99
+ });
100
+ }
91
101
  </script>
92
102
 
93
103
  <Drawer bind:this={drawer} size="800px">
@@ -41,7 +41,16 @@ let resourceEditor;
41
41
  bind:this={appConnect}
42
42
  />
43
43
 
44
- <ResourceEditor bind:this={resourceEditor} on:refresh={() => loadResources(resourceType)} />
44
+ <ResourceEditor
45
+ bind:this={resourceEditor}
46
+ on:refresh={async (e) => {
47
+ await loadResources(resourceType)
48
+ console.log(e)
49
+ if (e.detail) {
50
+ value = e.detail
51
+ }
52
+ }}
53
+ />
45
54
 
46
55
  <div class="flex flex-row gap-x-1 w-full">
47
56
  <Select
@@ -16,6 +16,7 @@ export let detailed = true;
16
16
  export let autofocus = false;
17
17
  export let topButton = false;
18
18
  export let loading = false;
19
+ export let noVariablePicker = false;
19
20
  export let args = decodeArgs($page.url.searchParams.get('args') ?? undefined);
20
21
  export function run() {
21
22
  runAction(scheduledForStr, args, invisible_to_owner);
@@ -84,52 +85,55 @@ let invisible_to_owner;
84
85
  {#if !runnable.schema.properties || Object.keys(runnable.schema.properties).length === 0}
85
86
  <div class="text-sm p-4">No arguments</div>
86
87
  {:else}
87
- <SchemaForm {autofocus} schema={runnable.schema} bind:isValid bind:args />
88
+ <SchemaForm {noVariablePicker} {autofocus} schema={runnable.schema} bind:isValid bind:args />
88
89
  {/if}
89
90
  {:else}
90
91
  <div class="text-xs text-gray-600">No schema</div>
91
92
  {/if}
92
- {#if viewOptions}
93
- <div transition:slide class="mt-6">
94
- <h2>Run later</h2>
95
- <div class="border rounded-md p-3 pt-4">
96
- <div class="flex flex-row items-end">
97
- <div class="w-max md:w-2/3 mt-2 mb-1">
98
- <label for="run-time" />
99
- <input
100
- class="inline-block"
101
- type="datetime-local"
102
- id="run-time"
103
- name="run-scheduled-time"
104
- bind:value={scheduledForStr}
105
- min={getToday().toISOString().slice(0, 16)}
106
- />
107
- </div>
93
+ {#if schedulable}
94
+ <div class="flex gap-2 items-start flex-wrap justify-between mt-2 md:mt-6 mb-6">
95
+ <div class="flex flex-col">
96
+ <div>
108
97
  <Button
109
- variant="border"
110
- color="blue"
98
+ color="light"
111
99
  size="sm"
112
- btnClasses="mx-2 mb-1"
113
- on:click={() => {
114
- scheduledForStr = undefined
115
- }}
100
+ endIcon={{ icon: viewOptions ? faChevronUp : faChevronDown }}
101
+ on:click={() => (viewOptions = !viewOptions)}
116
102
  >
117
- Clear
103
+ Schedule to run later
118
104
  </Button>
119
105
  </div>
106
+ {#if viewOptions}
107
+ <div transition:slide class="mt-6">
108
+ <div class="border rounded-md p-3 pt-4">
109
+ <div class="flex flex-row items-end">
110
+ <div class="w-max md:w-2/3 mt-2 mb-1">
111
+ <label for="run-time" />
112
+ <input
113
+ class="inline-block"
114
+ type="datetime-local"
115
+ id="run-time"
116
+ name="run-scheduled-time"
117
+ bind:value={scheduledForStr}
118
+ min={getToday().toISOString().slice(0, 16)}
119
+ />
120
+ </div>
121
+ <Button
122
+ variant="border"
123
+ color="blue"
124
+ size="sm"
125
+ btnClasses="mx-2 mb-1"
126
+ on:click={() => {
127
+ scheduledForStr = undefined
128
+ }}
129
+ >
130
+ Clear
131
+ </Button>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ {/if}
120
136
  </div>
121
- </div>
122
- {/if}
123
- {#if schedulable}
124
- <div class="flex gap-2 items-center flex-wrap justify-between mt-2 md:mt-6 mb-6">
125
- <Button
126
- color="light"
127
- size="sm"
128
- endIcon={{ icon: viewOptions ? faChevronUp : faChevronDown }}
129
- on:click={() => (viewOptions = !viewOptions)}
130
- >
131
- Schedule to run later
132
- </Button>
133
137
  {#if runnable?.path?.startsWith(`u/${$userStore?.username}`) != true && (runnable?.path?.split('/')?.length ?? 0) > 2}
134
138
  <div class="flex items-center gap-1">
135
139
  <Toggle
@@ -150,7 +154,7 @@ let invisible_to_owner;
150
154
  disabled={!isValid}
151
155
  on:click={() => runAction(scheduledForStr, args, invisible_to_owner)}
152
156
  >
153
- {scheduledForStr ? 'Schedule run to a later time' : buttonText}
157
+ {scheduledForStr ? 'Schedule to run later' : buttonText}
154
158
  </Button>
155
159
  </div>
156
160
  </div>
@@ -22,6 +22,7 @@ declare const __propDef: {
22
22
  autofocus?: boolean | undefined;
23
23
  topButton?: boolean | undefined;
24
24
  loading?: boolean | undefined;
25
+ noVariablePicker?: boolean | undefined;
25
26
  args?: Record<string, any> | undefined;
26
27
  run?: (() => void) | undefined;
27
28
  isValid?: boolean | undefined;
@@ -4,7 +4,7 @@ import { page } from '$app/stores';
4
4
  import { inferArgs } from '../infer';
5
5
  import { initialCode, isInitialCode } from '../script_helpers';
6
6
  import { userStore, workspaceStore } from '../stores';
7
- import { encodeState, sendUserToast, setQueryWithoutLoad } from '../utils';
7
+ import { emptySchema, encodeState, sendUserToast, setQueryWithoutLoad } from '../utils';
8
8
  import Path from './Path.svelte';
9
9
  import RadioButton from './RadioButton.svelte';
10
10
  import ScriptEditor from './ScriptEditor.svelte';
@@ -43,6 +43,7 @@ async function editScript() {
43
43
  try {
44
44
  $dirtyStore = false;
45
45
  localStorage.removeItem(script.path);
46
+ script.schema = script.schema ?? emptySchema();
46
47
  if (!script.schema) {
47
48
  await inferArgs(script.language, script.content, script.schema);
48
49
  }
@@ -69,6 +70,7 @@ async function editScript() {
69
70
  }
70
71
  async function changeStep(step) {
71
72
  if (step > 1) {
73
+ script.schema = script.schema ?? emptySchema();
72
74
  await inferArgs(script.language, script.content, script.schema);
73
75
  }
74
76
  goto(`?step=${step}`);
@@ -56,6 +56,7 @@ async function loadPastTests() {
56
56
  });
57
57
  }
58
58
  async function inferSchema(code) {
59
+ schema = schema ?? emptySchema();
59
60
  let isDefault = [];
60
61
  Object.entries(args).forEach(([k, v]) => {
61
62
  if (schema.properties[k].default == v) {
@@ -338,6 +338,9 @@ export let extraLib = '';
338
338
  export let autoHeight = true;
339
339
  export let fixedOverflowWidgets = true;
340
340
  export let fontSize = 16;
341
+ if (typeof code != 'string') {
342
+ code = '';
343
+ }
341
344
  const lang = 'template';
342
345
  const dispatch = createEventDispatcher();
343
346
  const uri = `file:///${hash}.ts`;
@@ -511,4 +514,14 @@ onDestroy(() => {
511
514
  });
512
515
  </script>
513
516
 
514
- <div bind:this={divEl} class="{$$props.class} rounded-lg mx-0.5" bind:clientWidth={width} />
517
+ <div
518
+ bind:this={divEl}
519
+ style="height: 18px;"
520
+ class="{$$props.class} template rounded-lg min-h-4 mx-0.5"
521
+ bind:clientWidth={width}
522
+ />
523
+
524
+ <style>
525
+ :global(.template .mtk20) {
526
+ color: black !important;
527
+ }</style>
@@ -163,6 +163,6 @@ async function syncer(id) {
163
163
  setTimeout(() => syncer(id), nextIteration);
164
164
  }
165
165
  onDestroy(async () => {
166
- await clearCurrentJob();
166
+ currentId = undefined;
167
167
  });
168
168
  </script>
@@ -2,13 +2,18 @@
2
2
  import Icon from 'svelte-awesome';
3
3
  import Popover from './Popover.svelte';
4
4
  export let light = false;
5
+ export let scale = 0.8;
6
+ export let wrapperClass = '';
7
+ export let placement = undefined;
5
8
  </script>
6
9
 
7
- <Popover notClickable>
10
+ <Popover notClickable {placement} class={wrapperClass}>
8
11
  <Icon
9
- class="{light ? 'text-gray-300' : ' text-gray-500'} font-thin inline-block align-middle w-4"
12
+ class="{light
13
+ ? 'text-gray-300'
14
+ : ' text-gray-500'} font-thin inline-block align-middle w-4 {$$props.class}"
10
15
  data={faInfoCircle}
11
- scale={0.8}
16
+ {scale}
12
17
  />
13
18
  <span slot="text"> <slot /> </span>
14
19
  </Popover>
@@ -1,7 +1,12 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
+ import type { PopoverPlacement } from './Popover.model';
2
3
  declare const __propDef: {
3
4
  props: {
5
+ [x: string]: any;
4
6
  light?: boolean | undefined;
7
+ scale?: number | undefined;
8
+ wrapperClass?: string | undefined;
9
+ placement?: PopoverPlacement | undefined;
5
10
  };
6
11
  events: {
7
12
  [evt: string]: CustomEvent<any>;
@@ -18,6 +18,7 @@ let labelValue;
18
18
  let color;
19
19
  let size;
20
20
  let runnableComponent;
21
+ let disabled = undefined;
21
22
  let isLoading = false;
22
23
  let ownClick = false;
23
24
  $: outputs = $worldStore?.outputsById[id];
@@ -33,11 +34,22 @@ $: outputs?.loading.subscribe({
33
34
  }
34
35
  });
35
36
  $: loading = isLoading && ownClick;
37
+ let errors = {};
38
+ $: errorsMessage = Object.values(errors)
39
+ .filter((x) => x != '')
40
+ .join('\n');
36
41
  </script>
37
42
 
38
43
  <InputValue {id} input={configuration.label} bind:value={labelValue} />
39
44
  <InputValue {id} input={configuration.color} bind:value={color} />
40
45
  <InputValue {id} input={configuration.size} bind:value={size} />
46
+ <InputValue
47
+ row={extraQueryParams['row']}
48
+ {id}
49
+ input={configuration.disabled}
50
+ bind:value={disabled}
51
+ bind:error={errors.disabled}
52
+ />
41
53
 
42
54
  <RunnableWrapper
43
55
  flexWrap
@@ -48,7 +60,11 @@ $: loading = isLoading && ownClick;
48
60
  autoRefresh={false}
49
61
  >
50
62
  <AlignWrapper {noWFull} {horizontalAlignment} {verticalAlignment}>
63
+ {#if errorsMessage}
64
+ <div class="text-red-500 text-xs">{errorsMessage}</div>
65
+ {/if}
51
66
  <Button
67
+ {disabled}
52
68
  on:pointerdown={(e) => {
53
69
  e?.stopPropagation()
54
70
  window.dispatchEvent(new Event('pointerup'))
@@ -7,17 +7,29 @@ export let verticalAlignment = undefined;
7
7
  export let configuration;
8
8
  export const staticOutputs = ['result', 'loading'];
9
9
  let result = undefined;
10
+ let h = undefined;
11
+ let w = undefined;
10
12
  </script>
11
13
 
12
- <RunnableWrapper flexWrap bind:componentInput {id} bind:result>
13
- <AlignWrapper {horizontalAlignment} {verticalAlignment}>
14
- <div
15
- on:pointerdown={(e) => {
16
- e?.preventDefault()
17
- }}
18
- class="h-full relative w-full overflow-hidden"
19
- >
20
- {@html result ?? 'No html'}
21
- </div>
22
- </AlignWrapper>
23
- </RunnableWrapper>
14
+ <div
15
+ on:pointerdown={(e) => {
16
+ e?.preventDefault()
17
+ }}
18
+ class="h-full w-full"
19
+ bind:clientHeight={h}
20
+ bind:clientWidth={w}
21
+ >
22
+ <RunnableWrapper flexWrap bind:componentInput {id} bind:result>
23
+ <AlignWrapper {horizontalAlignment} {verticalAlignment}>
24
+ {#key result}
25
+ <iframe
26
+ frameborder="0"
27
+ style="height: {h}px; width: {w}px"
28
+ class="p-0"
29
+ title="sandbox"
30
+ srcdoc={result ? '<scr' + `ipt src="/tailwind.css"></script>` + result : 'No html'}
31
+ />
32
+ {/key}
33
+ </AlignWrapper>
34
+ </RunnableWrapper>
35
+ </div>
@@ -0,0 +1,28 @@
1
+ <script>import { onMount } from 'svelte';
2
+ import AlignWrapper from '../helpers/AlignWrapper.svelte';
3
+ import RunnableWrapper from '../helpers/RunnableWrapper.svelte';
4
+ export let id;
5
+ export let componentInput;
6
+ export let horizontalAlignment = 'left';
7
+ export let verticalAlignment = undefined;
8
+ export let configuration;
9
+ export const staticOutputs = ['result', 'loading'];
10
+ let result = undefined;
11
+ let divEl = null;
12
+ let vegaEmbed;
13
+ onMount(async () => {
14
+ if (divEl) {
15
+ await import('https://cdn.jsdelivr.net/npm/vega@5.22.1');
16
+ await import('https://cdn.jsdelivr.net/npm/vega-lite@5.6.0');
17
+ vegaEmbed = await import('https://cdn.jsdelivr.net/npm/vega-embed@6.21.0');
18
+ console.log(vegaEmbed);
19
+ vegaEmbed(divEl, result);
20
+ }
21
+ });
22
+ </script>
23
+
24
+ <RunnableWrapper flexWrap bind:componentInput {id} bind:result>
25
+ <AlignWrapper {horizontalAlignment} {verticalAlignment}>
26
+ <div bind:this={divEl} />
27
+ </AlignWrapper>
28
+ </RunnableWrapper>