windmill-components 1.103.2 → 1.109.1

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 (164) hide show
  1. package/package/components/AppConnect.svelte +4 -1
  2. package/package/components/ArgInput.svelte +81 -68
  3. package/package/components/ArgInput.svelte.d.ts +0 -2
  4. package/package/components/Awareness.svelte +17 -0
  5. package/package/components/Awareness.svelte.d.ts +14 -0
  6. package/package/components/CliHelpBox.svelte +2 -5
  7. package/package/components/Editor.svelte +81 -30
  8. package/package/components/Editor.svelte.d.ts +4 -0
  9. package/package/components/EditorBar.svelte +127 -131
  10. package/package/components/EditorBar.svelte.d.ts +8 -0
  11. package/package/components/FlowBuilder.svelte +6 -1
  12. package/package/components/FlowStatusViewer.svelte +157 -144
  13. package/package/components/FlowStatusViewer.svelte.d.ts +1 -0
  14. package/package/components/HighlightCode.svelte +9 -2
  15. package/package/components/HighlightCode.svelte.d.ts +1 -0
  16. package/package/components/InputTransformForm.svelte +1 -1
  17. package/package/components/InputTransformSchemaForm.svelte +4 -1
  18. package/package/components/InputTransformSchemaForm.svelte.d.ts +3 -0
  19. package/package/components/ObjectTypeNarrowing.svelte +8 -2
  20. package/package/components/ResourcePicker.svelte +0 -1
  21. package/package/components/ResourceTypePicker.svelte +1 -1
  22. package/package/components/RunForm.svelte.d.ts +1 -1
  23. package/package/components/ScheduleEditor.svelte +35 -3
  24. package/package/components/SchemaEditor.svelte +7 -8
  25. package/package/components/SchemaEditor.svelte.d.ts +1 -1
  26. package/package/components/SchemaForm.svelte.d.ts +1 -1
  27. package/package/components/SchemaModal.svelte +7 -12
  28. package/package/components/SchemaModal.svelte.d.ts +2 -3
  29. package/package/components/SchemaViewer.svelte +7 -1
  30. package/package/components/SchemaViewer.svelte.d.ts +1 -1
  31. package/package/components/ScriptBuilder.svelte +95 -21
  32. package/package/components/ScriptEditor.svelte +114 -6
  33. package/package/components/ScriptEditor.svelte.d.ts +7 -1
  34. package/package/components/ScriptSchema.svelte.d.ts +1 -1
  35. package/package/components/TemplateEditor.svelte +1 -0
  36. package/package/components/Toggle.svelte +1 -1
  37. package/package/components/Urlize.svelte +19 -0
  38. package/package/components/Urlize.svelte.d.ts +16 -0
  39. package/package/components/UserSettings.svelte +57 -36
  40. package/package/components/UserSettings.svelte.d.ts +1 -0
  41. package/package/components/VariableEditor.svelte +1 -1
  42. package/package/components/apps/components/buttons/AppSchemaForm.svelte +6 -1
  43. package/package/components/apps/components/display/AppDisplayComponent.svelte +6 -1
  44. package/package/components/apps/components/display/AppDownload.svelte +33 -25
  45. package/package/components/apps/components/display/AppFlowStatusComponent.svelte +2 -2
  46. package/package/components/apps/components/display/AppLogsComponent.svelte +2 -2
  47. package/package/components/apps/components/display/AppText.svelte +9 -14
  48. package/package/components/apps/components/display/table/AppAggridTable.svelte +45 -36
  49. package/package/components/apps/components/display/table/AppTable.svelte +5 -2
  50. package/package/components/apps/components/helpers/ComponentErrorHandler.svelte +26 -0
  51. package/package/components/apps/components/helpers/ComponentErrorHandler.svelte.d.ts +18 -0
  52. package/package/components/apps/components/helpers/InputValue.svelte +15 -17
  53. package/package/components/apps/components/helpers/NonRunnableComponent.svelte +1 -1
  54. package/package/components/apps/components/helpers/eval.d.ts +1 -0
  55. package/package/components/apps/components/helpers/eval.js +3 -1
  56. package/package/components/apps/components/inputs/AppCheckbox.svelte +21 -8
  57. package/package/components/apps/components/inputs/AppDateInput.svelte +6 -1
  58. package/package/components/apps/components/inputs/AppMultiSelect.svelte +18 -7
  59. package/package/components/apps/components/inputs/AppNumberInput.svelte +6 -1
  60. package/package/components/apps/components/inputs/AppRangeInput.svelte +6 -2
  61. package/package/components/apps/components/inputs/AppSelect.svelte +11 -3
  62. package/package/components/apps/components/inputs/AppSelectStep.svelte +19 -6
  63. package/package/components/apps/components/inputs/AppSelectTab.svelte +9 -1
  64. package/package/components/apps/components/inputs/AppSliderInputs.svelte +6 -1
  65. package/package/components/apps/components/inputs/AppTextInput.svelte +6 -1
  66. package/package/components/apps/components/inputs/currency/AppCurrencyInput.svelte +6 -1
  67. package/package/components/apps/components/inputs/currency/CurrencyInput.svelte +0 -1
  68. package/package/components/apps/editor/AppEditor.svelte +4 -7
  69. package/package/components/apps/editor/AppEditor.svelte.d.ts +3 -2
  70. package/package/components/apps/editor/AppEditorHeader.svelte +38 -11
  71. package/package/components/apps/editor/AppEditorHeader.svelte.d.ts +3 -0
  72. package/package/components/apps/editor/AppPreview.svelte +9 -7
  73. package/package/components/apps/editor/AppPreview.svelte.d.ts +6 -6
  74. package/package/components/apps/editor/ConnectionInstructions.svelte +1 -0
  75. package/package/components/apps/editor/DeploymentHistory.svelte +70 -0
  76. package/package/components/apps/editor/DeploymentHistory.svelte.d.ts +18 -0
  77. package/package/components/apps/editor/RecomputeAllComponents.svelte +49 -20
  78. package/package/components/apps/editor/component/ComponentNavigation.svelte +51 -20
  79. package/package/components/apps/editor/component/ComponentNavigation.svelte.d.ts +4 -1
  80. package/package/components/apps/editor/component/components.d.ts +50 -49
  81. package/package/components/apps/editor/component/components.js +6 -0
  82. package/package/components/apps/editor/inlineScriptsPanel/EmptyInlineScript.svelte +1 -0
  83. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte +2 -2
  84. package/package/components/apps/editor/settingsPanel/ComponentPanel.svelte +1 -4
  85. package/package/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte +4 -7
  86. package/package/components/apps/rx.js +6 -1
  87. package/package/components/apps/types.d.ts +1 -1
  88. package/package/components/apps/utils.js +1 -0
  89. package/package/components/common/button/ButtonDropdown.svelte +45 -19
  90. package/package/components/common/button/ButtonDropdown.svelte.d.ts +1 -0
  91. package/package/components/common/modal/Modal.svelte +13 -2
  92. package/package/components/common/modal/Modal.svelte.d.ts +1 -0
  93. package/package/components/common/table/AppRow.svelte +33 -3
  94. package/package/components/flows/content/FlowModuleCache.svelte +37 -0
  95. package/package/components/flows/content/FlowModuleCache.svelte.d.ts +17 -0
  96. package/package/components/flows/content/FlowModuleComponent.svelte +57 -54
  97. package/package/components/flows/content/FlowModuleEarlyStop.svelte +1 -1
  98. package/package/components/flows/content/FlowModuleHeader.svelte +12 -1
  99. package/package/components/flows/content/FlowModuleHeader.svelte.d.ts +1 -0
  100. package/package/components/flows/content/FlowModuleSleep.svelte +1 -1
  101. package/package/components/flows/content/FlowModuleSuspend.svelte +1 -7
  102. package/package/components/flows/content/ScriptEditorDrawer.svelte +2 -1
  103. package/package/components/flows/map/FlowModuleSchemaItem.svelte +13 -1
  104. package/package/components/flows/map/FlowModuleSchemaItem.svelte.d.ts +1 -0
  105. package/package/components/flows/map/FlowModuleSchemaMap.svelte +49 -5
  106. package/package/components/flows/map/MapItem.svelte +9 -2
  107. package/package/components/flows/map/MapItem.svelte.d.ts +1 -0
  108. package/package/components/flows/pickers/PickHubApp.svelte +2 -1
  109. package/package/components/flows/pickers/PickHubApp.svelte.d.ts +1 -0
  110. package/package/components/flows/pickers/PickHubFlow.svelte +2 -1
  111. package/package/components/flows/pickers/PickHubFlow.svelte.d.ts +1 -0
  112. package/package/components/flows/pickers/PickHubScript.svelte +2 -1
  113. package/package/components/flows/pickers/PickHubScript.svelte.d.ts +1 -0
  114. package/package/components/flows/previousResults.d.ts +2 -0
  115. package/package/components/flows/previousResults.js +46 -0
  116. package/package/components/graph/FlowGraph.svelte +1 -1
  117. package/package/components/home/ItemsList.svelte +11 -3
  118. package/package/components/home/ListFilters.svelte +39 -0
  119. package/package/components/home/ListFilters.svelte.d.ts +4 -0
  120. package/package/components/propertyPicker/ObjectViewer.svelte +77 -79
  121. package/package/components/propertyPicker/ObjectViewer.svelte.d.ts +1 -1
  122. package/package/components/propertyPicker/PropPicker.svelte +18 -0
  123. package/package/components/sidebar/MultiplayerMenu.svelte +123 -0
  124. package/package/components/sidebar/MultiplayerMenu.svelte.d.ts +16 -0
  125. package/package/components/sidebar/WorkspaceMenu.svelte +1 -1
  126. package/package/gen/core/CancelablePromise.d.ts +2 -8
  127. package/package/gen/core/CancelablePromise.js +38 -36
  128. package/package/gen/core/OpenAPI.js +1 -1
  129. package/package/gen/core/request.js +3 -2
  130. package/package/gen/models/AuditLog.d.ts +1 -1
  131. package/package/gen/models/CreateInput.d.ts +1 -1
  132. package/package/gen/models/FlowMetadata.d.ts +1 -1
  133. package/package/gen/models/FlowModule.d.ts +1 -0
  134. package/package/gen/models/Input.d.ts +1 -1
  135. package/package/gen/models/NewScript.d.ts +2 -1
  136. package/package/gen/models/NewToken.d.ts +1 -0
  137. package/package/gen/models/OpenFlow.d.ts +1 -1
  138. package/package/gen/models/Policy.d.ts +1 -1
  139. package/package/gen/models/Script.d.ts +2 -1
  140. package/package/gen/models/TruncatedToken.d.ts +1 -0
  141. package/package/gen/services/AppService.d.ts +1 -1
  142. package/package/gen/services/JobService.d.ts +64 -4
  143. package/package/gen/services/JobService.js +45 -0
  144. package/package/gen/services/ResourceService.d.ts +2 -1
  145. package/package/gen/services/ResourceService.js +4 -1
  146. package/package/gen/services/ScriptService.d.ts +0 -45
  147. package/package/gen/services/ScriptService.js +0 -52
  148. package/package/gen/services/SettingsService.d.ts +6 -0
  149. package/package/gen/services/SettingsService.js +11 -0
  150. package/package/gen/services/UserService.d.ts +14 -0
  151. package/package/gen/services/UserService.js +11 -0
  152. package/package/gen/services/VariableService.d.ts +12 -0
  153. package/package/gen/services/VariableService.js +16 -0
  154. package/package/hub.d.ts +1 -1
  155. package/package/infer.js +8 -13
  156. package/package/navigation.d.ts +1 -1
  157. package/package/navigation.js +6 -1
  158. package/package/script_helpers.d.ts +1 -1
  159. package/package/script_helpers.js +6 -1
  160. package/package/stores.d.ts +2 -0
  161. package/package/stores.js +4 -2
  162. package/package/utils.d.ts +1 -0
  163. package/package/utils.js +14 -0
  164. package/package.json +23 -19
