windmill-components 1.35.42 → 1.36.0

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 (245) hide show
  1. package/components/AppConnect.svelte +85 -59
  2. package/components/ArgInput.svelte +50 -33
  3. package/components/ArgInput.svelte.d.ts +1 -1
  4. package/components/Button.svelte +15 -48
  5. package/components/Button.svelte.d.ts +1 -1
  6. package/components/CronInput.svelte +1 -1
  7. package/components/DisplayResult.svelte +75 -67
  8. package/components/Dropdown.svelte +9 -7
  9. package/components/Editor.svelte +187 -178
  10. package/components/Editor.svelte.d.ts +4 -2
  11. package/components/EditorBar.svelte +135 -98
  12. package/components/EditorBar.svelte.d.ts +2 -1
  13. package/components/FlowBuilder.svelte +115 -134
  14. package/components/FlowJobResult.svelte +4 -5
  15. package/components/FlowModulesViewer.svelte +89 -7
  16. package/components/FlowModulesViewer.svelte.d.ts +1 -0
  17. package/components/FlowPreviewContent.svelte +88 -27
  18. package/components/FlowPreviewContent.svelte.d.ts +1 -1
  19. package/components/FlowStatusViewer.svelte +39 -24
  20. package/components/FlowStatusViewer.svelte.d.ts +0 -1
  21. package/components/FlowViewer.svelte +17 -11
  22. package/components/GroupModal.svelte +10 -1
  23. package/components/HighlightCode.svelte +22 -0
  24. package/components/HighlightCode.svelte.d.ts +17 -0
  25. package/components/IconedPath.svelte +9 -7
  26. package/components/InputTransformForm.svelte +97 -115
  27. package/components/InputTransformForm.svelte.d.ts +0 -1
  28. package/components/InputTransformsViewer.svelte +1 -1
  29. package/components/InviteGlobalUser.svelte +8 -8
  30. package/components/InviteUser.svelte +9 -9
  31. package/components/ItemPicker.svelte +37 -30
  32. package/components/ItemPicker.svelte.d.ts +2 -1
  33. package/components/JobStatus.svelte +2 -1
  34. package/components/LogViewer.svelte +23 -0
  35. package/components/LogViewer.svelte.d.ts +19 -0
  36. package/components/ModulePreview.svelte +107 -0
  37. package/components/ModulePreview.svelte.d.ts +24 -0
  38. package/components/Path.svelte +1 -1
  39. package/components/RadioButton.svelte +3 -2
  40. package/components/ResourceEditor.svelte +22 -34
  41. package/components/ResourceTypePicker.svelte +23 -34
  42. package/components/RunForm.svelte +34 -31
  43. package/components/RunForm.svelte.d.ts +6 -2
  44. package/components/SchemaEditor.svelte +19 -11
  45. package/components/SchemaForm.svelte +3 -3
  46. package/components/SchemaForm.svelte.d.ts +1 -1
  47. package/components/SchemaModal.svelte +18 -7
  48. package/components/ScriptBuilder.svelte +99 -83
  49. package/components/ScriptBuilder.svelte.d.ts +2 -4
  50. package/components/ScriptEditor.svelte +71 -143
  51. package/components/ScriptEditor.svelte.d.ts +0 -5
  52. package/components/ScriptPicker.svelte +24 -14
  53. package/components/ScriptPicker.svelte.d.ts +2 -1
  54. package/components/ScriptSchema.svelte +8 -11
  55. package/components/ScriptSchema.svelte.d.ts +0 -1
  56. package/components/ShareModal.svelte +6 -6
  57. package/components/SharedBadge.svelte +5 -13
  58. package/components/SimpleEditor.svelte +14 -10
  59. package/components/StringTypeNarrowing.svelte +24 -30
  60. package/components/TestJobLoader.svelte +106 -0
  61. package/components/TestJobLoader.svelte.d.ts +26 -0
  62. package/components/Tooltip.svelte +3 -2
  63. package/components/VariableEditor.svelte +15 -24
  64. package/components/common/actionRow/ActionRow.svelte +31 -0
  65. package/components/common/actionRow/ActionRow.svelte.d.ts +22 -0
  66. package/components/common/alert/Alert.svelte +53 -0
  67. package/components/common/alert/Alert.svelte.d.ts +20 -0
  68. package/components/common/alert/model.d.ts +1 -0
  69. package/components/common/alert/model.js +1 -0
  70. package/components/common/badge/Badge.svelte +76 -0
  71. package/components/common/badge/Badge.svelte.d.ts +28 -0
  72. package/components/common/badge/model.d.ts +8 -0
  73. package/components/common/badge/model.js +1 -0
  74. package/components/common/button/Button.svelte +110 -0
  75. package/components/common/button/Button.svelte.d.ts +39 -0
  76. package/components/common/button/model.d.ts +6 -0
  77. package/components/common/button/model.js +1 -0
  78. package/components/common/confirmationModal/ConfirmationModal.svelte +72 -0
  79. package/components/common/confirmationModal/ConfirmationModal.svelte.d.ts +23 -0
  80. package/components/common/confirmationModal/UnsavedConfirmationModal.svelte +41 -0
  81. package/components/common/confirmationModal/UnsavedConfirmationModal.svelte.d.ts +14 -0
  82. package/components/common/confirmationModal/dirtyStore.d.ts +1 -0
  83. package/components/common/confirmationModal/dirtyStore.js +2 -0
  84. package/components/common/drawer/Drawer.svelte +3 -0
  85. package/components/common/drawer/Drawer.svelte.d.ts +2 -0
  86. package/components/common/index.d.ts +14 -0
  87. package/components/common/index.js +14 -0
  88. package/components/common/tabs/TabContent.svelte +3 -2
  89. package/components/common/tabs/TabContent.svelte.d.ts +1 -0
  90. package/components/common/tabs/Tabs.svelte +8 -1
  91. package/components/common/tabs/Tabs.svelte.d.ts +2 -0
  92. package/components/common/toggleButton/ToggleButton.svelte +20 -0
  93. package/components/common/toggleButton/ToggleButton.svelte.d.ts +19 -0
  94. package/components/common/toggleButton/ToggleButtonGroup.svelte +33 -0
  95. package/components/common/toggleButton/ToggleButtonGroup.svelte.d.ts +24 -0
  96. package/components/flows/FlowEditor.svelte +30 -0
  97. package/components/{FlowEditor.svelte.d.ts → flows/FlowEditor.svelte.d.ts} +1 -6
  98. package/components/flows/common/FlowCard.svelte +9 -0
  99. package/components/flows/common/FlowCard.svelte.d.ts +21 -0
  100. package/components/flows/common/FlowCardHeader.svelte +39 -0
  101. package/components/flows/common/FlowCardHeader.svelte.d.ts +20 -0
  102. package/components/flows/content/CopyFirstStepSchema.svelte +13 -0
  103. package/components/flows/{CopyFirstStepSchema.svelte.d.ts → content/CopyFirstStepSchema.svelte.d.ts} +0 -0
  104. package/components/flows/{DynamicInputHelpBox.svelte → content/DynamicInputHelpBox.svelte} +0 -0
  105. package/components/flows/{DynamicInputHelpBox.svelte.d.ts → content/DynamicInputHelpBox.svelte.d.ts} +0 -0
  106. package/components/flows/content/FlowEditorPanel.svelte +25 -0
  107. package/components/flows/content/FlowEditorPanel.svelte.d.ts +16 -0
  108. package/components/flows/content/FlowFailureModule.svelte +15 -0
  109. package/components/flows/content/FlowFailureModule.svelte.d.ts +14 -0
  110. package/components/flows/content/FlowInput.svelte +26 -0
  111. package/components/flows/{FlowInput.svelte.d.ts → content/FlowInput.svelte.d.ts} +0 -0
  112. package/components/flows/content/FlowInputs.svelte +91 -0
  113. package/components/flows/{FlowInputs.svelte.d.ts → content/FlowInputs.svelte.d.ts} +1 -0
  114. package/components/flows/content/FlowLoop.svelte +168 -0
  115. package/components/flows/content/FlowLoop.svelte.d.ts +18 -0
  116. package/components/flows/content/FlowLoopWrapper.svelte +9 -0
  117. package/components/flows/content/FlowLoopWrapper.svelte.d.ts +14 -0
  118. package/components/flows/content/FlowModule.svelte +211 -0
  119. package/components/flows/content/FlowModule.svelte.d.ts +29 -0
  120. package/components/flows/content/FlowModuleEarlyStop.svelte +76 -0
  121. package/components/flows/content/FlowModuleEarlyStop.svelte.d.ts +17 -0
  122. package/components/flows/content/FlowModuleHeader.svelte +157 -0
  123. package/components/flows/{FlowModuleHeader.svelte.d.ts → content/FlowModuleHeader.svelte.d.ts} +5 -3
  124. package/components/flows/content/FlowModuleScript.svelte +21 -0
  125. package/components/flows/content/FlowModuleScript.svelte.d.ts +17 -0
  126. package/components/flows/content/FlowModuleSuspend.svelte +27 -0
  127. package/components/flows/content/FlowModuleSuspend.svelte.d.ts +17 -0
  128. package/components/flows/content/FlowModuleWrapper.svelte +45 -0
  129. package/components/flows/content/FlowModuleWrapper.svelte.d.ts +14 -0
  130. package/components/flows/content/FlowRetries.svelte +80 -0
  131. package/components/flows/content/FlowRetries.svelte.d.ts +17 -0
  132. package/components/flows/content/FlowSchedules.svelte +18 -0
  133. package/components/flows/content/FlowSchedules.svelte.d.ts +14 -0
  134. package/components/flows/content/FlowSettings.svelte +78 -0
  135. package/components/flows/{FlowSettings.svelte.d.ts → content/FlowSettings.svelte.d.ts} +2 -6
  136. package/components/flows/content/RemoveStepConfirmationModal.svelte +32 -0
  137. package/components/flows/content/RemoveStepConfirmationModal.svelte.d.ts +19 -0
  138. package/components/flows/flowState.d.ts +8 -7
  139. package/components/flows/flowState.js +25 -46
  140. package/components/flows/flowStateUtils.d.ts +16 -14
  141. package/components/flows/flowStateUtils.js +81 -73
  142. package/components/flows/flowStore.js +7 -4
  143. package/components/flows/header/FlowImportExportMenu.svelte +55 -0
  144. package/components/flows/header/FlowImportExportMenu.svelte.d.ts +14 -0
  145. package/components/flows/header/FlowPreviewButtons.svelte +57 -0
  146. package/components/flows/header/FlowPreviewButtons.svelte.d.ts +14 -0
  147. package/components/flows/map/FlowErrorHandlerItem.svelte +60 -0
  148. package/components/flows/map/FlowErrorHandlerItem.svelte.d.ts +14 -0
  149. package/components/flows/map/FlowModuleSchemaItem.svelte +80 -0
  150. package/components/flows/map/FlowModuleSchemaItem.svelte.d.ts +32 -0
  151. package/components/flows/map/FlowModuleSchemaMap.svelte +241 -0
  152. package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +20 -0
  153. package/components/flows/pickers/PickHubScript.svelte +5 -3
  154. package/components/flows/pickers/PickHubScript.svelte.d.ts +2 -1
  155. package/components/flows/pickers/PickScript.svelte +4 -12
  156. package/components/flows/pickers/PickScript.svelte.d.ts +1 -1
  157. package/components/flows/propPicker/PropPickerWrapper.svelte +44 -0
  158. package/components/flows/propPicker/PropPickerWrapper.svelte.d.ts +33 -0
  159. package/components/flows/scheduleUtils.d.ts +0 -1
  160. package/components/flows/scheduleUtils.js +0 -1
  161. package/components/flows/types.d.ts +8 -0
  162. package/components/flows/types.js +1 -0
  163. package/components/flows/utils.d.ts +3 -1
  164. package/components/flows/utils.js +26 -10
  165. package/components/icons/AirtableIcon.svelte +1 -1
  166. package/components/icons/DiscordIcon.svelte +1 -1
  167. package/components/icons/GCloudIcon.svelte +1 -1
  168. package/components/icons/GItlabIcon.svelte +1 -1
  169. package/components/icons/GSheetsIcon.svelte +1 -1
  170. package/components/icons/GcalIcon.svelte +1 -1
  171. package/components/icons/GdriveIcon.svelte +1 -1
  172. package/components/icons/GithubIcon.svelte +1 -1
  173. package/components/icons/GmailIcon.svelte +1 -1
  174. package/components/icons/HatIcon.svelte +19 -0
  175. package/components/icons/HatIcon.svelte.d.ts +16 -0
  176. package/components/icons/MastodonIcon.svelte +1 -1
  177. package/components/icons/MatrixIcon.svelte +1 -1
  178. package/components/icons/PostgresIcon.svelte +1 -1
  179. package/components/icons/S3Icon.svelte +1 -1
  180. package/components/icons/Slack.svelte +1 -1
  181. package/components/icons/TogglIcon.svelte +8 -46
  182. package/components/jobs/JobDetail.svelte +1 -1
  183. package/components/landing/FlowGettingStarted.svelte +22 -68
  184. package/components/landing/FlowLandingBox.svelte +1 -1
  185. package/components/landing/RessourceGettingStarted.svelte +7 -37
  186. package/components/landing/ScriptBox.svelte +33 -60
  187. package/components/landing/ScriptGettingStarted.svelte +23 -69
  188. package/components/propertyPicker/ObjectViewer.svelte +18 -12
  189. package/components/propertyPicker/ObjectViewer.svelte.d.ts +1 -0
  190. package/components/propertyPicker/PropPicker.svelte +108 -11
  191. package/components/propertyPicker/WarningMessage.svelte +2 -15
  192. package/components/script_editor/LogPanel.svelte +108 -119
  193. package/components/script_editor/LogPanel.svelte.d.ts +2 -0
  194. package/components/sidebar/SidebarContent.svelte +2 -2
  195. package/editorUtils.d.ts +3 -0
  196. package/editorUtils.js +1 -0
  197. package/gen/core/OpenAPI.js +1 -1
  198. package/gen/index.d.ts +1 -0
  199. package/gen/models/CompletedJob.d.ts +2 -1
  200. package/gen/models/CompletedJob.js +1 -0
  201. package/gen/models/FlowModule.d.ts +3 -0
  202. package/gen/models/FlowStatus.d.ts +3 -0
  203. package/gen/models/FlowStatusModule.d.ts +1 -1
  204. package/gen/models/Preview.d.ts +2 -1
  205. package/gen/models/Preview.js +1 -0
  206. package/gen/models/QueuedJob.d.ts +2 -1
  207. package/gen/models/QueuedJob.js +1 -0
  208. package/gen/models/RawScript.d.ts +2 -1
  209. package/gen/models/RawScript.js +1 -0
  210. package/gen/models/Retry.d.ts +11 -0
  211. package/gen/models/Retry.js +4 -0
  212. package/gen/models/Script.d.ts +9 -2
  213. package/gen/models/Script.js +8 -0
  214. package/gen/services/JobService.d.ts +40 -0
  215. package/gen/services/JobService.js +70 -0
  216. package/gen/services/ScriptService.d.ts +14 -3
  217. package/gen/services/ScriptService.js +13 -0
  218. package/infer.d.ts +1 -1
  219. package/infer.js +6 -1
  220. package/package.json +71 -38
  221. package/script_helpers.d.ts +8 -2
  222. package/script_helpers.js +88 -16
  223. package/stores.d.ts +1 -1
  224. package/utils.d.ts +8 -6
  225. package/utils.js +57 -21
  226. package/components/FlowEditor.svelte +0 -55
  227. package/components/FlowPreview.svelte +0 -107
  228. package/components/FlowPreview.svelte.d.ts +0 -23
  229. package/components/ModuleStep.svelte +0 -131
  230. package/components/ModuleStep.svelte.d.ts +0 -25
  231. package/components/flows/CopyFirstStepSchema.svelte +0 -13
  232. package/components/flows/FlowBox.svelte +0 -16
  233. package/components/flows/FlowBox.svelte.d.ts +0 -23
  234. package/components/flows/FlowBoxHeader.svelte +0 -16
  235. package/components/flows/FlowBoxHeader.svelte.d.ts +0 -21
  236. package/components/flows/FlowInput.svelte +0 -22
  237. package/components/flows/FlowInputs.svelte +0 -65
  238. package/components/flows/FlowModuleHeader.svelte +0 -109
  239. package/components/flows/FlowSettings.svelte +0 -165
  240. package/components/flows/FlowTimeline.svelte +0 -169
  241. package/components/flows/FlowTimeline.svelte.d.ts +0 -21
  242. package/components/flows/stepOpenedStore.d.ts +0 -1
  243. package/components/flows/stepOpenedStore.js +0 -6
  244. package/components/propertyPicker/OverlayPropertyPicker.svelte +0 -69
  245. package/components/propertyPicker/OverlayPropertyPicker.svelte.d.ts +0 -24
