windmill-components 1.35.43 → 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 (134) hide show
  1. package/components/AppConnect.svelte +85 -59
  2. package/components/ArgInput.svelte +31 -14
  3. package/components/Button.svelte +15 -48
  4. package/components/Button.svelte.d.ts +1 -1
  5. package/components/CronInput.svelte +1 -1
  6. package/components/DisplayResult.svelte +31 -29
  7. package/components/Dropdown.svelte +9 -7
  8. package/components/Editor.svelte +10 -14
  9. package/components/EditorBar.svelte +115 -91
  10. package/components/FlowBuilder.svelte +63 -74
  11. package/components/FlowPreviewContent.svelte +44 -24
  12. package/components/FlowStatusViewer.svelte +2 -5
  13. package/components/FlowViewer.svelte +12 -10
  14. package/components/GroupModal.svelte +10 -1
  15. package/components/HighlightCode.svelte +4 -3
  16. package/components/InputTransformForm.svelte +15 -14
  17. package/components/InputTransformsViewer.svelte +1 -1
  18. package/components/InviteGlobalUser.svelte +8 -8
  19. package/components/InviteUser.svelte +9 -9
  20. package/components/ItemPicker.svelte +36 -29
  21. package/components/ItemPicker.svelte.d.ts +2 -1
  22. package/components/JobStatus.svelte +2 -1
  23. package/components/ModulePreview.svelte +7 -8
  24. package/components/Path.svelte +1 -1
  25. package/components/RadioButton.svelte +3 -2
  26. package/components/ResourceEditor.svelte +22 -34
  27. package/components/ResourceTypePicker.svelte +23 -34
  28. package/components/RunForm.svelte +23 -31
  29. package/components/SchemaEditor.svelte +16 -10
  30. package/components/SchemaForm.svelte +3 -1
  31. package/components/SchemaForm.svelte.d.ts +1 -0
  32. package/components/SchemaModal.svelte +18 -7
  33. package/components/ScriptBuilder.svelte +22 -17
  34. package/components/ScriptEditor.svelte +2 -1
  35. package/components/ScriptPicker.svelte +21 -11
  36. package/components/ScriptSchema.svelte +8 -11
  37. package/components/ScriptSchema.svelte.d.ts +0 -1
  38. package/components/ShareModal.svelte +6 -6
  39. package/components/SimpleEditor.svelte +10 -10
  40. package/components/StringTypeNarrowing.svelte +24 -30
  41. package/components/TestJobLoader.svelte +15 -7
  42. package/components/Tooltip.svelte +1 -1
  43. package/components/VariableEditor.svelte +15 -24
  44. package/components/common/actionRow/ActionRow.svelte +11 -6
  45. package/components/common/actionRow/ActionRow.svelte.d.ts +1 -0
  46. package/components/common/badge/Badge.svelte +2 -8
  47. package/components/common/badge/model.d.ts +1 -1
  48. package/components/common/button/Button.svelte +7 -4
  49. package/components/common/button/Button.svelte.d.ts +2 -0
  50. package/components/common/confirmationModal/ConfirmationModal.svelte +19 -2
  51. package/components/common/confirmationModal/UnsavedConfirmationModal.svelte +41 -0
  52. package/components/common/confirmationModal/UnsavedConfirmationModal.svelte.d.ts +14 -0
  53. package/components/common/confirmationModal/dirtyStore.d.ts +1 -0
  54. package/components/common/confirmationModal/dirtyStore.js +2 -0
  55. package/components/flows/FlowEditor.svelte +7 -7
  56. package/components/flows/FlowEditor.svelte.d.ts +3 -1
  57. package/components/flows/common/FlowCardHeader.svelte +1 -1
  58. package/components/flows/content/FlowEditorPanel.svelte +5 -6
  59. package/components/flows/content/FlowEditorPanel.svelte.d.ts +3 -1
  60. package/components/flows/content/FlowFailureModule.svelte +2 -4
  61. package/components/flows/content/FlowInput.svelte +5 -1
  62. package/components/flows/content/FlowInputs.svelte +27 -12
  63. package/components/flows/content/FlowInputs.svelte.d.ts +1 -0
  64. package/components/flows/content/FlowLoop.svelte +155 -25
  65. package/components/flows/content/FlowLoop.svelte.d.ts +5 -1
  66. package/components/flows/content/FlowLoopWrapper.svelte +9 -0
  67. package/components/flows/content/FlowLoopWrapper.svelte.d.ts +14 -0
  68. package/components/flows/content/FlowModule.svelte +31 -10
  69. package/components/flows/content/FlowModule.svelte.d.ts +1 -1
  70. package/components/flows/content/FlowModuleEarlyStop.svelte +76 -0
  71. package/components/flows/content/FlowModuleEarlyStop.svelte.d.ts +17 -0
  72. package/components/flows/content/FlowModuleHeader.svelte +90 -1
  73. package/components/flows/content/FlowModuleHeader.svelte.d.ts +3 -0
  74. package/components/flows/content/FlowModuleSuspend.svelte +27 -0
  75. package/components/flows/content/FlowModuleSuspend.svelte.d.ts +17 -0
  76. package/components/flows/content/FlowModuleWrapper.svelte +4 -6
  77. package/components/flows/content/FlowRetries.svelte +18 -18
  78. package/components/flows/content/FlowRetries.svelte.d.ts +4 -1
  79. package/components/flows/content/FlowSettings.svelte +39 -12
  80. package/components/flows/content/FlowSettings.svelte.d.ts +1 -0
  81. package/components/flows/content/RemoveStepConfirmationModal.svelte +1 -1
  82. package/components/flows/flowStateUtils.d.ts +1 -1
  83. package/components/flows/flowStateUtils.js +2 -2
  84. package/components/flows/header/FlowImportExportMenu.svelte +4 -5
  85. package/components/flows/header/FlowPreviewButtons.svelte +24 -16
  86. package/components/flows/map/FlowErrorHandlerItem.svelte +14 -8
  87. package/components/flows/map/FlowModuleSchemaItem.svelte +41 -19
  88. package/components/flows/map/FlowModuleSchemaItem.svelte.d.ts +6 -1
  89. package/components/flows/map/FlowModuleSchemaMap.svelte +86 -6
  90. package/components/flows/pickers/PickHubScript.svelte +2 -1
  91. package/components/flows/propPicker/PropPickerWrapper.svelte +3 -1
  92. package/components/flows/propPicker/PropPickerWrapper.svelte.d.ts +2 -0
  93. package/components/flows/types.d.ts +0 -1
  94. package/components/flows/utils.d.ts +2 -0
  95. package/components/flows/utils.js +19 -0
  96. package/components/icons/AirtableIcon.svelte +1 -1
  97. package/components/icons/DiscordIcon.svelte +1 -1
  98. package/components/icons/GCloudIcon.svelte +1 -1
  99. package/components/icons/GItlabIcon.svelte +1 -1
  100. package/components/icons/GSheetsIcon.svelte +1 -1
  101. package/components/icons/GcalIcon.svelte +1 -1
  102. package/components/icons/GdriveIcon.svelte +1 -1
  103. package/components/icons/GithubIcon.svelte +1 -1
  104. package/components/icons/GmailIcon.svelte +1 -1
  105. package/components/icons/MastodonIcon.svelte +1 -1
  106. package/components/icons/MatrixIcon.svelte +1 -1
  107. package/components/icons/PostgresIcon.svelte +1 -1
  108. package/components/icons/S3Icon.svelte +1 -1
  109. package/components/icons/Slack.svelte +1 -1
  110. package/components/icons/TogglIcon.svelte +8 -46
  111. package/components/jobs/JobDetail.svelte +1 -1
  112. package/components/propertyPicker/ObjectViewer.svelte +9 -12
  113. package/components/propertyPicker/ObjectViewer.svelte.d.ts +1 -0
  114. package/components/propertyPicker/PropPicker.svelte +85 -14
  115. package/components/script_editor/LogPanel.svelte +1 -1
  116. package/editorUtils.d.ts +3 -0
  117. package/editorUtils.js +1 -0
  118. package/gen/core/OpenAPI.js +1 -1
  119. package/gen/index.d.ts +1 -0
  120. package/gen/models/FlowModule.d.ts +2 -0
  121. package/gen/models/FlowValue.d.ts +0 -11
  122. package/gen/models/Retry.d.ts +11 -0
  123. package/gen/models/Retry.js +4 -0
  124. package/package.json +18 -15
  125. package/script_helpers.d.ts +4 -1
  126. package/script_helpers.js +48 -4
  127. package/utils.d.ts +2 -2
  128. package/utils.js +31 -18
  129. package/components/flows/content/FlowModuleAdvancedSettings.svelte +0 -64
  130. package/components/flows/content/FlowModuleAdvancedSettings.svelte.d.ts +0 -17
  131. package/components/flows/header/FlowEditorHeader.svelte +0 -23
  132. package/components/flows/header/FlowEditorHeader.svelte.d.ts +0 -14
  133. package/components/flows/header/FlowStatus.svelte +0 -36
  134. package/components/flows/header/FlowStatus.svelte.d.ts +0 -14