@@ -4,7 +4,7 @@ declare const __propDef: {
4
4
  props: {
5
5
  isFlowInput?: boolean | undefined;
6
6
  lightMode?: boolean | undefined;
7
- schema?: Schema | undefined;
7
+ schema?: Schema | any;
8
8
  getSchema?: (() => Schema) | undefined;
9
9
  };
10
10
  events: {
@@ -2,7 +2,7 @@ import { SvelteComponentTyped } from "svelte";
2
2
  import type { Schema } from '../common';
3
3
  declare const __propDef: {
4
4
  props: {
5
- schema: Schema;
5
+ schema: Schema | any;
6
6
  args?: Record<string, any> | undefined;
7
7
  disabledArgs?: string[] | undefined;
8
8
  disabled?: boolean | undefined;
@@ -29,23 +29,22 @@ import { Alert, Button } from './common';
29
29
  import Toggle from './Toggle.svelte';
30
30
  import DrawerContent from './common/drawer/DrawerContent.svelte';
31
31
  import Drawer from './common/drawer/Drawer.svelte';
32
- export let property = DEFAULT_PROPERTY;
33
32
  export let error = '';
34
33
  export let editing = false;
35
34
  export let oldArgName = undefined;
36
35
  export let isFlowInput = false;
37
- let resource_type = undefined;
38
36
  const dispatch = createEventDispatcher();
39
37
  let drawer;
38
+ let property = DEFAULT_PROPERTY;
40
39
  function handleKeyUp(event) {
41
40
  const key = event.key;
42
41
  if (key === 'Enter') {
43
- dispatch('save');
42
+ dispatch('save', property);
44
43
  }
45
44
  }
46
- export function openDrawer() {
45
+ export function openDrawer(nproperty) {
47
46
  drawer.openDrawer();
48
- resource_type = property.format?.substring(5);
47
+ property = nproperty;
49
48
  }
50
49
  export function closeDrawer() {
51
50
  drawer.closeDrawer();
@@ -60,12 +59,8 @@ function clearModal() {
60
59
  property.required = DEFAULT_PROPERTY.required;
61
60
  property.selectedType = DEFAULT_PROPERTY.selectedType;
62
61
  property.format = undefined;
63
- resource_type = undefined;
64
62
  drawer.closeDrawer();
65
63
  }
66
- $: if (property.selectedType == 'object' && resource_type) {
67
- property.format = resource_type ? `$res:${resource_type}` : undefined;
68
- }
69
64
  $: if (property.name == '') {
70
65
  error = 'Name is required';
71
66
  }
@@ -142,7 +137,7 @@ else {
142
137
  </div>
143
138
  </div>
144
139
  <div>
145
- <div class="flex flex-row gap-x-4">
140
+ <div class="flex flex-row gap-x-4 items-center">
146
141
  <ArgInput
147
142
  label="Default"
148
143
  bind:value={property.default}
@@ -151,7 +146,7 @@ else {
151
146
  />
152
147
  <Toggle
153
148
  options={{ right: 'Required' }}
154
- class="mt-5 !justify-start"
149
+ class="!justify-start"
155
150
  bind:checked={property.required}
156
151
  />
157
152
  </div>
@@ -194,7 +189,7 @@ else {
194
189
  color="blue"
195
190
  disabled={!property.name || !property.selectedType || error != ''}
196
191
  on:click={() => {
197
- dispatch('save')
192
+ dispatch('save', property)
198
193
  }}
199
194
  >
200
195
  Save
@@ -20,12 +20,11 @@ export declare function schemaToModal(schema: SchemaProperty, name: string, requ
20
20
  export declare const DEFAULT_PROPERTY: ModalSchemaProperty;
21
21
  declare const __propDef: {
22
22
  props: {
23
- property?: ModalSchemaProperty | undefined;
24
23
  error?: string | undefined;
25
24
  editing?: boolean | undefined;
26
25
  oldArgName?: string | undefined;
27
26
  isFlowInput?: boolean | undefined;
28
- openDrawer?: (() => void) | undefined;
27
+ openDrawer?: ((nproperty: ModalSchemaProperty) => void) | undefined;
29
28
  closeDrawer?: (() => void) | undefined;
30
29
  };
31
30
  events: {
@@ -39,7 +38,7 @@ export type SchemaModalProps = typeof __propDef.props;
39
38
  export type SchemaModalEvents = typeof __propDef.events;
40
39
  export type SchemaModalSlots = typeof __propDef.slots;
41
40
  export default class SchemaModal extends SvelteComponentTyped<SchemaModalProps, SchemaModalEvents, SchemaModalSlots> {
42
- get openDrawer(): () => void;
41
+ get openDrawer(): (nproperty: ModalSchemaProperty) => void;
43
42
  get closeDrawer(): () => void;
44
43
  }
45
44
  export {};
@@ -7,6 +7,12 @@ import TabContent from './common/tabs/TabContent.svelte';
7
7
  import Tabs from './common/tabs/Tabs.svelte';
8
8
  import { Badge } from './common';
9
9
  export let schema = emptySchema();
10
+ function getProperties(schema) {
11
+ if (schema.properties) {
12
+ return Object.entries(schema.properties);
13
+ }
14
+ return [];
15
+ }
10
16
  </script>
11
17
 
12
18
  <div class="w-full">
@@ -28,7 +34,7 @@ export let schema = emptySchema();
28
34
  <th>required</th>
29
35
  </tr>
30
36
  <tbody slot="body">
31
- {#each Object.entries(schema.properties) as [name, property] (name)}
37
+ {#each getProperties(schema) as [name, property] (name)}
32
38
  <tr>
33
39
  <td class="font-semibold pl-1">{name}</td>
34
40
  <td
@@ -2,7 +2,7 @@ import { SvelteComponentTyped } from "svelte";
2
2
  import type { Schema } from '../common';
3
3
  declare const __propDef: {
4
4
  props: {
5
- schema?: Schema | undefined;
5
+ schema?: Schema | undefined | any;
6
6
  };
7
7
  events: {
8
8
  [evt: string]: CustomEvent<any>;
@@ -3,23 +3,26 @@ import { goto } from '$app/navigation';
3
3
  import { page } from '$app/stores';
4
4
  import { inferArgs } from '../infer';
5
5
  import { initialCode } from '../script_helpers';
6
- import { userStore, workerTags, workspaceStore } from '../stores';
6
+ import { enterpriseLicense, userStore, workerTags, workspaceStore } from '../stores';
7
7
  import { emptySchema, encodeState, getModifierKey, setQueryWithoutLoad } from '../utils';
8
8
  import Path from './Path.svelte';
9
9
  import ScriptEditor from './ScriptEditor.svelte';
10
10
  import ScriptSchema from './ScriptSchema.svelte';
11
11
  import { dirtyStore } from './common/confirmationModal/dirtyStore';
12
- import { Badge, Button, Drawer, Kbd } from './common';
13
- import { faSave } from '@fortawesome/free-solid-svg-icons';
12
+ import { Alert, Badge, Button, Drawer, Kbd } from './common';
13
+ import { faPlus, faSave } from '@fortawesome/free-solid-svg-icons';
14
14
  import LanguageIcon from './common/languageIcons/LanguageIcon.svelte';
15
15
  import Tooltip from './Tooltip.svelte';
16
16
  import DrawerContent from './common/drawer/DrawerContent.svelte';
17
- import { Pen } from 'lucide-svelte';
17
+ import { Pen, X } from 'lucide-svelte';
18
18
  import autosize from 'svelte-autosize';
19
19
  import { SCRIPT_SHOW_BASH, SCRIPT_SHOW_GO, SCRIPT_SHOW_PSQL, SCRIPT_CUSTOMISE_SHOW_KIND } from '../consts';
20
20
  import UnsavedConfirmationModal from './common/confirmationModal/UnsavedConfirmationModal.svelte';
21
21
  import { sendUserToast } from '../toast';
22
22
  import { isCloudHosted } from '../cloud';
23
+ import Awareness from './Awareness.svelte';
24
+ import { Icon } from 'svelte-awesome';
25
+ import { fade } from 'svelte/transition';
23
26
  export let script;
24
27
  export let initialPath = '';
25
28
  export let template = 'script';
@@ -27,7 +30,10 @@ export let initialArgs = {};
27
30
  export let lockedLanguage = false;
28
31
  export let topHash = undefined;
29
32
  export let showMeta = false;
30
- let metadataOpen = showMeta || (initialPath == '' && $page.url.searchParams.get('state') == undefined);
33
+ let metadataOpen = showMeta ||
34
+ (initialPath == '' &&
35
+ $page.url.searchParams.get('state') == undefined &&
36
+ $page.url.searchParams.get('collab') == undefined);
31
37
  let advancedOpen = false;
32
38
  let editor = undefined;
33
39
  let scriptEditor = undefined;
@@ -77,13 +83,25 @@ const scriptKindOptions = [
77
83
  let pathError = '';
78
84
  let loadingSave = false;
79
85
  let loadingDraft = false;
80
- $: setQueryWithoutLoad($page.url, [{ key: 'state', value: encodeState(script) }]);
86
+ $: {
87
+ ;
88
+ ['collab', 'path'].forEach((x) => {
89
+ if ($page.url.searchParams.get(x)) {
90
+ $page.url.searchParams.delete(x);
91
+ }
92
+ });
93
+ setQueryWithoutLoad($page.url, [{ key: 'state', value: encodeState(script) }]);
94
+ }
81
95
  if (script.content == '') {
82
96
  initContent(script.language, script.kind, template);
83
97
  }
84
98
  function initContent(language, kind, template) {
99
+ scriptEditor?.disableCollaboration();
85
100
  script.content = initialCode(language, kind, template);
86
101
  scriptEditor?.inferSchema(script.content, language);
102
+ if (script.content != editor?.getCode()) {
103
+ setCode(script.content);
104
+ }
87
105
  }
88
106
  async function editScript() {
89
107
  loadingSave = true;
@@ -109,7 +127,8 @@ async function editScript() {
109
127
  is_template: script.is_template,
110
128
  language: script.language,
111
129
  kind: script.kind,
112
- tag: script.tag
130
+ tag: script.tag,
131
+ envs: script.envs
113
132
  }
114
133
  });
115
134
  history.replaceState(history.state, '', `/scripts/edit/${script.path}`);
@@ -145,7 +164,8 @@ async function saveDraft() {
145
164
  language: script.language,
146
165
  kind: script.kind,
147
166
  tag: script.tag,
148
- draft_only: true
167
+ draft_only: true,
168
+ envs: script.envs
149
169
  }
150
170
  });
151
171
  }
@@ -234,13 +254,9 @@ function onKeyDown(event) {
234
254
  color={isPicked ? 'blue' : 'dark'}
235
255
  btnClasses={isPicked ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
236
256
  on:click={() => {
237
- let lastTemplate = template
238
257
  template = 'script'
239
258
  initContent(lang, script.kind, template)
240
259
  script.language = lang
241
- if (lastTemplate != template) {
242
- setCode(script.content)
243
- }
244
260
  }}
245
261
  disabled={lockedLanguage}
246
262
  >
@@ -256,13 +272,9 @@ function onKeyDown(event) {
256
272
  btnClasses={template == 'pgsql' ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
257
273
  disabled={lockedLanguage}
258
274
  on:click={() => {
259
- let lastTemplate = template
260
275
  template = 'pgsql'
261
276
  initContent(Script.language.DENO, script.kind, template)
262
277
  script.language = Script.language.DENO
263
- if (lastTemplate != template) {
264
- setCode(script.content)
265
- }
266
278
  }}
267
279
  >
268
280
  <LanguageIcon lang="pgsql" /><span class="ml-2 py-2">PostgreSQL</span>
@@ -290,13 +302,9 @@ function onKeyDown(event) {
290
302
  )
291
303
  return
292
304
  }
293
- let lastTemplate = template
294
305
  template = 'docker'
295
306
  initContent(Script.language.BASH, script.kind, template)
296
307
  script.language = Script.language.BASH
297
- if (lastTemplate != template) {
298
- setCode(script.content)
299
- }
300
308
  }}
301
309
  >
302
310
  <LanguageIcon lang="docker" /><span class="ml-2 py-2">Docker</span>
@@ -358,6 +366,57 @@ function onKeyDown(event) {
358
366
  {/if}
359
367
  {/if}
360
368
  </div>
369
+ {#if !isCloudHosted()}
370
+ <h2 class="border-b pb-1 mt-10 mb-4"
371
+ >Custom env variables<Tooltip
372
+ >Additional static custom env variables to pass to the script.</Tooltip
373
+ ></h2
374
+ >
375
+ <div class="w-full">
376
+ <span class="text-gray-600 text-xs pb-2">Format is: `{'<KEY>=<VALUE>'}`</span>
377
+ {#if Array.isArray(script.envs ?? [])}
378
+ {#each script.envs ?? [] as v, i}
379
+ <div class="flex max-w-md mt-1 w-full items-center">
380
+ <input type="text" bind:value={v} placeholder="<KEY>=<VALUE>" />
381
+ <button
382
+ transition:fade|local={{ duration: 50 }}
383
+ class="rounded-full p-1 bg-white/60 duration-200 hover:bg-gray-200"
384
+ aria-label="Clear"
385
+ on:click={() => {
386
+ script.envs && script.envs.splice(i, 1)
387
+ script.envs = script.envs
388
+ }}
389
+ >
390
+ <X size={14} />
391
+ </button>
392
+ </div>
393
+ {/each}
394
+ {#if script.envs && script.envs.length > 0}
395
+ <div class="pt-2" />
396
+ <Alert type="warning" title="Not passed in previews"
397
+ >Static envs variables are not passed in preview but solely on deployed scripts.</Alert
398
+ >
399
+ {/if}
400
+ {/if}
401
+ </div>
402
+ {/if}
403
+ <div class="flex mt-2">
404
+ <Button
405
+ variant="border"
406
+ color="dark"
407
+ size="xs"
408
+ btnClasses="mt-1"
409
+ on:click={() => {
410
+ if (script.envs == undefined || !Array.isArray(script.envs)) {
411
+ script.envs = []
412
+ }
413
+ script.envs = script.envs.concat('')
414
+ }}
415
+ >
416
+ <Icon data={faPlus} class="mr-2" />
417
+ Add item
418
+ </Button>
419
+ </div>
361
420
  </DrawerContent>
362
421
  </Drawer>
363
422
 
@@ -409,7 +468,21 @@ function onKeyDown(event) {
409
468
  <LanguageIcon lang={script.language} />
410
469
  </button>
411
470
  </div>
471
+ {#if $enterpriseLicense && initialPath != ''}
472
+ <Awareness />
473
+ {/if}
474
+
412
475
  <div class="flex flex-row gap-x-4">
476
+ <Button
477
+ color="light"
478
+ variant="border"
479
+ size="xs"
480
+ on:click={() => {
481
+ metadataOpen = true
482
+ }}
483
+ >
484
+ Metadata
485
+ </Button>
413
486
  <Button
414
487
  color="dark"
415
488
  variant="border"
@@ -464,7 +537,6 @@ function onKeyDown(event) {
464
537
  template = 'script'
465
538
  script.kind = value
466
539
  initContent(script.language, value, template)
467
- setCode(script.content)
468
540
  }}
469
541
  >
470
542
  {title}
@@ -487,6 +559,8 @@ function onKeyDown(event) {
487
559
  </DrawerContent>
488
560
  </Drawer>
489
561
  <ScriptEditor
562
+ collabMode
563
+ edit={initialPath != ''}
490
564
  on:format={() => {
491
565
  saveDraft()
492
566
  }}
@@ -1,7 +1,8 @@
1
- <script>import { CompletedJob, Job, JobService } from '../gen';
2
- import { userStore, workspaceStore } from '../stores';
3
- import { emptySchema, getModifierKey } from '../utils';
4
- import { faPlay } from '@fortawesome/free-solid-svg-icons';
1
+ <script>import { BROWSER } from 'esm-env';
2
+ import { CompletedJob, Job, JobService, SettingsService } from '../gen';
3
+ import { enterpriseLicense, userStore, workspaceStore } from '../stores';
4
+ import { copyToClipboard, emptySchema, getModifierKey, sendUserToast } from '../utils';
5
+ import { faClipboard, faPlay } from '@fortawesome/free-solid-svg-icons';
5
6
  import Editor from './Editor.svelte';
6
7
  import { inferArgs } from '../infer';
7
8
  import { Pane, Splitpanes } from 'svelte-splitpanes';
@@ -10,11 +11,15 @@ import LogPanel from './scriptEditor/LogPanel.svelte';
10
11
  import { faGithub } from '@fortawesome/free-brands-svg-icons';
11
12
  import EditorBar, { EDITOR_BAR_WIDTH_THRESHOLD } from './EditorBar.svelte';
12
13
  import TestJobLoader from './TestJobLoader.svelte';
13
- import { createEventDispatcher, onMount } from 'svelte';
14
+ import { createEventDispatcher, onDestroy, onMount } from 'svelte';
14
15
  import { Button, Kbd } from './common';
15
16
  import SplitPanesWrapper from './splitPanes/SplitPanesWrapper.svelte';
16
17
  import WindmillIcon from './icons/WindmillIcon.svelte';
18
+ import * as Y from 'yjs';
17
19
  import { scriptLangToEditorLang } from '../scripts';
20
+ import { WebsocketProvider } from 'y-websocket';
21
+ import Modal from './common/modal/Modal.svelte';
22
+ import { Icon } from 'svelte-awesome';
18
23
  // Exported
19
24
  export let schema = emptySchema();
20
25
  export let code;
@@ -26,6 +31,8 @@ export let initialArgs = {};
26
31
  export let fixedOverflowWidgets = true;
27
32
  export let noSyncFromGithub = false;
28
33
  export let editor = undefined;
34
+ export let collabMode = false;
35
+ export let edit = true;
29
36
  let websocketAlive = {
30
37
  pyright: false,
31
38
  black: false,
@@ -44,6 +51,18 @@ let testIsLoading = false;
44
51
  let testJob;
45
52
  let pastPreviews = [];
46
53
  let validCode = true;
54
+ let wsProvider = undefined;
55
+ let yContent = undefined;
56
+ let peers = [];
57
+ let showCollabPopup = false;
58
+ const url = new URL(window.location.toString());
59
+ let initialCollab = /true|1/i.test(url.searchParams.get('collab') ?? '0');
60
+ if (initialCollab) {
61
+ setCollaborationMode();
62
+ url.searchParams.delete('collab');
63
+ url.searchParams.delete('path');
64
+ history.replaceState(null, '', url);
65
+ }
47
66
  function onKeyDown(event) {
48
67
  if ((event.ctrlKey || event.metaKey) && event.key == 'Enter') {
49
68
  event.preventDefault();
@@ -90,10 +109,74 @@ onMount(() => {
90
109
  inferSchema(code);
91
110
  loadPastTests();
92
111
  });
112
+ export async function setCollaborationMode() {
113
+ if (!$enterpriseLicense) {
114
+ $enterpriseLicense = await SettingsService.getLicenseId();
115
+ }
116
+ if (!$enterpriseLicense) {
117
+ sendUserToast(`Multiplayer is an enterprise feature`, true, [
118
+ {
119
+ label: 'Upgrade',
120
+ callback: () => {
121
+ window.open('https://www.windmill.dev/pricing', '_blank');
122
+ }
123
+ }
124
+ ]);
125
+ return;
126
+ }
127
+ const ydoc = new Y.Doc();
128
+ if (wsProvider) {
129
+ wsProvider.destroy();
130
+ }
131
+ let yContentInit = ydoc.getText('content');
132
+ const wsProtocol = BROWSER && window.location.protocol == 'https:' ? 'wss' : 'ws';
133
+ wsProvider = new WebsocketProvider(`${wsProtocol}://${window.location.host}/ws_mp/`, $workspaceStore + '/' + path ?? 'no-room-name', ydoc, { connect: false });
134
+ wsProvider.on('sync', (isSynced) => {
135
+ if (isSynced && yContentInit?.toJSON() == '') {
136
+ showCollabPopup = true;
137
+ yContentInit?.insert(0, code);
138
+ }
139
+ yContent = yContentInit;
140
+ });
141
+ wsProvider.on('connection-error', (WSErrorEvent) => {
142
+ console.error(WSErrorEvent);
143
+ sendUserToast('Multiplayer server connection had an error', true);
144
+ });
145
+ wsProvider.connect();
146
+ const awareness = wsProvider.awareness;
147
+ awareness.setLocalStateField('user', {
148
+ name: $userStore?.username
149
+ });
150
+ function setPeers() {
151
+ peers = Array.from(awareness.getStates().values()).map((x) => x.user);
152
+ }
153
+ setPeers();
154
+ // You can observe when a user updates their awareness information
155
+ awareness.on('change', (changes) => {
156
+ setPeers();
157
+ });
158
+ }
159
+ export function disableCollaboration() {
160
+ if (!wsProvider?.shouldConnect)
161
+ return;
162
+ peers = [];
163
+ console.log('collab mode disabled');
164
+ wsProvider?.disconnect();
165
+ wsProvider.destroy();
166
+ wsProvider = undefined;
167
+ }
168
+ onDestroy(() => {
169
+ disableCollaboration();
170
+ });
93
171
  const dispatch = createEventDispatcher();
94
172
  function asKind(str) {
95
173
  return str;
96
174
  }
175
+ function collabUrl() {
176
+ let url = new URL(window.location.toString());
177
+ url.search = '';
178
+ return `${url}?collab=1` + (edit ? '' : `&path=${path}`);
179
+ }
97
180
  </script>
98
181
 
99
182
  <TestJobLoader
@@ -105,14 +188,34 @@ function asKind(str) {
105
188
 
106
189
  <svelte:window on:keydown={onKeyDown} />
107
190
 
191
+ <Modal title="Invite others" bind:open={showCollabPopup}>
192
+ <div>Have others join by sharing the following url:</div>
193
+ <div class="flex gap-2 pr-4">
194
+ <input type="text" disabled value={collabUrl()} />
195
+ <button on:click={() => copyToClipboard(collabUrl())} class="text-gray-700 ml-2">
196
+ <Icon data={faClipboard} />
197
+ </button>
198
+ </div>
199
+ </Modal>
108
200
  <div class="border-b-2 shadow-sm px-1 pr-4" bind:clientWidth={width}>
109
201
  <div class="flex justify-between space-x-2">
110
202
  <EditorBar
203
+ on:toggleCollabMode={() => {
204
+ if (wsProvider?.shouldConnect) {
205
+ disableCollaboration()
206
+ } else {
207
+ setCollaborationMode()
208
+ }
209
+ }}
210
+ collabLive={wsProvider?.shouldConnect}
211
+ {collabMode}
111
212
  {validCode}
112
213
  iconOnly={width < EDITOR_BAR_WIDTH_THRESHOLD}
214
+ on:collabPopup={() => (showCollabPopup = true)}
113
215
  {editor}
114
216
  {lang}
115
217
  {websocketAlive}
218
+ collabUsers={peers}
116
219
  kind={asKind(kind)}
117
220
  />
118
221
  {#if !noSyncFromGithub}
@@ -139,10 +242,13 @@ function asKind(str) {
139
242
  <div class="pl-2 h-full !overflow-visible">
140
243
  {#key lang}
141
244
  <Editor
245
+ folding
142
246
  {path}
143
247
  bind:code
144
248
  bind:websocketAlive
145
249
  bind:this={editor}
250
+ {yContent}
251
+ awareness={wsProvider?.awareness}
146
252
  on:change={(e) => {
147
253
  inferSchema(e.detail)
148
254
  }}
@@ -184,7 +290,9 @@ function asKind(str) {
184
290
  {:else}
185
291
  <Button
186
292
  color="dark"
187
- on:click={runTest}
293
+ on:click={() => {
294
+ runTest()
295
+ }}
188
296
  btnClasses="w-full"
189
297
  size="xs"
190
298
  startIcon={{
@@ -4,7 +4,7 @@ import Editor from './Editor.svelte';
4
4
  import type { Preview } from '../gen/models/Preview';
5
5
  declare const __propDef: {
6
6
  props: {
7
- schema?: Schema | undefined;
7
+ schema?: Schema | any;
8
8
  code: string;
9
9
  path: string | undefined;
10
10
  lang: Preview.language;
@@ -14,7 +14,11 @@ declare const __propDef: {
14
14
  fixedOverflowWidgets?: boolean | undefined;
15
15
  noSyncFromGithub?: boolean | undefined;
16
16
  editor?: Editor | undefined;
17
+ collabMode?: boolean | undefined;
18
+ edit?: boolean | undefined;
17
19
  inferSchema?: ((code: string, nlang?: 'go' | 'bash' | 'python3' | 'deno') => Promise<void>) | undefined;
20
+ setCollaborationMode?: (() => Promise<void>) | undefined;
21
+ disableCollaboration?: (() => void) | undefined;
18
22
  };
19
23
  events: {
20
24
  format: CustomEvent<any>;
@@ -28,5 +32,7 @@ export type ScriptEditorEvents = typeof __propDef.events;
28
32
  export type ScriptEditorSlots = typeof __propDef.slots;
29
33
  export default class ScriptEditor extends SvelteComponentTyped<ScriptEditorProps, ScriptEditorEvents, ScriptEditorSlots> {
30
34
  get inferSchema(): (code: string, nlang?: "deno" | "python3" | "go" | "bash" | undefined) => Promise<void>;
35
+ get setCollaborationMode(): () => Promise<void>;
36
+ get disableCollaboration(): () => void;
31
37
  }
32
38
  export {};
@@ -2,7 +2,7 @@ import { SvelteComponentTyped } from "svelte";
2
2
  import type { Schema } from '../common';
3
3
  declare const __propDef: {
4
4
  props: {
5
- schema: Schema;
5
+ schema: Schema | any;
6
6
  setSchema?: ((newSchema: Schema) => void) | undefined;
7
7
  };
8
8
  events: {
@@ -336,6 +336,7 @@ let model;
336
336
  const { componentControl, selectedComponent } = getContext('AppViewerContext') || { componentControl: writable({}), selectedComponent: writable([]) };
337
337
  if ($selectedComponent) {
338
338
  $componentControl[$selectedComponent[0]] = {
339
+ ...$componentControl[$selectedComponent[0]],
339
340
  setCode: (value) => {
340
341
  code = value;
341
342
  setCode(value);
@@ -33,6 +33,7 @@ const dispatch = createEventDispatcher();
33
33
  {options?.left}
34
34
  </span>
35
35
  {/if}
36
+
36
37
  <!-- svelte-ignore a11y-click-events-have-key-events -->
37
38
  <div class="relative" on:click|stopPropagation>
38
39
  <input
@@ -40,7 +41,6 @@ const dispatch = createEventDispatcher();
40
41
  on:click
41
42
  {disabled}
42
43
  type="checkbox"
43
- value={false}
44
44
  {id}
45
45
  class="sr-only peer"
46
46
  bind:checked
@@ -0,0 +1,19 @@
1
+ <script>export let text;
2
+ const parseURL = (input) => {
3
+ if (input.startsWith('http://') || input.startsWith('https://')) {
4
+ return `<a href="${input}" target="_blank" rel="noopener noreferrer">${input}</a>`;
5
+ }
6
+ else {
7
+ return input;
8
+ }
9
+ };
10
+ const parseInput = (input) => {
11
+ if (!input)
12
+ return '';
13
+ const words = input.split(' ');
14
+ return words.map((word) => parseURL(word)).join(' ');
15
+ };
16
+ $: parsed = text ? text.split('\n').map(parseInput).join('\n') : '';
17
+ </script>
18
+
19
+ {@html parsed}
@@ -0,0 +1,16 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ text: string;
5
+ };
6
+ events: {
7
+ [evt: string]: CustomEvent<any>;
8
+ };
9
+ slots: {};
10
+ };
11
+ export type UrlizeProps = typeof __propDef.props;
12
+ export type UrlizeEvents = typeof __propDef.events;
13
+ export type UrlizeSlots = typeof __propDef.slots;
14
+ export default class Urlize extends SvelteComponentTyped<UrlizeProps, UrlizeEvents, UrlizeSlots> {
15
+ }
16
+ export {};