windmill-components 1.55.2 → 1.56.2

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 (81) hide show
  1. package/assets/app.css +54 -0
  2. package/components/CenteredModal.svelte +3 -2
  3. package/components/Dropdown.svelte +7 -13
  4. package/components/Editor.svelte +29 -29
  5. package/components/Editor.svelte.d.ts +3 -3
  6. package/components/FlowPreviewContent.svelte +2 -2
  7. package/components/FlowStatusViewer.svelte +57 -5
  8. package/components/FlowStatusViewer.svelte.d.ts +2 -0
  9. package/components/InputTransformForm.svelte +13 -5
  10. package/components/InputTransformForm.svelte.d.ts +0 -2
  11. package/components/ModulePreview.svelte +6 -2
  12. package/components/ModulePreview.svelte.d.ts +1 -1
  13. package/components/RunForm.svelte +10 -8
  14. package/components/ScheduleEditor.svelte +2 -2
  15. package/components/SimpleEditor.svelte +18 -20
  16. package/components/TemplateEditor.svelte +34 -26
  17. package/components/TemplateEditor.svelte.d.ts +1 -25
  18. package/components/TestJobLoader.svelte +1 -1
  19. package/components/apps/components/DisplayComponent.svelte +1 -1
  20. package/components/apps/components/buttons/AppButton.svelte +24 -1
  21. package/components/apps/components/form/AppForm.svelte +18 -1
  22. package/components/apps/components/helpers/InputValue.svelte +0 -4
  23. package/components/apps/components/helpers/MissingConnectionWarning.svelte +11 -0
  24. package/components/apps/components/helpers/MissingConnectionWarning.svelte.d.ts +17 -0
  25. package/components/apps/components/helpers/RunnableComponent.svelte +82 -29
  26. package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +1 -1
  27. package/components/apps/components/helpers/RunnableWrapper.svelte +1 -1
  28. package/components/apps/components/selectInputs/AppSelect.svelte +14 -3
  29. package/components/apps/components/table/AppTable.svelte +5 -5
  30. package/components/apps/editor/AppEditor.svelte +5 -7
  31. package/components/apps/editor/ComponentEditor.svelte +1 -0
  32. package/components/apps/editor/GridEditor.svelte +6 -2
  33. package/components/apps/editor/SettingsPanel.svelte +13 -0
  34. package/components/apps/editor/SettingsPanel.svelte.d.ts +14 -0
  35. package/components/apps/editor/TablePanel.svelte +16 -0
  36. package/components/apps/editor/TablePanel.svelte.d.ts +17 -0
  37. package/components/apps/editor/componentsPanel/ComponentList.svelte +25 -7
  38. package/components/apps/editor/contextPanel/ComponentOutputViewer.svelte +1 -1
  39. package/components/apps/editor/contextPanel/ContextPanel.svelte +3 -0
  40. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +1 -1
  41. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte +63 -46
  42. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte.d.ts +2 -2
  43. package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte +16 -2
  44. package/components/apps/editor/settingsPanel/AlignmentEditor.svelte +17 -15
  45. package/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte.d.ts +9 -0
  46. package/components/apps/editor/settingsPanel/ComponentPanel.svelte +37 -2
  47. package/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte +7 -4
  48. package/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte.d.ts +1 -0
  49. package/components/apps/editor/settingsPanel/Recompute.svelte +6 -2
  50. package/components/apps/editor/settingsPanel/TableActions.svelte +9 -32
  51. package/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte +25 -8
  52. package/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte +10 -1
  53. package/components/apps/inputType.d.ts +2 -1
  54. package/components/apps/rx.js +1 -1
  55. package/components/apps/utils.js +6 -3
  56. package/components/common/confirmationModal/UnsavedConfirmationModal.svelte +6 -2
  57. package/components/common/drawer/Drawer.svelte +8 -4
  58. package/components/common/drawer/Drawer.svelte.d.ts +1 -0
  59. package/components/common/menu/Menu.svelte +16 -1
  60. package/components/common/table/LanguageBadge.svelte.d.ts +6 -13
  61. package/components/common/table/Row.svelte +9 -11
  62. package/components/common/table/RowIcon.svelte +3 -2
  63. package/components/common/table/RowIcon.svelte.d.ts +1 -0
  64. package/components/flows/common/FlowCardHeader.svelte +29 -2
  65. package/components/flows/content/FlowModuleComponent.svelte +1 -1
  66. package/components/flows/content/FlowModuleScript.svelte +8 -3
  67. package/components/flows/content/FlowModuleScript.svelte.d.ts +1 -0
  68. package/components/flows/header/FlowPreviewButtons.svelte +2 -1
  69. package/components/flows/pickers/WorkspaceScriptPicker.svelte +1 -1
  70. package/components/flows/previousResults.d.ts +1 -1
  71. package/components/flows/previousResults.js +15 -3
  72. package/components/propertyPicker/PropPicker.svelte +2 -1
  73. package/components/sidebar/MenuLink.svelte +4 -4
  74. package/components/sidebar/MenuLink.svelte.d.ts +1 -1
  75. package/gen/core/OpenAPI.js +1 -1
  76. package/gen/services/JobService.d.ts +10 -0
  77. package/gen/services/JobService.js +17 -0
  78. package/package.json +16 -12
  79. package/stores.js +1 -1
  80. package/utils.d.ts +1 -0
  81. package/utils.js +4 -2