@@ -28,6 +28,7 @@ import Icon from 'svelte-awesome';
28
28
  import Modal from './Modal.svelte';
29
29
  import Password from './Password.svelte';
30
30
  import Path from './Path.svelte';
31
+ import { Button } from './common';
31
32
  let manual = false;
32
33
  let value = '';
33
34
  let valueToken;
@@ -156,6 +157,10 @@ $: isGoogleSignin =
156
157
  resource_type == 'gcal' ||
157
158
  resource_type == 'gdrive' ||
158
159
  resource_type == 'gsheets');
160
+ $: disabled =
161
+ (step == 1 && resource_type == '') ||
162
+ (step == 2 && value == '') ||
163
+ (step == 3 && pathError != '');
159
164
  </script>
160
165
 
161
166
  <Modal
@@ -185,8 +190,10 @@ $: isGoogleSignin =
185
190
  <PageHeader title="OAuth APIs" />
186
191
  <div class="grid sm:grid-cols-2 md:grid-cols-3 gap-x-2 gap-y-1 items-center mb-2">
187
192
  {#each Object.entries(connects).sort((a, b) => a[0].localeCompare(b[0])) as [key, values]}
188
- <button
189
- class="px-4 h-8 {key == resource_type ? 'item-button-selected' : 'item-button'}"
193
+ <Button
194
+ variant="border"
195
+ color={key === resource_type ? 'blue' : 'dark'}
196
+ btnClasses={key === resource_type ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
190
197
  on:click={() => {
191
198
  manual = false
192
199
  resource_type = key
@@ -197,64 +204,93 @@ $: isGoogleSignin =
197
204
  }}
198
205
  >
199
206
  <IconedResourceType name={key} after={true} />
200
- </button>
207
+ </Button>
201
208
  {/each}
202
209
  </div>
203
- <PageHeader title="scopes" primary={false} />
210
+ <PageHeader title="Scopes" primary={false} />
204
211
  {#if !manual && resource_type != ''}
205
212
  {#each scopes as v}
206
- <div class="flex flex-row max-w-md">
213
+ <div class="flex flex-row max-w-md mb-2">
207
214
  <input type="text" bind:value={v} />
208
- <button
209
- class="default-button-secondary mx-6"
215
+ <Button
216
+ variant="border"
217
+ color="red"
218
+ size="xs"
219
+ btnClasses="mx-6"
210
220
  on:click={() => {
211
221
  scopes = scopes.filter((el) => el != v)
212
- }}><Icon data={faMinus} class="mb-1" /></button
222
+ }}
213
223
  >
224
+ <Icon data={faMinus} />
225
+ </Button>
214
226
  </div>
215
227
  {/each}
216
- <button
217
- class="default-button-secondary mt-1"
218
- on:click={() => {
219
- scopes = scopes.concat('')
220
- }}>Add item &nbsp;<Icon data={faPlus} class="mb-1" /></button
221
- ><span class="ml-2">{(scopes ?? []).length} item{(scopes ?? []).length > 1 ? 's' : ''}</span
222
- >
228
+ <div class="flex items-center mt-1">
229
+ <Button
230
+ variant="border"
231
+ color="blue"
232
+ size="sm"
233
+ endIcon={{ icon: faPlus }}
234
+ on:click={() => {
235
+ scopes = scopes.concat('')
236
+ }}
237
+ >
238
+ Add item
239
+ </Button>
240
+ <span class="ml-2 text-sm text-gray-500">
241
+ ({(scopes ?? []).length} item{(scopes ?? []).length > 1 ? 's' : ''})
242
+ </span>
243
+ </div>
223
244
  {:else}
224
245
  <p class="italic text-sm">Pick an OAuth API and customize the scopes here</p>
225
246
  {/if}
226
247
  <PageHeader title="Extra Params" primary={false} />
227
248
  {#if !manual && resource_type != ''}
228
249
  {#each extra_params as [k, v]}
229
- <div class="flex flex-row max-w-md">
230
- <input type="text" bind:value={k} />
250
+ <div class="flex flex-row max-w-md mb-2">
251
+ <input type="text" bind:value={k} class="mr-2" />
231
252
  <input type="text" bind:value={v} />
232
253
 
233
- <button
234
- class="default-button-secondary mx-6"
254
+ <Button
255
+ variant="border"
256
+ color="red"
257
+ size="xs"
258
+ btnClasses="mx-6"
235
259
  on:click={() => {
236
260
  extra_params = extra_params.filter((el) => el[0] != k)
237
- }}><Icon data={faMinus} class="mb-1" /></button
261
+ }}
238
262
  >
263
+ <Icon data={faMinus} />
264
+ </Button>
239
265
  </div>
240
266
  {/each}
241
- <button
242
- class="default-button-secondary mt-1"
243
- on:click={() => {
244
- extra_params.push(['', ''])
245
- extra_params = extra_params
246
- }}>Add item &nbsp;<Icon data={faPlus} class="mb-1" /></button
247
- ><span class="ml-2"
248
- >{(extra_params ?? []).length} item{(extra_params ?? []).length > 1 ? 's' : ''}</span
249
- >
267
+ <div class="flex items-center mt-1">
268
+ <Button
269
+ variant="border"
270
+ color="blue"
271
+ size="sm"
272
+ endIcon={{ icon: faPlus }}
273
+ on:click={() => {
274
+ extra_params.push(['', ''])
275
+ extra_params = extra_params
276
+ }}
277
+ >
278
+ Add item
279
+ </Button>
280
+ <span class="ml-2 text-sm text-gray-500">
281
+ ({(extra_params ?? []).length} item{(extra_params ?? []).length > 1 ? 's' : ''})
282
+ </span>
283
+ </div>
250
284
  {:else}
251
285
  <p class="italic text-sm">Pick an OAuth API and customize the extra parameters here</p>
252
286
  {/if}
253
287
  <PageHeader title="Non OAuth APIs" />
254
288
  <div class="grid sm:grid-cols-2 md:grid-cols-3 gap-x-2 gap-y-1 items-center mb-2">
255
289
  {#each connectsManual as [key, instructions]}
256
- <button
257
- class="px-4 h-8 {key == resource_type ? 'item-button-selected' : 'item-button'}"
290
+ <Button
291
+ variant="border"
292
+ color={key === resource_type ? 'blue' : 'dark'}
293
+ btnClasses={key === resource_type ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
258
294
  on:click={() => {
259
295
  manual = true
260
296
  resource_type = key
@@ -262,7 +298,7 @@ $: isGoogleSignin =
262
298
  }}
263
299
  >
264
300
  <IconedResourceType name={key} after={true} />
265
- </button>
301
+ </Button>
266
302
  {/each}
267
303
  </div>
268
304
  {:else if step == 2}
@@ -310,34 +346,24 @@ $: isGoogleSignin =
310
346
  </ul>
311
347
  {/if}
312
348
  </div>
313
- <div slot="submission">
349
+ <div slot="submission" class="flex items-center gap-4">
314
350
  {#if step > 1 && !no_back}
315
- <button class="default-button px-4 py-2 font-semibold" on:click={back}>Back</button>
351
+ <Button variant="border" on:click={back}>Back</Button>
352
+ {/if}
353
+ {#if isGoogleSignin}
354
+ <button {disabled} on:click={next}>
355
+ <img class="h-10 w-auto" src="/google_signin.png" alt="Google sign-in" />
356
+ </button>
357
+ {:else}
358
+ <Button {disabled} on:click={next}>
359
+ {#if step == 1 && !manual}
360
+ Connect
361
+ {:else if step == 3}
362
+ Add resource
363
+ {:else}
364
+ Next
365
+ {/if}
366
+ </Button>
316
367
  {/if}
317
- <button
318
- class={isGoogleSignin ? '' : 'default-button px-4 py-2 font-semibold'}
319
- class:default-button-disabled={(step == 1 && resource_type == '') ||
320
- (step == 2 && value == '') ||
321
- (step == 3 && pathError != '')}
322
- on:click={next}
323
- >
324
- {#if isGoogleSignin}
325
- <img src="/google_signin.png" alt="Google sign-in" />
326
- {:else if step == 1 && !manual}
327
- Connect
328
- {:else if step == 3}
329
- Add resource
330
- {:else}
331
- Next
332
- {/if}
333
- </button>
334
368
  </div>
335
369
  </Modal>
336
-
337
- <style>
338
- .selected:hover {
339
- border-radius: 0.375rem;
340
- border-width: 1px;
341
- border-color: rgb(156 163 175 / var(--tw-border-opacity));
342
- --tw-border-opacity: 0.5
343
- }</style>
@@ -1,7 +1,7 @@
1
1
  <script>import { slide } from 'svelte/transition';
2
- import { faArrowRotateLeft, faChevronDown, faChevronUp, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons';
2
+ import { faChevronDown, faChevronUp, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons';
3
3
  import { setInputCat as computeInputCat } from '../utils';
4
- import { Button, Tooltip } from 'flowbite-svelte';
4
+ import { Button } from './common';
5
5
  import { createEventDispatcher } from 'svelte';
6
6
  import Icon from 'svelte-awesome';
7
7
  import FieldHeader from './FieldHeader.svelte';
@@ -31,10 +31,10 @@ export let displayHeader = true;
31
31
  export let properties = undefined;
32
32
  let seeEditable = enum_ != undefined || pattern != undefined;
33
33
  const dispatch = createEventDispatcher();
34
- $: minHeight = `${1 + minRows * 1.2}em`;
35
34
  $: maxHeight = maxRows ? `${1 + maxRows * 1.2}em` : `auto`;
36
35
  $: validateInput(pattern, value);
37
36
  let error = '';
37
+ let el = undefined;
38
38
  export let editor = undefined;
39
39
  let rawValue = undefined;
40
40
  $: {
@@ -210,8 +210,11 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
210
210
  {:else}
211
211
  <input type="text" bind:value={v} />
212
212
  {/if}
213
- <button
214
- class="default-button-secondary mx-6"
213
+ <Button
214
+ variant="border"
215
+ color="red"
216
+ size="sm"
217
+ btnClasses="mx-6"
215
218
  on:click={() => {
216
219
  value = value.filter((el) => el != v)
217
220
  if (value.length == 0) {
@@ -219,13 +222,16 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
219
222
  }
220
223
  }}
221
224
  >
222
- <Icon data={faMinus} class="mb-1" />
223
- </button>
225
+ <Icon data={faMinus} />
226
+ </Button>
224
227
  </div>
225
228
  {/each}
226
229
  </div>
227
- <button
228
- class="default-button-secondary mt-1"
230
+ <Button
231
+ variant="border"
232
+ color="blue"
233
+ size="sm"
234
+ btnClasses="mt-1"
229
235
  on:click={() => {
230
236
  if (value == undefined) {
231
237
  value = []
@@ -235,7 +241,7 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
235
241
  >
236
242
  <Icon data={faPlus} class="mr-2" />
237
243
  Add item
238
- </button>
244
+ </Button>
239
245
  <span class="ml-2">
240
246
  {(value ?? []).length} item{(value ?? []).length > 1 ? 's' : ''}
241
247
  </span>
@@ -252,9 +258,16 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
252
258
  </div>
253
259
  {:else}
254
260
  <textarea
261
+ bind:this={el}
262
+ on:focus
255
263
  {disabled}
256
- style="min-height: {minHeight}; max-height: {maxHeight}"
257
- on:input={async () => recomputeRowSize(rawValue ?? '')}
264
+ style="max-height: {maxHeight}"
265
+ on:input={(e) => {
266
+ if (el) {
267
+ el.style.height = '5px'
268
+ el.style.height = el.scrollHeight + 'px'
269
+ }
270
+ }}
258
271
  class="col-span-10 {valid
259
272
  ? ''
260
273
  : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}"
@@ -300,17 +313,21 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
300
313
  />
301
314
  {:else if inputCat == 'string'}
302
315
  <textarea
316
+ bind:this={el}
303
317
  on:focus={() => dispatch('focus')}
304
318
  on:blur={() => dispatch('blur')}
305
319
  {disabled}
306
- style="height: {minHeight}; max-height: {maxHeight}"
320
+ style="height: 30px; max-height: {maxHeight}"
307
321
  class="col-span-10 {valid
308
322
  ? ''
309
323
  : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}"
310
324
  placeholder={defaultValue ?? ''}
311
325
  bind:value
312
326
  on:input={async () => {
313
- recomputeRowSize(value)
327
+ if (el) {
328
+ el.style.height = '30px'
329
+ el.style.height = el.scrollHeight + 'px'
330
+ }
314
331
  dispatch('input', { rawValue: value, isRaw: false })
315
332
  }}
316
333
  />
@@ -1,16 +1,25 @@
1
1
  <script>import { faArchive, faEdit, faList, faPlay, faShare, faTrash } from '@fortawesome/free-solid-svg-icons';
2
- import { createEventDispatcher } from 'svelte';
3
2
  import Icon from 'svelte-awesome';
4
3
  export let category;
5
4
  export let disabled = false;
6
- const dispatch = createEventDispatcher();
5
+ const colors = {
6
+ red: 'bg-transparent hover:bg-red-600 text-red-600 font-normal hover:text-white border-red-600 hover:border-transparent rounded',
7
+ blue: 'hover:bg-blue-500 hover:text-white'
8
+ };
9
+ const getCategoryClasses = () => {
10
+ if (category === 'delete' || category === 'archive')
11
+ return colors.red;
12
+ else if (category === 'edit' || category === 'list' || category === 'share')
13
+ return colors.blue;
14
+ return '';
15
+ };
7
16
  </script>
8
17
 
9
18
  <button
10
- class="{$$props.class} inline-flex items-center default-button py-0 px-1 {category} default-button-secondary"
11
- on:click={() => {
12
- dispatch('click')
13
- }}
19
+ class="{$$props.class} inline-flex items-center bg-blue-500 hover:bg-blue-700 text-white
20
+ font-bold py-1 px-2 border rounded border-blue-500 hover:border-blue-700 w-min min-w-max
21
+ text-sm {getCategoryClasses()}"
22
+ on:click
14
23
  {disabled}
15
24
  >
16
25
  <div class="inline-flex items-center justify-center">
@@ -47,45 +56,3 @@ const dispatch = createEventDispatcher();
47
56
  {/if}
48
57
  </div>
49
58
  </button>
50
-
51
- <style>
52
- .delete,
53
- .archive {
54
- background-color: transparent
55
- }
56
- .delete:hover,
57
- .archive:hover {
58
- --tw-bg-opacity: 1;
59
- background-color: rgb(224 36 36 / var(--tw-bg-opacity))
60
- }
61
- .delete,
62
- .archive {
63
- font-weight: 400;
64
- --tw-text-opacity: 1;
65
- color: rgb(224 36 36 / var(--tw-text-opacity))
66
- }
67
- .delete:hover,
68
- .archive:hover {
69
- --tw-text-opacity: 1;
70
- color: rgb(255 255 255 / var(--tw-text-opacity))
71
- }
72
- .delete,
73
- .archive {
74
- border-radius: 0.25rem;
75
- --tw-border-opacity: 1;
76
- border-color: rgb(224 36 36 / var(--tw-border-opacity))
77
- }
78
- .delete:hover,
79
- .archive:hover {
80
- border-color: transparent
81
- }
82
-
83
- .edit:hover,
84
- .play:hover,
85
- .list:hover,
86
- .share:hover {
87
- --tw-bg-opacity: 1;
88
- background-color: rgb(63 131 248 / var(--tw-bg-opacity));
89
- --tw-text-opacity: 1;
90
- color: rgb(255 255 255 / var(--tw-text-opacity))
91
- }</style>
@@ -6,7 +6,7 @@ declare const __propDef: {
6
6
  disabled?: boolean | undefined;
7
7
  };
8
8
  events: {
9
- click: CustomEvent<any>;
9
+ click: MouseEvent;
10
10
  } & {
11
11
  [evt: string]: CustomEvent<any>;
12
12
  };
@@ -32,7 +32,7 @@ async function handleScheduleInput(input) {
32
32
  }
33
33
  </script>
34
34
 
35
- <div class="text-purple-500 text-2xs grow">{cronError}</div>
35
+ <div class="text-red-600 text-2xs grow">{cronError}</div>
36
36
  <div class="flex flex-row items-end max-w-5xl">
37
37
  <label class="text-xs min-w-max mr-2 self-center" for="cron-schedule">CRON expression</label>
38
38
  <input
@@ -4,6 +4,7 @@ import TableCustom from './TableCustom.svelte';
4
4
  import { truncate } from '../utils';
5
5
  export let result;
6
6
  let resultKind = inferResultKind(result);
7
+ let forceJson = false;
7
8
  function isRectangularArray(obj) {
8
9
  if (!Array.isArray(obj) || obj.length == 0) {
9
10
  return false;
@@ -40,6 +41,9 @@ function inferResultKind(result) {
40
41
  else if (keys.length == 1 && keys[0] == 'file') {
41
42
  return 'file';
42
43
  }
44
+ else if (keys.length == 1 && keys[0] == 'error') {
45
+ return 'error';
46
+ }
43
47
  }
44
48
  catch (err) { }
45
49
  }
@@ -47,13 +51,17 @@ function inferResultKind(result) {
47
51
  }
48
52
  </script>
49
53
 
50
- <div>
54
+ <div class="inline-highlight">
51
55
  {#if result}
52
- {#if typeof result == 'object' && Object.keys(result).length > 0}
53
- <div>
54
- The result keys are: <b>{truncate(Object.keys(result).join(', '), 50)}</b>
55
- </div>{/if}{#if resultKind == 'table-col'}
56
- <div class="grid grid-flow-col-dense border border-gray-200 rounded-md ">
56
+ {#if resultKind && resultKind != 'json'}
57
+ <div class="mb-2 text-gray-500 text-sm bg-gray-50/20">
58
+ as JSON <input type="checkbox" bind:checked={forceJson} /></div
59
+ >{/if}{#if typeof result == 'object' && Object.keys(result).length > 0}<div
60
+ class="mb-2 text-gray-700"
61
+ >The result keys are: <b>{truncate(Object.keys(result).join(', '), 50)}</b></div
62
+ >{/if}{#if !forceJson && resultKind == 'table-col'}<div
63
+ class="grid grid-flow-col-dense border border-gray-200 rounded-md "
64
+ >
57
65
  {#each Object.keys(result) as col}
58
66
  <div class="flex flex-col max-h-40 min-w-full overflow-auto">
59
67
  <div
@@ -71,7 +79,7 @@ function inferResultKind(result) {
71
79
  </div>
72
80
  {/each}
73
81
  </div>
74
- {:else if resultKind == 'table-row'}<div
82
+ {:else if !forceJson && resultKind == 'table-row'}<div
75
83
  class="grid grid-flow-col-dense border border-gray-200 rounded-md "
76
84
  >
77
85
  <TableCustom>
@@ -86,37 +94,31 @@ function inferResultKind(result) {
86
94
  </tbody>
87
95
  </TableCustom>
88
96
  </div>
89
- {:else if resultKind == 'png'}
90
- <div class="h-full">
91
- Result is an image: <img
92
- alt="png rendered"
93
- class="w-auto h-full"
94
- src="data:image/png;base64,{result.png}"
95
- />
97
+ {:else if !forceJson && resultKind == 'png'}
98
+ <div class="h-full"
99
+ ><img alt="png rendered" class="w-auto h-full" src="data:image/png;base64,{result.png}" />
96
100
  </div>
97
- {:else if resultKind == 'jpeg'}
98
- <div class="h-full">
99
- Result is an image: <img
101
+ {:else if !forceJson && resultKind == 'jpeg'}
102
+ <div class="h-full"
103
+ ><img
100
104
  alt="jpeg rendered"
101
105
  class="w-auto h-full"
102
106
  src="data:image/jpeg;base64,{result.jpeg}"
103
107
  />
104
108
  </div>
105
- {:else if resultKind == 'gif'}
106
- <div class="h-full">
107
- Result is an image: <img
108
- alt="gif rendered"
109
- class="w-auto h-full"
110
- src="data:image/gif;base64,{result.gif}"
111
- />
109
+ {:else if !forceJson && resultKind == 'gif'}
110
+ <div class="h-full"
111
+ ><img alt="gif rendered" class="w-auto h-full" src="data:image/gif;base64,{result.gif}" />
112
112
  </div>
113
- {:else if resultKind == 'file'}
114
- <div>
115
- Result is a file: <a
116
- download="windmill.file"
117
- href="data:application/octet-stream;base64,{result.file}">Download</a
113
+ {:else if !forceJson && resultKind == 'file'}
114
+ <div
115
+ ><a download="windmill.file" href="data:application/octet-stream;base64,{result.file}"
116
+ >Download</a
118
117
  >
119
118
  </div>
119
+ {:else if !forceJson && resultKind == 'error'}<div
120
+ ><pre class="text-sm text-red-500">{result.error}</pre>
121
+ </div>
120
122
  {:else}<Highlight
121
123
  language={json}
122
124
  code={JSON.stringify(result, null, 4).replace(/\\n/g, '\n')}
@@ -2,6 +2,7 @@
2
2
  import { createEventDispatcher } from 'svelte';
3
3
  import Icon from 'svelte-awesome';
4
4
  import { faEllipsisH } from '@fortawesome/free-solid-svg-icons';
5
+ import { Button } from './common';
5
6
  let open = false;
6
7
  export let dropdownItems;
7
8
  export let name = undefined;
@@ -20,15 +21,16 @@ function handleClickOutsideMenu(event) {
20
21
  </script>
21
22
 
22
23
  <div
23
- class="ml-3 {relative ? 'relative' : ''} {$$props.class}"
24
+ class="ml-2 {relative ? 'relative' : ''} {$$props.class}"
24
25
  use:clickOutside
25
26
  on:click_outside={handleClickOutsideMenu}
26
27
  >
27
- <button
28
- class="text-blue-500 text-right "
29
- id="dropdown"
28
+ <Button
29
+ color="light"
30
+ size="xs"
30
31
  aria-expanded="false"
31
32
  aria-haspopup="true"
33
+ btnClasses="!text-blue-500 bg-transparent"
32
34
  on:click={openMenu}
33
35
  >
34
36
  {#if !name}
@@ -36,7 +38,7 @@ function handleClickOutsideMenu(event) {
36
38
  {:else}
37
39
  {name}
38
40
  {/if}
39
- </button>
41
+ </Button>
40
42
  <div
41
43
  class="flex flex-col z-50 origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none {open
42
44
  ? 'visible'
@@ -48,10 +50,10 @@ function handleClickOutsideMenu(event) {
48
50
  {#each dropdownItems as item, i}
49
51
  {#if item.action}
50
52
  <button
51
- on:click={() => {
53
+ on:click={(event) => {
52
54
  if (!item.disabled) {
53
55
  open = false
54
- item.action && item.action()
56
+ item.action && item.action(event)
55
57
  dispatch('click', { item: item?.eventName })
56
58
  }
57
59
  }}
@@ -22,6 +22,7 @@ import getMessageServiceOverride from 'vscode/service-override/messages';
22
22
  import { StandaloneServices } from 'vscode/services';
23
23
  import { DENO_INIT_CODE_CLEAR, PYTHON_INIT_CODE_CLEAR } from '../script_helpers';
24
24
  import { createHash as randomHash, editorConfig, langToExt, updateOptions } from '../editorUtils';
25
+ import { dirtyStore } from './common/confirmationModal/dirtyStore';
25
26
  try {
26
27
  StandaloneServices.initialize({
27
28
  ...getMessageServiceOverride(document.body)
@@ -312,18 +313,9 @@ async function loadMonaco() {
312
313
  const model = monaco.editor.createModel(code, lang, monaco.Uri.parse(uri));
313
314
  model.updateOptions(updateOptions);
314
315
  editor = monaco.editor.create(divEl, editorConfig(model, code, lang, automaticLayout));
315
- if (shouldBindKey) {
316
- editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
317
- format();
318
- });
319
- editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, function () {
320
- if (cmdEnterAction) {
321
- cmdEnterAction();
322
- }
323
- });
324
- }
325
316
  let timeoutModel = undefined;
326
317
  editor.onDidChangeModelContent((event) => {
318
+ $dirtyStore = true;
327
319
  timeoutModel && clearTimeout(timeoutModel);
328
320
  timeoutModel = setTimeout(() => {
329
321
  code = getCode();
@@ -332,6 +324,14 @@ async function loadMonaco() {
332
324
  });
333
325
  editor.onDidFocusEditorText(() => {
334
326
  dispatch('focus');
327
+ editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
328
+ code = getCode();
329
+ shouldBindKey && format && format();
330
+ });
331
+ editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, function () {
332
+ code = getCode();
333
+ shouldBindKey && cmdEnterAction && cmdEnterAction();
334
+ });
335
335
  if (!websocketAlive.black &&
336
336
  !websocketAlive.deno &&
337
337
  !websocketAlive.pyright &&
@@ -375,10 +375,6 @@ onDestroy(() => {
375
375
  });
376
376
  </script>
377
377
 
378
- <!-- <button class="default-button px-6 max-h-8" type="button" on:click={format}>
379
- Format (CtrlCmd + S)
380
- </button> -->
381
-
382
378
  <div bind:this={divEl} class={$$props.class} />
383
379
 
384
380
  <style>