@@ -1,12 +1,11 @@
1
- <script>import { ScriptService } from '../gen';
1
+ <script>import { Script, ScriptService } from '../gen';
2
2
  import { goto } from '$app/navigation';
3
3
  import { page } from '$app/stores';
4
4
  import { inferArgs } from '../infer';
5
- import { DENO_INIT_CODE, DENO_INIT_CODE_TRIGGER, initialCode, POSTGRES_INIT_CODE } from '../script_helpers';
5
+ import { initialCode, isInitialCode } from '../script_helpers';
6
6
  import { workspaceStore } from '../stores';
7
- import { emptySchema, encodeState, sendUserToast, setQueryWithoutLoad } from '../utils';
7
+ import { encodeState, sendUserToast, setQueryWithoutLoad } from '../utils';
8
8
  import { Breadcrumb, BreadcrumbItem } from 'flowbite-svelte';
9
- import { onDestroy } from 'svelte';
10
9
  import SvelteMarkdown from 'svelte-markdown';
11
10
  import Path from './Path.svelte';
12
11
  import RadioButton from './RadioButton.svelte';
@@ -14,27 +13,28 @@ import Required from './Required.svelte';
14
13
  import ScriptEditor from './ScriptEditor.svelte';
15
14
  import ScriptSchema from './ScriptSchema.svelte';