package/assets/app.css ADDED
@@ -0,0 +1,54 @@
1
+ /* Write your global styles here, in PostCSS syntax */
2
+ @tailwind base;
3
+ @tailwind components;
4
+ @tailwind utilities;
5
+
6
+ @layer base {
7
+ @font-face {
8
+ font-family: 'Inter';
9
+ src: url('/Inter-Variable.ttf');
10
+ font-weight: 100 900;
11
+ font-display: swap;
12
+ }
13
+
14
+ .splitpanes--vertical > .splitpanes__pane {
15
+ transition: none !important;
16
+ }
17
+
18
+ .splitpanes--horizontal > .splitpanes__pane {
19
+ transition: none !important;
20
+ }
21
+
22
+ .monaco-workbench > .notifications-toasts.visible {
23
+ display: none !important;
24
+ }
25
+
26
+ .nowrap pre code.hljs {
27
+ whitespace: normal !important;
28
+ }
29
+
30
+ svelte-virtual-list-row {
31
+ overflow: visible !important;
32
+ }
33
+
34
+ svelte-virtual-list-contents > * + * {
35
+ border-top-width: 1px !important;
36
+ border-bottom-width: 0px !important;
37
+ }
38
+
39
+ .monaco-editor textarea:focus {
40
+ box-shadow: none !important;
41
+ }
42
+
43
+ .templatable-editor span.mtk20 {
44
+ color: black !important;
45
+ }
46
+ }
47
+
48
+ @layer components {
49
+ /* Flow graph viewer -> Svelvet library internal class overwrite */
50
+ .Node {
51
+ display: flex !important;
52
+ cursor: pointer !important;
53
+ }
54
+ }
@@ -1,10 +1,11 @@
1
1
  <script>import { SettingsService } from '../gen';
2
+ import { onMount } from 'svelte';
2
3
  import WindmillIcon from './icons/WindmillIcon.svelte';
3
4
  export let subtitle = undefined;
4
5
  export let title = 'Windmill';
5
6
  let version = '';