16
15
  import CenteredPage from './CenteredPage.svelte';
17
- let editor;
18
- let scriptSchema;
16
+ import Tooltip from './Tooltip.svelte';
17
+ import UnsavedConfirmationModal from './common/confirmationModal/UnsavedConfirmationModal.svelte';
18
+ import { dirtyStore } from './common/confirmationModal/dirtyStore';
19
+ import { Button } from './common';
19
20
  export let script;
20
21
  export let initialPath = '';
21
- export let template = undefined;
22
+ export let template = 'script';
22
23
  let pathError = '';
23
24
  $: setQueryWithoutLoad($page.url, 'state', encodeState(script));
24
25
  $: step = Number($page.url.searchParams.get('step')) || 1;
25
- $: {
26
- if (script.language == 'python3') {
27
- script.is_trigger = false;
28
- }
29
- }
30
26
  if (script.content == '') {
31
- initContent(script.language, template);
27
+ initContent(script.language, script.kind, template);
32
28
  }
33
- function initContent(language, template) {
34
- script.content = initialCode(language, template == 'pgsql' ? 'pgsql' : script.is_trigger ? 'trigger' : undefined);
29
+ function initContent(language, kind, template) {
30
+ script.content = initialCode(language, kind, template);
35
31
  }
36
32
  async function editScript() {
37
33
  try {
34
+ $dirtyStore = false;
35
+ if (!script.schema) {
36
+ await inferArgs(script.language, script.content, script.schema);
37
+ }
38
38
  const newHash = await ScriptService.createScript({
39
39
  workspace: $workspaceStore,
40
40
  requestBody: {
@@ -46,7 +46,7 @@ async function editScript() {
46
46
  schema: script.schema,
47
47
  is_template: script.is_template,
48
48
  language: script.language,
49
- is_trigger: script.is_trigger
49
+ kind: script.kind
50
50
  }
51
51
  });
52
52
  sendUserToast(`Success! New script version created with hash ${newHash}`);
@@ -56,33 +56,15 @@ async function editScript() {
56
56
  sendUserToast(`Impossible to save the script: ${error.body}`, true);
57
57
  }
58
58
  }
59
- export function setCode(script) {
60
- editor?.getEditor().setCode(script.content);
61
- if (scriptSchema) {
62
- if (script.schema) {
63
- scriptSchema.setSchema(script.schema);
64
- }
65
- else {
66
- scriptSchema.setSchema(emptySchema());
67
- }
68
- }
69
- }
70
- async function inferSchema() {
71
- await inferArgs(script.language, script.content, script.schema);
72
- }
73
59
  async function changeStep(step) {
74
- if (step == 3) {
75
- script.content = editor?.getEditor().getCode() ?? script.content;
76
- await inferSchema();
77
- script.schema = script.schema;
60
+ if (step > 1) {
61
+ await inferArgs(script.language, script.content, script.schema);
78
62
  }
79
63
  goto(`?step=${step}`);
80
64
  }
81
- onDestroy(() => {
82
- editor?.$destroy();
83
- });
84
65
  </script>
85
66
 
67
+ <UnsavedConfirmationModal />
86
68
  <div class="flex flex-col h-screen">
87
69
  <!-- Nav between steps-->
88
70
  <div class="flex flex-col w-full px-4 py-2 border-b shadow-sm">
@@ -116,38 +98,37 @@ onDestroy(() => {
116
98
  </div>
117
99
  <div class="flex flex-row-reverse ml-2">
118
100
  {#if step != 3}
119
- <button
120
- disabled={step == 1 && pathError != ''}
121
- class="default-button px-6 max-h-8"
122
- on:click={() => {
123
- changeStep(step + 1)
124
- }}
101
+ <Button
102
+ size="sm"
103
+ disabled={step === 1 && pathError !== ''}
104
+ on:click={() => changeStep(step + 1)}
125
105
  >
126
106
  Next
127
- </button>
107
+ </Button>
128
108
  {:else}
129
- <button class="default-button px-6 self-end" on:click={editScript}>Save</button>
109
+ <Button size="sm" on:click={editScript}>Save</Button>
130
110
  {/if}
131
111
  {#if step > 1}
132
- <button
133
- class="default-button-secondary px-6 max-h-8 mr-2"
134
- on:click={async () => {
135
- changeStep(step - 1)
136
- }}
112
+ <Button
113
+ variant="border"
114
+ size="sm"
115
+ btnClasses="mr-2"
116
+ on:click={() => changeStep(step - 1)}
137
117
  >
138
118
  Back
139
- </button>
119
+ </Button>
140
120
  {/if}
141
121
  {#if step == 2}
142
- <button
143
- class="default-button-secondary px-6 max-h-8 mr-2"
122
+ <Button
123
+ variant="border"
124
+ size="sm"
125
+ btnClasses="mr-2"
144
126
  on:click={async () => {
145
- await inferSchema()
146
127
  editScript()
147
128
  }}
148
129
  >
149
130
  Save (commit)
150
- </button>
131
+ </Button>
151
132
  {/if}
152
133
  </div>
153
134
  </div>
@@ -178,30 +159,80 @@ onDestroy(() => {
178
159
  label="Language"
179
160
  options={[
180
161
  ['Typescript (Deno)', 'deno'],
181
- ['Python 3.10', 'python3']
162
+ ['Python 3.10', 'python3'],
163
+ ['Go', 'go']
182
164
  ]}
183
- on:change={(e) => initContent(e.detail, template)}
165
+ on:change={(e) => initContent(e.detail, script.kind, template)}
184
166
  bind:value={script.language}
185
167
  />
186
168
  </div>
169
+ <h4 class="text-gray-700 border-b">
170
+ Script Kind <Tooltip
171
+ >In most cases, you will want the General Script. <br />
172
+ Trigger are meant to be used as the first module of flows to trigger them based on watching
173
+ new events externally. <br />
174
+ Failure scripts are used to handle unrecoverable errors of flows and for handling errors
175
+ at the workspace level. <br />
176
+ Command scripts are used when the workspace is associated with a slack workspace to be triggered
177
+ on command.</Tooltip
178
+ >
179
+ </h4>
180
+
187
181
  {#if script.language == 'deno'}
188
- <h4 class="text-gray-700 border-b">Template</h4>
182
+ <div class="max-w-lg">
183
+ <RadioButton
184
+ label="Script Type"
185
+ options={[
186
+ ['General Script', Script.kind.SCRIPT],
187
+ ['Trigger Script', Script.kind.TRIGGER]
188
+ // ['Failure Handler', Script.kind.FAILURE],
189
+ // ['Command Handler', Script.kind.COMMAND]
190
+ ]}
191
+ on:change={(e) => {
192
+ if (isInitialCode(script.content)) {
193
+ template = 'script'
194
+ initContent(script.language, e.detail, template)
195
+ }
196
+ }}
197
+ bind:value={script.kind}
198
+ />
199
+ </div>
200
+ {:else}
201
+ <div class="max-w-lg">
202
+ <RadioButton
203
+ label="Script Type"
204
+ options={[['General Script', Script.kind.SCRIPT]]}
205
+ on:change={(e) => {
206
+ if (isInitialCode(script.content)) {
207
+ template = 'script'
208
+ initContent(script.language, e.detail, template)
209
+ }
210
+ }}
211
+ bind:value={script.kind}
212
+ />
213
+ </div>
214
+ {/if}
215
+
216
+ {#if script.language == 'deno' && script.kind == Script.kind.SCRIPT}
217
+ <h4 class="text-gray-700 border-b">
218
+ Script Template <Tooltip
219
+ >A template is a pre-filled script corresponding to a more specialized use-case</Tooltip
220
+ >
221
+ </h4>
189
222
 
190
223
  <div class="max-w-md">
191
224
  <RadioButton
192
225
  label="Template"
193
226
  options={[
194
- ['None', undefined],
195
- ['PostgreSQL', 'pgsql']
227
+ ['Standard', 'script'],
228
+ ['PostgreSQL Prepared Statement', 'pgsql']
196
229
  ]}
197
- on:change={(e) => initContent(script.language, e.detail)}
230
+ on:change={(e) => initContent(script.language, script.kind, e.detail)}
198
231
  bind:value={template}
199
232
  />
200
233
  </div>
201
234
  {/if}
202
235
 
203
- <h3 class="text-gray-700 pb-1 border-b">Metadata</h3>
204
-
205
236
  <label class="block ">
206
237
  <span class="text-gray-700">Summary <Required required={false} /></span>
207
238
  <textarea
@@ -241,28 +272,14 @@ onDestroy(() => {
241
272
  </label>
242
273
 
243
274
  <label class="block">
244
- <span class="text-gray-700 mr-2">Save as template</span>
275
+ <span class="text-gray-700 mr-2"
276
+ >Save as workspace template <Tooltip
277
+ >Enable your teammates to use this script as a template to write new scripts.</Tooltip
278
+ >
279
+ </span>
245
280
  <input type="checkbox" bind:checked={script.is_template} />
246
281
  </label>
247
282
 
248
- <label class="block">
249
- <span class="text-gray-700 mr-2">Save as trigger script</span>
250
- <input
251
- disabled={script.language == 'python3'}
252
- type="checkbox"
253
- bind:checked={script.is_trigger}
254
- on:change={() => {
255
- if (
256
- script.content == DENO_INIT_CODE ||
257
- script.content == DENO_INIT_CODE_TRIGGER ||
258
- script.content == POSTGRES_INIT_CODE
259
- ) {
260
- initContent(script.language, template)
261
- }
262
- }}
263
- />
264
- </label>
265
-
266
283
  <div>
267
284
  <h3 class="text-gray-700 ">Description rendered</h3>
268
285
  <div
@@ -276,7 +293,6 @@ onDestroy(() => {
276
293
  </CenteredPage>
277
294
  {:else if step === 2}
278
295
  <ScriptEditor
279
- bind:this={editor}
280
296
  bind:schema={script.schema}
281
297
  path={script.path}
282
298
  bind:code={script.content}
@@ -1,11 +1,10 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import { type Script } from '../gen';
2
+ import { Script } from '../gen';
3
3
  declare const __propDef: {
4
4
  props: {
5
5
  script: Script;
6
6
  initialPath?: string | undefined;
7
- template?: 'pgsql' | undefined;
8
- setCode?: ((script: Script) => void) | undefined;
7
+ template?: "script" | "pgsql" | undefined;
9
8
  };
10
9
  events: {
11
10
  [evt: string]: CustomEvent<any>;
@@ -16,6 +15,5 @@ export declare type ScriptBuilderProps = typeof __propDef.props;
16
15
  export declare type ScriptBuilderEvents = typeof __propDef.events;
17
16
  export declare type ScriptBuilderSlots = typeof __propDef.slots;
18
17
  export default class ScriptBuilder extends SvelteComponentTyped<ScriptBuilderProps, ScriptBuilderEvents, ScriptBuilderSlots> {
19
- get setCode(): (script: Script) => void;
20
18
  }
21
19
  export {};
@@ -1,8 +1,7 @@
1
1
  <script>import { CompletedJob, Job, JobService } from '../gen';
2
2
  import { userStore, workspaceStore } from '../stores';
3
- import { classNames, emptySchema } from '../utils';
3
+ import { emptySchema, scriptLangToEditorLang } from '../utils';
4
4
  import { faCheck, faExclamationTriangle, faPlay, faRotateRight } from '@fortawesome/free-solid-svg-icons';
5
- import { onDestroy, onMount } from 'svelte';
6
5
  import Icon from 'svelte-awesome';
7
6
  import Editor from './Editor.svelte';
8
7
  import { inferArgs } from '../infer';
@@ -11,6 +10,10 @@ import LogPanel from './script_editor/LogPanel.svelte';
11
10
  import { HSplitPane, VSplitPane } from 'svelte-split-pane';
12
11
  import { faGithub } from '@fortawesome/free-brands-svg-icons';
13
12
  import EditorBar from './EditorBar.svelte';
13
+ import Button from './common/button/Button.svelte';
14
+ import TestJobLoader from './TestJobLoader.svelte';
15
+ import { onMount } from 'svelte';
16
+ import UnsavedConfirmationModal from './common/confirmationModal/UnsavedConfirmationModal.svelte';
14
17
  // Exported
15
18
  export let schema = emptySchema();
16
19
  export let code;
@@ -19,58 +22,26 @@ export let lang;
19
22
  let websocketAlive = { pyright: false, black: false, deno: false };
20
23
  // Internal state
21
24
  let editor;
22
- // Preview args input
25
+ let testJobLoader;
26
+ // Test args input
23
27
  let args = {};
24
28
  let isValid = true;
25
- // Preview
26
- let previewIsLoading = false;
27
- let previewIntervalId;
28
- let previewJob;
29
+ // Test
30
+ let testIsLoading = false;
31
+ let testJob;
29
32
  let pastPreviews = [];
30
33
  let lastSave;
31
- let syncIteration = 0;
32
- let ITERATIONS_BEFORE_SLOW_REFRESH = 100;
33
34
  $: lastSave = localStorage.getItem(path ?? 'last_save');
34
- export function getEditor() {
35
- return editor;
36
- }
37
- let div = null;
38
- export async function runPreview() {
39
- try {
40
- if (previewIntervalId) {
41
- clearInterval(previewIntervalId);
42
- }
43
- if (previewIsLoading && previewJob) {
44
- JobService.cancelQueuedJob({
45
- workspace: $workspaceStore,
46
- id: previewJob.id,
47
- requestBody: {}
48
- });
49
- }
50
- previewIsLoading = true;
51
- const previewId = await JobService.runScriptPreview({
52
- workspace: $workspaceStore,
53
- requestBody: {
54
- path,
55
- content: editor.getCode(),
56
- args: args,
57
- language: lang
58
- }
59
- });
60
- previewJob = undefined;
61
- loadPreviewJob(previewId);
62
- syncIteration = 0;
63
- previewIntervalId = setInterval(() => {
64
- syncer(previewId);
65
- }, 500);
66
- //TODO fetch preview, every x time, until it's completed
67
- }
68
- catch (err) {
69
- previewIsLoading = false;
70
- throw err;
35
+ function onKeyDown(event) {
36
+ if ((event.ctrlKey || event.metaKey) && event.key == 'Enter') {
37
+ event.preventDefault();
38
+ runTest();
71
39
  }
72
40
  }
73
- async function loadPastPreviews() {
41
+ function runTest() {
42
+ testJobLoader.runPreview(path, code, lang, args);
43
+ }
44
+ async function loadPastTests() {
74
45
  pastPreviews = await JobService.listCompletedJobs({
75
46
  workspace: $workspaceStore,
76
47
  jobKinds: 'preview',
@@ -78,37 +49,6 @@ async function loadPastPreviews() {
78
49
  scriptPathExact: path
79
50
  });
80
51
  }
81
- async function loadPreviewJob(id) {
82
- try {
83
- if (previewJob && `running` in previewJob) {
84
- let previewJobUpdates = await JobService.getJobUpdates({
85
- workspace: $workspaceStore,
86
- id,
87
- running: previewJob.running,
88
- logOffset: previewJob.logs?.length ?? 0
89
- });
90
- if (previewJobUpdates.new_logs) {
91
- previewJob.logs = (previewJob.logs ?? '').concat(previewJobUpdates.new_logs);
92
- }
93
- if ((previewJobUpdates.running ?? false) || (previewJobUpdates.completed ?? false)) {
94
- previewJob = await JobService.getJob({ workspace: $workspaceStore, id });
95
- }
96
- }
97
- else {
98
- previewJob = await JobService.getJob({ workspace: $workspaceStore, id });
99
- }
100
- if (previewJob?.type === 'CompletedJob') {
101
- //only CompletedJob has success property
102
- clearInterval(previewIntervalId);
103
- previewIsLoading = false;
104
- loadPastPreviews();
105
- }
106
- div?.scroll({ top: div?.scrollHeight, behavior: 'smooth' });
107
- }
108
- catch (err) {
109
- console.error(err);
110
- }
111
- }
112
52
  async function inferSchema() {
113
53
  let isDefault = [];
114
54
  Object.entries(args).forEach(([k, v]) => {
@@ -116,7 +56,7 @@ async function inferSchema() {
116
56
  isDefault.push(k);
117
57
  }
118
58
  });
119
- await inferArgs(lang, editor.getCode(), schema);
59
+ await inferArgs(lang, code, schema);
120
60
  schema = schema;
121
61
  isDefault
122
62
  .filter((key) => schema.properties[key] != undefined)
@@ -127,72 +67,38 @@ async function inferSchema() {
127
67
  }
128
68
  }
129
69
  }
130
- function syncer(id) {
131
- if (syncIteration > ITERATIONS_BEFORE_SLOW_REFRESH) {
132
- loadPreviewJob(id);
133
- if (previewIntervalId) {
134
- clearInterval(previewIntervalId);
135
- previewIntervalId = setInterval(() => loadPreviewJob(id), 5000);
136
- }
137
- }
138
- else {
139
- syncIteration++;
140
- loadPreviewJob(id);
141
- }
142
- }
143
- let syncCode;
144
70
  onMount(() => {
145
71
  inferSchema();
146
- syncCode = setInterval(() => {
147
- const newCode = editor?.getCode();
148
- if (newCode && code != newCode) {
149
- code = editor.getCode();
150
- }
151
- }, 3000);
152
- });
153
- onDestroy(() => {
154
- if (editor) {
155
- code = editor.getCode();
156
- }
157
- if (previewIntervalId) {
158
- clearInterval(previewIntervalId);
159
- }
160
- if (syncCode) {
161
- clearInterval(syncCode);
162
- }
163
72
  });
164
73
  </script>
165
74
 
75
+ <TestJobLoader
76
+ on:done={loadPastTests}
77
+ bind:this={testJobLoader}
78
+ bind:isLoading={testIsLoading}
79
+ bind:job={testJob}
80
+ />
81
+
82
+ <svelte:window on:keydown={onKeyDown} />
83
+
166
84
  <div class="border-b shadow-sm p-1 pr-4">
167
85
  <div class="flex justify-between">
168
86
  <EditorBar {editor} {lang} {websocketAlive} />
169
87
 
170
88
  <div class="flex divide-x">
171
89
  <div>
172
- <a
90
+ <Button
173
91
  target="_blank"
174
92
  href="https://github.com/windmill-labs/windmill-gh-action-deploy"
175
- class="text-gray-800 mx-1 bg-white rounded-md items-center flex border-gray-300 hover:bg-gray-100 font-medium text-xs p-2"
93
+ color="light"
94
+ size="xs"
95
+ btnClasses="mr-1"
96
+ startIcon={{
97
+ icon: faGithub
98
+ }}
176
99
  >
177
- <Icon data={faGithub} class="h-4 w-4 mr-2" />
178
100
  Sync from Github
179
- </a>
180
- </div>
181
-
182
- <div>
183
- <button
184
- type="button"
185
- on:click|stopPropagation={() => runPreview()}
186
- disabled={previewIsLoading}
187
- class="text-white ml-1 w-28 bg-blue-500 hover:bg-blue-700 rounded-md flex justify-center items-center focus:outline-none font-medium text-xs p-2"
188
- >
189
- <Icon
190
- data={previewIsLoading ? faRotateRight : faPlay}
191
- class={classNames('h-4 w-4 mr-2', previewIsLoading ? 'animate-spin' : 'animate-none')}
192
- />
193
-
194
- {previewIsLoading ? 'Running' : 'Run preview'}
195
- </button>
101
+ </Button>
196
102
  </div>
197
103
  </div>
198
104
  </div>
@@ -204,29 +110,23 @@ onDestroy(() => {
204
110
  <div
205
111
  class="p-2 h-full"
206
112
  on:mouseleave={() => {
207
- code = getEditor().getCode()
208
113
  inferSchema()
209
114
  }}
210
115
  >
211
116
  <Editor
212
- {code}
117
+ bind:code
213
118
  bind:websocketAlive
214
119
  bind:this={editor}
215
120
  cmdEnterAction={() => {
216
- runPreview()
121
+ runTest()
217
122
  }}
218
123
  formatAction={async () => {
219
- code = getEditor().getCode()
220
124
  await inferSchema()
221
125
  localStorage.setItem(path ?? 'last_save', code)
222
126
  lastSave = code
223
127
  }}
224
- on:blur={() => {
225
- code = getEditor().getCode()
226
- inferSchema()
227
- }}
228
128
  class="flex flex-1 h-full"
229
- deno={lang == 'deno'}
129
+ lang={scriptLangToEditorLang(lang)}
230
130
  automaticLayout={true}
231
131
  />
232
132
  </div>
@@ -234,7 +134,7 @@ onDestroy(() => {
234
134
  </left>
235
135
  <right slot="right">
236
136
  <div class="h-full">
237
- <VSplitPane topPanelSize="50%" downPanelSize="50%">
137
+ <VSplitPane topPanelSize="30%" downPanelSize="70%">
238
138
  <top slot="top">
239
139
  <div class="h-full overflow-auto">
240
140
  <div class="p-4">
@@ -264,13 +164,41 @@ onDestroy(() => {
264
164
  </div>
265
165
  </top>
266
166
  <down slot="down">
267
- <div class="pt-1 h-full overflow-auto">
167
+ <div class="h-full overflow-hidden">
168
+ <div class="px-2 py-1">
169
+ {#if testIsLoading}
170
+ <Button
171
+ on:click={testJobLoader?.cancelJob}
172
+ btnClasses="w-full"
173
+ color="red"
174
+ size="xs"
175
+ startIcon={{
176
+ icon: faRotateRight,
177
+ classes: 'animate-spin'
178
+ }}
179
+ >
180
+ 'Cancel'
181
+ </Button>
182
+ {:else}
183
+ <Button
184
+ on:click={runTest}
185
+ btnClasses="w-full"
186
+ size="xs"
187
+ startIcon={{
188
+ icon: faPlay,
189
+ classes: 'animate-none'
190
+ }}
191
+ >
192
+ {testIsLoading ? 'Running' : 'Test (Ctrl+Enter)'}
193
+ </Button>
194
+ {/if}
195
+ </div>
268
196
  <LogPanel
269
197
  {path}
270
198
  {lang}
271
- {previewJob}
199
+ previewJob={testJob}
272
200
  {pastPreviews}
273
- {previewIsLoading}
201
+ previewIsLoading={testIsLoading}
274
202
  bind:lastSave
275
203
  />
276
204
  </div>
@@ -1,6 +1,5 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import type { Schema } from '../common';
3
- import Editor from './Editor.svelte';
4
3
  import type { Preview } from '../gen/models/Preview';
5
4
  declare const __propDef: {
6
5
  props: {
@@ -8,8 +7,6 @@ declare const __propDef: {
8
7
  code: string;
9
8
  path: string | undefined;
10
9
  lang: Preview.language;
11
- getEditor?: (() => Editor) | undefined;
12
- runPreview?: (() => Promise<void>) | undefined;
13
10
  };
14
11
  events: {
15
12
  [evt: string]: CustomEvent<any>;
@@ -20,7 +17,5 @@ export declare type ScriptEditorProps = typeof __propDef.props;
20
17
  export declare type ScriptEditorEvents = typeof __propDef.events;
21
18
  export declare type ScriptEditorSlots = typeof __propDef.slots;
22
19
  export default class ScriptEditor extends SvelteComponentTyped<ScriptEditorProps, ScriptEditorEvents, ScriptEditorSlots> {
23
- get getEditor(): () => Editor;
24
- get runPreview(): () => Promise<void>;
25
20
  }
26
21
  export {};