6
- SettingsService.backendVersion().then((x) => {
7
- version = x;
7
+ onMount(async () => {
8
+ version = await SettingsService.backendVersion();
8
9
  });
9
10
  </script>
10
11
 
@@ -20,8 +20,7 @@ const dispatch = createEventDispatcher();
20
20
  {#each dropdownItems as item, i}
21
21
  {#if item.action}
22
22
  <button
23
- on:click={(event) => {
24
- event.preventDefault()
23
+ on:click|preventDefault|stopPropagation={(event) => {
25
24
  if (!item.disabled) {
26
25
  close()
27
26
  item.action && item.action(event)
@@ -30,7 +29,7 @@ const dispatch = createEventDispatcher();
30
29
  }}
31
30
  class="block w-full whitespace-nowrap hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30
32
31
  px-4 py-2 text-sm text-gray-700 text-left
33
- {item.disabled ? 'bg-gray-100' : ''}
32
+ {item.disabled ? 'bg-gray-200' : ''}
34
33
  {item.separatorTop ? 'border-t' : ''} {item.separatorBottom ? 'border-b' : ''} {item.type ==
35
34
  'delete'
36
35
  ? 'text-red-500'
@@ -52,14 +51,9 @@ const dispatch = createEventDispatcher();
52
51
  {:else if item.href && !item.disabled}
53
52
  <a
54
53
  href={item.href}
55
- on:click={(e) => {
56
- if (!item.disabled) {
57
- close()
58
- } else {
59
- e.preventDefault()
60
- }
61
- }}
62
- class="block w-full px-4 font-semibold py-2 text-sm text-gray-700 hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30"
54
+ on:click|stopPropagation
55
+ class="block w-full px-4 font-semibold text-left py-2 text-sm text-gray-700 hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30
56
+ {item.disabled ? 'bg-gray-200' : ''}"
63
57
  role="menuitem"
64
58
  tabindex="-1"
65
59
  id="user-menu-item-{name}-{i}}"
@@ -77,11 +71,11 @@ const dispatch = createEventDispatcher();
77
71
  {:else}
78
72
  <span
79
73
  class:bg-gray-50={item.disabled}
80
- class="block px-4 py-2 text-sm text-gray-700 cursor-auto"
74
+ class="block text-left px-4 py-2 text-sm text-gray-700 cursor-auto"
81
75
  role="menuitem"
82
76
  tabindex="-1"
83
77
  id="user-menu-item-{name}-{i}}"
84
- on:click|preventDefault
78
+ on:click|preventDefault|stopPropagation
85
79
  >
86
80
  {#if item.icon}
87
81
  <Icon
@@ -1,26 +1,7 @@
1
- <script context="module">import * as monaco from 'monaco-editor';
2
- monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
3
- target: monaco.languages.typescript.ScriptTarget.Latest,
4
- allowNonTsExtensions: true,
5
- noLib: true
6
- });
7
- monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
8
- noSemanticValidation: true,
9
- noSuggestionDiagnostics: true,
10
- noSyntaxValidation: true
11
- });
12
- monaco.editor.defineTheme('myTheme', {
13
- base: 'vs',
14
- inherit: true,
15
- rules: [],
16
- colors: {
17
- 'editorLineNumber.foreground': '#999',
18
- 'editorGutter.background': '#F9FAFB'
19
- }
20
- });
21
- monaco.editor.setTheme('myTheme');
1
+ <script context="module">import getMessageServiceOverride from 'vscode/service-override/messages';
2
+ import { StandaloneServices } from 'vscode/services';
22
3
  try {
23
- StandaloneServices.initialize({
4
+ StandaloneServices?.initialize({
24
5
  ...getMessageServiceOverride(document.body)
25
6
  });
26
7
  }
@@ -29,18 +10,37 @@ catch (e) {
29
10
  }
30
11
  </script>
31
12
 
32
- <script>import { browser, dev } from '$app/env';
13
+ <script>import { browser, dev } from '$app/environment';
33
14
  import { page } from '$app/stores';
34
15
  import { sendUserToast } from '../utils';
35
16
  import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
36
17
  import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
37
18
  import { buildWorkerDefinition } from 'monaco-editor-workers';
38
- import getMessageServiceOverride from 'vscode/service-override/messages';
39
19
  import { createEventDispatcher, onDestroy, onMount } from 'svelte';
20
+ import { languages, editor as meditor, KeyCode, KeyMod, Uri as mUri } from 'monaco-editor';
21
+ languages.typescript.typescriptDefaults.setCompilerOptions({
22
+ target: languages.typescript.ScriptTarget.Latest,
23
+ allowNonTsExtensions: true,
24
+ noLib: true
25
+ });
26
+ languages.typescript.typescriptDefaults.setDiagnosticsOptions({
27
+ noSemanticValidation: true,
28
+ noSuggestionDiagnostics: true,
29
+ noSyntaxValidation: true
30
+ });
31
+ meditor.defineTheme('myTheme', {
32
+ base: 'vs',
33
+ inherit: true,
34
+ rules: [],
35
+ colors: {
36
+ 'editorLineNumber.foreground': '#999',
37
+ 'editorGutter.background': '#F9FAFB'
38
+ }
39
+ });
40
+ meditor.setTheme('myTheme');
40
41
  import { BASH_INIT_CODE, DENO_INIT_CODE_CLEAR, GO_INIT_CODE, PYTHON_INIT_CODE_CLEAR } from '../script_helpers';
41
42
  import { createHash as randomHash, editorConfig, langToExt, updateOptions } from '../editorUtils';
42
43
  import { dirtyStore } from './common/confirmationModal/dirtyStore';
43
- import { StandaloneServices } from 'vscode/services';
44
44
  let divEl = null;
45
45
  let editor;
46
46
  export let lang;
@@ -352,9 +352,9 @@ async function closeWebsockets() {
352
352
  websocketInterval && clearInterval(websocketInterval);
353
353
  }
354
354
  async function loadMonaco() {
355
- const model = monaco.editor.createModel(code, lang, monaco.Uri.parse(uri));
355
+ const model = meditor.createModel(code, lang, mUri.parse(uri));
356
356
  model.updateOptions(updateOptions);
357
- editor = monaco.editor.create(divEl, editorConfig(model, code, lang, automaticLayout, fixedOverflowWidgets));
357
+ editor = meditor.create(divEl, editorConfig(model, code, lang, automaticLayout, fixedOverflowWidgets));
358
358
  let timeoutModel = undefined;
359
359
  editor.onDidChangeModelContent((event) => {
360
360
  $dirtyStore = true;
@@ -366,11 +366,11 @@ async function loadMonaco() {
366
366
  });
367
367
  editor.onDidFocusEditorText(() => {
368
368
  dispatch('focus');
369
- editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
369
+ editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyS, function () {
370
370
  code = getCode();
371
371
  shouldBindKey && format && format();
372
372
  });
373
- editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, function () {
373
+ editor.addCommand(KeyMod.CtrlCmd | KeyCode.Enter, function () {
374
374
  code = getCode();
375
375
  shouldBindKey && cmdEnterAction && cmdEnterAction();
376
376
  });
@@ -1,5 +1,5 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import * as monaco from 'monaco-editor';
2
+ import { editor as meditor } from 'monaco-editor';
3
3
  declare const __propDef: {
4
4
  props: {
5
5
  [x: string]: any;
@@ -24,7 +24,7 @@ declare const __propDef: {
24
24
  setCode?: ((ncode: string) => void) | undefined;
25
25
  clearContent?: (() => Promise<void>) | undefined;
26
26
  reloadWebsocket?: (() => Promise<void>) | undefined;
27
- addAction?: ((id: string, label: string, callback: (editor: monaco.editor.IStandaloneCodeEditor) => void, keybindings?: number[]) => void) | undefined;
27
+ addAction?: ((id: string, label: string, callback: (editor: meditor.IStandaloneCodeEditor) => void, keybindings?: number[]) => void) | undefined;
28
28
  };
29
29
  events: {
30
30
  change: CustomEvent<any>;
@@ -46,6 +46,6 @@ export default class Editor extends SvelteComponentTyped<EditorProps, EditorEven
46
46
  get setCode(): (ncode: string) => void;
47
47
  get clearContent(): () => Promise<void>;
48
48
  get reloadWebsocket(): () => Promise<void>;
49
- get addAction(): (id: string, label: string, callback: (editor: monaco.editor.IStandaloneCodeEditor) => void, keybindings?: number[]) => void;
49
+ get addAction(): (id: string, label: string, callback: (editor: meditor.IStandaloneCodeEditor) => void, keybindings?: number[]) => void;
50
50
  }
51
51
  export {};
@@ -16,7 +16,7 @@ export let previewMode;
16
16
  export let open;
17
17
  export let jobId = undefined;
18
18
  export let job = undefined;
19
- let isValid = false;
19
+ let isValid = true;
20
20
  let isRunning = false;
21
21
  let jobProgressReset;
22
22
  const { selectedId, previewArgs } = getContext('FlowEditorContext');
@@ -89,7 +89,7 @@ $: if (job?.type === 'CompletedJob') {
89
89
  <div class="flex flex-row justify-between w-full items-center gap-x-2">
90
90
  <button
91
91
  on:click={() => dispatch('close')}
92
- class="hover:bg-gray-200 bg-gray-100 rounded-full w-8 h-8 flex items-center justify-center transition-all"
92
+ class="hover:bg-gray-200 bg-gray-100 rounded-full w-16 h-8 flex items-center justify-center transition-all"
93
93
  >
94
94
  <Icon data={faClose} class="text-gray-500" />
95
95
  </button>
@@ -1,9 +1,9 @@
1
1
  <script>import { FlowStatusModule, Job, JobService } from '../gen';
2
- import { workspaceStore } from '../stores';
2
+ import { userStore, workspaceStore } from '../stores';
3
3
  import FlowJobResult from './FlowJobResult.svelte';
4
4
  import FlowPreviewStatus from './preview/FlowPreviewStatus.svelte';
5
5
  import Icon from 'svelte-awesome';
6
- import { faChevronDown, faChevronUp, faHourglassHalf } from '@fortawesome/free-solid-svg-icons';
6
+ import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
7
7
  import { createEventDispatcher } from 'svelte';
8
8
  import { onDestroy } from 'svelte';
9
9
  import { Button, Tab } from './common';
@@ -11,8 +11,10 @@ import DisplayResult from './DisplayResult.svelte';
11
11
  import Tabs from './common/tabs/Tabs.svelte';
12
12
  import { FlowGraph } from './graph';
13
13
  import ModuleStatus from './ModuleStatus.svelte';
14
- import { displayDate, truncateRev } from '../utils';
14
+ import { displayDate, isOwner, pluralize, truncateRev } from '../utils';
15
15
  import JobArgs from './JobArgs.svelte';
16
+ import Tooltip from './Tooltip.svelte';
17
+ import SimpleEditor from './SimpleEditor.svelte';
16
18
  const dispatch = createEventDispatcher();
17
19
  export let jobId;
18
20
  export let flowState = undefined;
@@ -21,6 +23,8 @@ export let job = undefined;
21
23
  export let flowModuleStates = {};
22
24
  let localFlowModuleStates = {};
23
25
  export let retry_status = {};
26
+ export let suspend_status = undefined;
27
+ export let is_owner = false;
24
28
  let selectedNode = undefined;
25
29
  let jobResults = [];
26
30
  let jobFailures = [];
@@ -44,6 +48,7 @@ $: {
44
48
  }
45
49
  }
46
50
  $: updateFailCount(job?.flow_status?.retry?.fail_count);
51
+ $: suspend_status = job?.flow_status?.modules?.[job?.flow_status.step]?.count;
47
52
  function updateFailCount(count) {
48
53
  if (count) {
49
54
  retry_status[jobId ?? ''] = count;
@@ -103,11 +108,12 @@ async function loadJobInProgress() {
103
108
  }
104
109
  }
105
110
  $: job && dispatch('jobsLoaded', job);
106
- function updateJobId() {
111
+ async function updateJobId() {
107
112
  if (jobId !== job?.id) {
108
113
  retry_status = {};
109
114
  localFlowModuleStates = {};
110
- loadJobInProgress();
115
+ await loadJobInProgress();
116
+ job?.script_path && loadOwner(job.script_path);
111
117
  }
112
118
  }
113
119
  $: jobId && updateJobId();
@@ -115,7 +121,11 @@ $: isListJob = flowJobIds && Array.isArray(flowJobIds?.flowJobs);
115
121
  onDestroy(() => {
116
122
  timeout && clearTimeout(timeout);
117
123
  });
124
+ async function loadOwner(path) {
125
+ is_owner = await isOwner(path, $userStore, $workspaceStore);
126
+ }
118
127
  let selected = 'graph';
128
+ let payload = '"a test payload in json"';
119
129
  </script>
120
130
 
121
131
  {#if job}
@@ -134,6 +144,41 @@ let selected = 'graph';
134
144
  <div class="w-full h-full">
135
145
  <FlowJobResult result={job.result} logs={job.logs ?? ''} />
136
146
  </div>
147
+ {:else if job.flow_status?.modules?.[job?.flow_status?.step].type === FlowStatusModule.type.WAITING_FOR_EVENTS}
148
+ <div class="w-full h-full mt-2 text-sm text-gray-600">
149
+ <p>Waiting for approval from the previous step</p>
150
+ <div>
151
+ {#if is_owner}
152
+ <div class="flex flex-row gap-2 mt-2">
153
+ <div>
154
+ <Button
155
+ color="green"
156
+ variant="border"
157
+ on:click={async () =>
158
+ await JobService.resumeSuspendedFlowAsOwner({
159
+ workspace: $workspaceStore ?? '',
160
+ id: job?.id ?? '',
161
+ requestBody: JSON.parse(payload)
162
+ })}
163
+ >Resume <Tooltip
164
+ >Since you are an owner of this flow, you can send resume events without
165
+ necessarily knowing the resume id sent by the approval step</Tooltip
166
+ ></Button
167
+ >
168
+ </div>
169
+ <div class="w-full border rounded-lg border-gray-600 p-2">
170
+ <SimpleEditor automaticLayout lang="json" bind:code={payload} autoHeight />
171
+ </div>
172
+ <Tooltip
173
+ >The payload is optional, it is passed to the following step through the
174
+ `resume` variable</Tooltip
175
+ >
176
+ </div>
177
+ {:else}
178
+ You cannot resume the job without the resume id since you are not an owner of {job.script_path}
179
+ {/if}
180
+ </div>
181
+ </div>
137
182
  {:else if job.logs}
138
183
  <div class="text-xs p-4 bg-gray-50 overflow-auto max-h-80 border">
139
184
  <pre class="w-full">{job.logs}</pre>
@@ -183,6 +228,7 @@ let selected = 'graph';
183
228
  </Button>
184
229
  <div class="border p-6" class:hidden={forloop_selected != loopJobId}>
185
230
  <svelte:self
231
+ bind:suspend_status
186
232
  bind:retry_status
187
233
  bind:flowState
188
234
  bind:flowModuleStates={localFlowModuleStates}
@@ -254,6 +300,7 @@ let selected = 'graph';
254
300
  <li class="w-full border border-gray-600 p-6 space-y-2 bg-blue-50/50">
255
301
  {#if [FlowStatusModule.type.IN_PROGRESS, FlowStatusModule.type.SUCCESS, FlowStatusModule.type.FAILURE].includes(mod.type)}
256
302
  <svelte:self
303
+ bind:suspend_status
257
304
  bind:retry_status
258
305
  bind:flowState
259
306
  bind:flowModuleStates={localFlowModuleStates}
@@ -314,6 +361,11 @@ let selected = 'graph';
314
361
  Retry in progress, # of failed attempts: {count}
315
362
  </span>
316
363
  {/each}
364
+ {#if suspend_status}
365
+ <span class="text-sm">
366
+ Flow suspended, waiting for {pluralize(suspend_status, 'approval')}
367
+ </span>
368
+ {/if}
317
369
  </div>
318
370
 
319
371
  <FlowGraph
@@ -13,6 +13,8 @@ declare const __propDef: {
13
13
  job?: Job | undefined;
14
14
  flowModuleStates?: Record<string, GraphModuleState> | undefined;
15
15
  retry_status?: Record<string, number> | undefined;
16
+ suspend_status?: number | undefined;
17
+ is_owner?: boolean | undefined;
16
18
  };
17
19
  events: {
18
20
  jobsLoaded: CustomEvent<any>;
@@ -8,7 +8,7 @@ import { Button, ToggleButton, ToggleButtonGroup } from './common';
8
8
  import { faCode } from '@fortawesome/free-solid-svg-icons';
9
9
  import TemplateEditor from './TemplateEditor.svelte';
10
10
  import Tooltip from './Tooltip.svelte';
11
- import { escape } from 'svelte/internal';
11
+ import { setInputCat as computeInputCat } from '../utils';
12
12
  export let schema;
13
13
  export let arg;
14
14
  export let argName;
@@ -18,9 +18,10 @@ export let previousModuleId;
18
18
  export let pickForField = undefined;
19
19
  export let variableEditor = undefined;
20
20
  export let itemPicker = undefined;
21
- export let monaco = undefined;
21
+ let monaco = undefined;
22
+ let monacoTemplate = undefined;
22
23
  let argInput = undefined;
23
- let inputCat = 'object';
24
+ let inputCat = computeInputCat(schema.properties[argName].type, schema.properties[argName].format, schema.properties[argName].items?.type, schema.properties[argName].enum, schema.properties[argName].contentEncoding);
24
25
  let propertyType = getPropertyType(arg);
25
26
  function getPropertyType(arg) {
26
27
  let type = arg?.type ?? 'static';
@@ -58,6 +59,7 @@ function connectProperty(rawValue) {
58
59
  if (isStaticTemplate(inputCat)) {
59
60
  arg.value = `\$\{${rawValue}}`;
60
61
  setPropertyType(arg.value);
62
+ monacoTemplate?.setCode(arg.value);
61
63
  }
62
64
  else {
63
65
  arg.expr = getDefaultExpr(undefined, previousModuleId, rawValue);
@@ -71,6 +73,7 @@ function onFocus() {
71
73
  focusProp(argName, 'append', (path) => {
72
74
  const toAppend = `\$\{${path}}`;
73
75
  arg.value = `${arg.value ?? ''}${toAppend}`;
76
+ monacoTemplate?.setCode(arg.value);
74
77
  setPropertyType(arg.value);
75
78
  argInput?.focus();
76
79
  return false;
@@ -203,8 +206,13 @@ const closeBracket = '}';
203
206
  </span>
204
207
  {/if}
205
208
  {#if isStaticTemplate(inputCat) && propertyType == 'static'}
206
- <div class="py-1">
207
- <TemplateEditor {extraLib} on:focus={onFocus} bind:code={arg.value} />
209
+ <div class="py-1 rounded border border-1 border-gray-500">
210
+ <TemplateEditor
211
+ bind:this={monacoTemplate}
212
+ {extraLib}
213
+ on:focus={onFocus}
214
+ bind:code={arg.value}
215
+ />
208
216
  </div>
209
217
  {:else if propertyType === undefined || propertyType == 'static'}
210
218
  <ArgInput
@@ -1,6 +1,5 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import type { Schema } from '../common';
3
- import SimpleEditor from './SimpleEditor.svelte';
4
3
  import type VariableEditor from './VariableEditor.svelte';
5
4
  import type ItemPicker from './ItemPicker.svelte';
6
5
  import type { InputTransform } from '../gen';
@@ -15,7 +14,6 @@ declare const __propDef: {
15
14
  pickForField?: string | undefined;
16
15
  variableEditor?: VariableEditor | undefined;
17
16
  itemPicker?: ItemPicker | undefined;
18
- monaco?: SimpleEditor | undefined;
19
17
  };
20
18
  events: {
21
19
  [evt: string]: CustomEvent<any>;
@@ -1,4 +1,5 @@
1
- <script>import { getScriptByPath, sendUserToast, truncateRev } from '../utils';
1
+ <script>import { ScriptService } from '../gen';
2
+ import { getScriptByPath, sendUserToast, truncateRev } from '../utils';
2
3
  import { Pane, Splitpanes } from 'svelte-splitpanes';
3
4
  import RunForm from './RunForm.svelte';
4
5
  import TestJobLoader from './TestJobLoader.svelte';
@@ -9,6 +10,7 @@ import { faRotateRight } from '@fortawesome/free-solid-svg-icons';
9
10
  import { flowStateStore } from './flows/flowState';
10
11
  import { flowStore } from './flows/flowStore';
11
12
  import { Alert } from './common';
13
+ import { workspaceStore } from '../stores';
12
14
  let testJobLoader;
13
15
  // Test
14
16
  let testIsLoading = false;
@@ -25,7 +27,9 @@ export async function runTest(args) {
25
27
  await testJobLoader?.runPreview(val.path, val.content, val.language, args);
26
28
  }
27
29
  else if (val.type == 'script') {
28
- const script = await getScriptByPath(val.path);
30
+ const script = val.hash
31
+ ? await ScriptService.getScriptByHash({ workspace: $workspaceStore, hash: val.hash })
32
+ : await getScriptByPath(val.path);
29
33
  await testJobLoader?.runPreview(val.path, script.content, script.language, args);
30
34
  }
31
35
  else {
@@ -1,6 +1,6 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import type { Schema } from '../common';
3
- import type { FlowModule } from '../gen';
3
+ import { type FlowModule } from '../gen';
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  mod: FlowModule;
@@ -120,7 +120,7 @@ let invisible_to_owner;
120
120
  </div>
121
121
  {/if}
122
122
  {#if schedulable}
123
- <div class="flex justify-between mt-2 md:mt-6 mb-6">
123
+ <div class="flex gap-2 items-center flex-wrap justify-between mt-2 md:mt-6 mb-6">
124
124
  <Button
125
125
  color="light"
126
126
  size="sm"
@@ -142,13 +142,15 @@ let invisible_to_owner;
142
142
  >
143
143
  </div>
144
144
  {/if}
145
- <Button
146
- btnClasses="!px-6 !py-1"
147
- disabled={!isValid}
148
- on:click={() => runAction(scheduledForStr, args, invisible_to_owner)}
149
- >
150
- {scheduledForStr ? 'Schedule run to a later time' : buttonText}
151
- </Button>
145
+ <div class="flex-row-reverse flex grow">
146
+ <Button
147
+ btnClasses="!px-6 !py-1"
148
+ disabled={!isValid}
149
+ on:click={() => runAction(scheduledForStr, args, invisible_to_owner)}
150
+ >
151
+ {scheduledForStr ? 'Schedule run to a later time' : buttonText}
152
+ </Button>
153
+ </div>
152
154
  </div>
153
155
  {:else if !topButton}
154
156
  <Button
@@ -6,7 +6,7 @@
6
6
  }
7
7
  </script>
8
8
 
9
- <script>import { sendUserToast, formatCron, canWrite } from '../utils';
9
+ <script>import { sendUserToast, formatCron, canWrite, emptyString } from '../utils';
10
10
  import { ScriptService, Script, ScheduleService, FlowService } from '../gen';
11
11
  import Toggle from './Toggle.svelte';
12
12
  import Path from './Path.svelte';
@@ -151,7 +151,7 @@ let drawer;
151
151
  {/if}
152
152
  <Button
153
153
  startIcon={{ icon: faSave }}
154
- disabled={!allowSchedule || pathError != ''}
154
+ disabled={!allowSchedule || pathError != '' || emptyString(script_path)}
155
155
  on:click={scheduleScript}
156
156
  >
157
157
  {edit ? 'Save' : 'Schedule'}
@@ -1,26 +1,24 @@
1
- <script context="module">import * as monaco from 'monaco-editor';
1
+ <script>import { browser, dev } from '$app/environment';
2
+ import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
3
+ import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
4
+ import yamlWorker from 'monaco-yaml/yaml.worker?worker';
5
+ import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
6
+ import { buildWorkerDefinition } from 'monaco-editor-workers';
7
+ import { createEventDispatcher, onDestroy, onMount } from 'svelte';
8
+ import { createHash, editorConfig, langToExt, updateOptions } from '../editorUtils';
9
+ import { languages, editor as meditor, KeyCode, KeyMod, Uri as mUri } from 'monaco-editor';
2
10
  import libStdContent from '../es5.d.ts.txt?raw';
3
- monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
4
- target: monaco.languages.typescript.ScriptTarget.Latest,
11
+ languages.typescript.javascriptDefaults.setCompilerOptions({
12
+ target: languages.typescript.ScriptTarget.Latest,
5
13
  allowNonTsExtensions: true,
6
14
  noLib: true
7
15
  });
8
- monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
16
+ languages.json.jsonDefaults.setDiagnosticsOptions({
9
17
  validate: true,
10
18
  allowComments: false,
11
19
  schemas: [],
12
20
  enableSchemaRequest: true
13
21
  });
14
- </script>
15
-
16
- <script>import { browser, dev } from '$app/env';
17
- import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
18
- import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
19
- import yamlWorker from 'monaco-yaml/yaml.worker?worker';
20
- import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
21
- import { buildWorkerDefinition } from 'monaco-editor-workers';
22
- import { createEventDispatcher, onDestroy, onMount } from 'svelte';
23
- import { createHash, editorConfig, langToExt, updateOptions } from '../editorUtils';
24
22
  let divEl = null;
25
23
  let editor;
26
24
  let model;
@@ -86,9 +84,9 @@ function format() {
86
84
  }
87
85
  let width = 0;
88
86
  async function loadMonaco() {
89
- model = monaco.editor.createModel(code, lang, monaco.Uri.parse(uri));
87
+ model = meditor.createModel(code, lang, mUri.parse(uri));
90
88
  model.updateOptions(updateOptions);
91
- editor = monaco.editor.create(divEl, editorConfig(model, code, lang, automaticLayout, fixedOverflowWidgets));
89
+ editor = meditor.create(divEl, editorConfig(model, code, lang, automaticLayout, fixedOverflowWidgets));
92
90
  let timeoutModel = undefined;
93
91
  editor.onDidChangeModelContent((event) => {
94
92
  timeoutModel && clearTimeout(timeoutModel);
@@ -116,11 +114,11 @@ async function loadMonaco() {
116
114
  updateHeight();
117
115
  }
118
116
  editor.onDidFocusEditorText(() => {
119
- editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
117
+ editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyS, function () {
120
118
  code = getCode();
121
119
  shouldBindKey && format && format();
122
120
  });
123
- editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, function () {
121
+ editor.addCommand(KeyMod.CtrlCmd | KeyCode.Enter, function () {
124
122
  code = getCode();
125
123
  shouldBindKey && cmdEnterAction && cmdEnterAction();
126
124
  });
@@ -133,7 +131,7 @@ async function loadMonaco() {
133
131
  if (lang == 'javascript') {
134
132
  const stdLib = { content: libStdContent, filePath: 'es5.d.ts' };
135
133
  if (extraLib != '') {
136
- monaco.languages.typescript.javascriptDefaults.setExtraLibs([
134
+ languages.typescript.javascriptDefaults.setExtraLibs([
137
135
  {
138
136
  content: extraLib,
139
137
  filePath: 'windmill.d.ts'
@@ -142,7 +140,7 @@ async function loadMonaco() {
142
140
  ]);
143
141
  }
144
142
  else {
145
- monaco.languages.typescript.javascriptDefaults.setExtraLibs([stdLib]);
143
+ languages.typescript.javascriptDefaults.setExtraLibs([stdLib]);
146
144
  }
147
145
  }
148
146
  }