windmill-components 1.28.5 → 1.34.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 (120) hide show
  1. package/common.d.ts +3 -0
  2. package/components/AppConnect.svelte +28 -12
  3. package/components/ArgInput.svelte +28 -14
  4. package/components/ArgInput.svelte.d.ts +4 -0
  5. package/components/CenteredPage.svelte +1 -1
  6. package/components/DisplayResult.svelte +3 -3
  7. package/components/Drawer.svelte +108 -0
  8. package/components/Drawer.svelte.d.ts +23 -0
  9. package/components/Editor.svelte +97 -97
  10. package/components/Editor.svelte.d.ts +3 -0
  11. package/components/EditorBar.svelte +23 -10
  12. package/components/FlowBuilder.svelte +40 -32
  13. package/components/FlowEditor.svelte +19 -57
  14. package/components/FlowEditor.svelte.d.ts +1 -0
  15. package/components/FlowJobResult.svelte +18 -17
  16. package/components/FlowPreview.svelte +14 -36
  17. package/components/FlowPreview.svelte.d.ts +2 -6
  18. package/components/FlowPreviewContent.svelte +56 -44
  19. package/components/FlowPreviewContent.svelte.d.ts +0 -1
  20. package/components/FlowStatusViewer.svelte +123 -205
  21. package/components/FlowStatusViewer.svelte.d.ts +7 -4
  22. package/components/FlowViewer.svelte +19 -13
  23. package/components/IconedPath.svelte +12 -0
  24. package/components/IconedPath.svelte.d.ts +16 -0
  25. package/components/IconedResourceType.svelte +21 -2
  26. package/components/IconedResourceType.svelte.d.ts +1 -0
  27. package/components/InputTransformForm.svelte +9 -8
  28. package/components/InputTransformForm.svelte.d.ts +1 -1
  29. package/components/InviteGlobalUser.svelte +1 -1
  30. package/components/ItemPicker.svelte +6 -1
  31. package/components/JobStatus.svelte +1 -1
  32. package/components/ModuleStep.svelte +73 -95
  33. package/components/ModuleStep.svelte.d.ts +7 -4
  34. package/components/Path.svelte +62 -40
  35. package/components/Path.svelte.d.ts +2 -0
  36. package/components/ProgressBar.svelte +31 -0
  37. package/components/ProgressBar.svelte.d.ts +17 -0
  38. package/components/ProgressBarPart.svelte +20 -0
  39. package/components/ProgressBarPart.svelte.d.ts +20 -0
  40. package/components/ResourceEditor.svelte +2 -1
  41. package/components/ResourcePicker.svelte +9 -0
  42. package/components/SchemaForm.svelte +9 -4
  43. package/components/SchemaForm.svelte.d.ts +1 -1
  44. package/components/SchemaModal.svelte +20 -3
  45. package/components/ScriptBuilder.svelte +58 -21
  46. package/components/ScriptBuilder.svelte.d.ts +1 -0
  47. package/components/ScriptEditor.svelte +4 -2
  48. package/components/SharedBadge.svelte +8 -3
  49. package/components/VariableEditor.svelte +1 -1
  50. package/components/flows/CopyFirstStepSchema.svelte +4 -3
  51. package/components/flows/DynamicInputHelpBox.svelte +6 -4
  52. package/components/flows/DynamicInputHelpBox.svelte.d.ts +1 -1
  53. package/components/flows/FlowBox.svelte +15 -2
  54. package/components/flows/FlowBox.svelte.d.ts +14 -14
  55. package/components/flows/FlowBoxHeader.svelte +10 -3
  56. package/components/flows/FlowBoxHeader.svelte.d.ts +3 -0
  57. package/components/flows/FlowInput.svelte +14 -12
  58. package/components/flows/FlowInputs.svelte +56 -22
  59. package/components/flows/FlowInputs.svelte.d.ts +3 -1
  60. package/components/flows/FlowModuleHeader.svelte +71 -55
  61. package/components/flows/FlowModuleHeader.svelte.d.ts +6 -6
  62. package/components/flows/FlowSettings.svelte +45 -59
  63. package/components/flows/FlowSettings.svelte.d.ts +1 -1
  64. package/components/flows/FlowTimeline.svelte +169 -0
  65. package/components/flows/FlowTimeline.svelte.d.ts +21 -0
  66. package/components/flows/flowState.d.ts +14 -0
  67. package/components/flows/flowState.js +52 -0
  68. package/components/flows/flowStateUtils.d.ts +37 -0
  69. package/components/flows/flowStateUtils.js +222 -0
  70. package/components/flows/flowStore.d.ts +1 -16
  71. package/components/flows/flowStore.js +7 -208
  72. package/components/flows/pickers/FlowScriptPicker.svelte +5 -9
  73. package/components/flows/pickers/FlowScriptPicker.svelte.d.ts +0 -1
  74. package/components/flows/pickers/PickHubScript.svelte +1 -1
  75. package/components/flows/pickers/PickHubScript.svelte.d.ts +1 -1
  76. package/components/flows/pickers/PickScript.svelte +1 -1
  77. package/components/flows/pickers/PickScript.svelte.d.ts +1 -1
  78. package/components/flows/scheduleUtils.d.ts +7 -0
  79. package/components/flows/scheduleUtils.js +21 -0
  80. package/components/flows/stepOpenedStore.d.ts +1 -0
  81. package/components/flows/stepOpenedStore.js +6 -0
  82. package/components/flows/utils.d.ts +5 -12
  83. package/components/flows/utils.js +40 -112
  84. package/components/icons/DiscordIcon.svelte +16 -0
  85. package/components/icons/DiscordIcon.svelte.d.ts +17 -0
  86. package/components/icons/HttpIcon.svelte +21 -0
  87. package/components/icons/HttpIcon.svelte.d.ts +17 -0
  88. package/components/icons/MastodonIcon.svelte +16 -0
  89. package/components/icons/MastodonIcon.svelte.d.ts +17 -0
  90. package/components/icons/MatrixIcon.svelte +16 -0
  91. package/components/icons/MatrixIcon.svelte.d.ts +17 -0
  92. package/components/icons/S3Icon.svelte +16 -0
  93. package/components/icons/S3Icon.svelte.d.ts +17 -0
  94. package/components/icons/WindmillIcon.svelte +68 -0
  95. package/components/icons/WindmillIcon.svelte.d.ts +17 -0
  96. package/components/preview/FlowPreviewStatus.svelte +28 -0
  97. package/components/preview/FlowPreviewStatus.svelte.d.ts +17 -0
  98. package/components/propertyPicker/ObjectViewer.svelte +13 -13
  99. package/components/propertyPicker/utils.js +3 -2
  100. package/components/tabs/Tab.svelte +12 -0
  101. package/components/tabs/Tab.svelte.d.ts +19 -0
  102. package/components/tabs/TabPanel.svelte +11 -0
  103. package/components/tabs/TabPanel.svelte.d.ts +20 -0
  104. package/components/tabs/Tabs.svelte +3 -0
  105. package/components/tabs/Tabs.svelte.d.ts +23 -0
  106. package/gen/core/OpenAPI.js +1 -1
  107. package/gen/core/request.js +1 -0
  108. package/gen/models/MainArgSignature.d.ts +14 -3
  109. package/gen/services/JobService.d.ts +10 -2
  110. package/gen/services/JobService.js +4 -2
  111. package/gen/services/ScriptService.d.ts +18 -0
  112. package/gen/services/ScriptService.js +30 -0
  113. package/infer.js +47 -24
  114. package/package.json +39 -20
  115. package/script_helpers.d.ts +4 -1
  116. package/script_helpers.js +68 -17
  117. package/stores.d.ts +1 -2
  118. package/stores.js +1 -4
  119. package/utils.d.ts +4 -2
  120. package/utils.js +33 -5
@@ -1,7 +1,5 @@
1
1
  <script>import { RawScript } from '../gen';
2
- import { previewResults } from '../stores';
3
- import { buildExtraLib, objectToTsType, schemaToTsType } from '../utils';
4
- import { faChevronDown, faChevronUp, faPlus } from '@fortawesome/free-solid-svg-icons';
2
+ import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
5
3
  import Icon from 'svelte-awesome';
6
4
  import Editor from './Editor.svelte';
7
5
  import EditorBar from './EditorBar.svelte';
@@ -9,80 +7,81 @@ import FlowPreview from './FlowPreview.svelte';
9
7
  import FlowBox from './flows/FlowBox.svelte';
10
8
  import FlowInputs from './flows/FlowInputs.svelte';
11
9
  import FlowModuleHeader from './flows/FlowModuleHeader.svelte';
12
- import { addModule, createInlineScriptModule, flowStore, loadSchema, pickScript, schemasStore } from './flows/flowStore';
13
- import { getPickableProperties, jobsToResults } from './flows/utils';
10
+ import { flowStore } from './flows/flowStore';
11
+ import { createInlineScriptModule, createLoop, fork, loadFlowModuleSchema, pickScript, createScriptFromInlineScript, isEmptyFlowModule, getStepPropPicker } from './flows/flowStateUtils';
14
12
  import SchemaForm from './SchemaForm.svelte';
15
- import Tooltip from './Tooltip.svelte';
16
- export let open;
17
- export let mode;
18
- export let i;
13
+ import { flowStateStore } from './flows/flowState';
14
+ import { stepOpened } from './flows/stepOpenedStore';
15
+ export let indexes;
19
16
  export let mod;
20
17
  export let args = {};
18
+ export let schema;
19
+ export let childFlowModules = undefined;
21
20
  let editor;
22
21
  let websocketAlive = { pyright: false, black: false, deno: false };
23
- let pickableProperties = undefined;
24
22
  let bigEditor = false;
25
- $: schema = $schemasStore[i];
26
- $: shouldPick = 'path' in mod.value && mod.value.path === '' && !('language' in mod.value);
27
- $: pickableProperties = getPickableProperties($flowStore?.schema, args, $previewResults, mode, i);
28
- $: extraLib = buildExtraLib(schemaToTsType($flowStore?.schema), i === 0 ? schemaToTsType($flowStore?.schema) : objectToTsType($previewResults[i]));
29
- const isTrigger = mode === 'pull' && i === 0;
23
+ const i = indexes[0];
24
+ $: shouldPick = isEmptyFlowModule(mod);
25
+ $: stepPropPicker = getStepPropPicker(indexes, $flowStore.schema, $flowStateStore, args);
26
+ async function apply(fn, arg) {
27
+ const flowModuleSchema = await fn(arg);
28
+ mod = flowModuleSchema.flowModule;
29
+ schema = flowModuleSchema.schema;
30
+ if (flowModuleSchema.childFlowModules) {
31
+ childFlowModules = flowModuleSchema.childFlowModules;
32
+ }
33
+ }
34
+ async function reload(flowModule) {
35
+ apply(loadFlowModuleSchema, flowModule);
36
+ }
37
+ async function applyCreateLoop() {
38
+ await apply(createLoop, null);
39
+ stepOpened.update(() => `${indexes[0]}-0`);
40
+ }
41
+ $: opened = $stepOpened === String(indexes.join('-'));
30
42
  </script>
31
43
 
32
- <button
33
- class="rounded-full h-10 w-10 bg-white border-2 border-gray-400"
34
- on:click={() => {
35
- addModule(i)
36
- open = i
37
- }}
44
+ <FlowBox
45
+ headerClickable={true}
46
+ on:clickheader={() => ($stepOpened = !opened ? String(indexes.join('-')) : undefined)}
38
47
  >
39
- <Icon class="text-gray-400 mb-1" data={faPlus} />
40
- </button>
41
- <FlowBox>
42
- <div id="module-{i}">
43
- <FlowModuleHeader bind:open {mod} {i} {shouldPick}>
44
- <div>
45
- <h3 class="text-lg font-bold text-gray-900">Step {i + 1}</h3>
46
- {#if isTrigger}
47
- <h3 class="font-bold">
48
- Trigger Script
49
- <Tooltip>
50
- When a flow is 'Pull', the first step is a trigger script. Trigger scripts are scripts
51
- that must return a list which are the new items to be treated one by one by the rest
52
- of the flow, usually the list of new items since last time the flow was run. One can
53
- retrieve the item in the next step using `previous_result._value`. To easily compute
54
- the diff, windmill provides some helpers under the form of `getInternalState` and
55
- `setInternalState`.
56
- </Tooltip>
57
- </h3>
58
- {/if}
59
- <p>
60
- {#if 'path' in mod.value && mod.value.path}
61
- {mod.value.path}
62
- {/if}
63
- {#if 'language' in mod.value && mod.value.language}
64
- Inline {mod.value.language}
65
- {/if}
66
- {#if !('path' in mod.value) && !('language' in mod.value)}
67
- Select a script
68
- {/if}
69
- </p>
70
- </div>
71
- </FlowModuleHeader>
72
- {#if open == i}
73
- <div class="p-6">
48
+ <svelte:fragment slot="header">
49
+ <FlowModuleHeader
50
+ bind:mod
51
+ bind:indexes
52
+ on:delete
53
+ on:fork={() => apply(fork, mod)}
54
+ on:createScriptFromInlineScript={() => {
55
+ apply(createScriptFromInlineScript, {
56
+ flowModule: mod,
57
+ suffix: indexes.join('-'),
58
+ schema
59
+ })
60
+ }}
61
+ />
62
+ </svelte:fragment>
63
+
64
+ <div slot="content">
65
+ {#if opened}
66
+ <div class="p-6 border-t border-gray-300">
74
67
  {#if shouldPick}
75
68
  <FlowInputs
76
- {isTrigger}
77
- on:pick={(e) => pickScript(e.detail.path, i)}
78
- on:new={(e) => createInlineScriptModule(e.detail.language, i, mode)}
69
+ shouldDisableTriggerScripts={i != 0}
70
+ shouldDisableLoopCreation={indexes.length > 1 || i == 0}
71
+ on:pick={(e) => apply(pickScript, e.detail.path)}
72
+ on:new={(e) =>
73
+ apply(createInlineScriptModule, {
74
+ language: e.detail.language,
75
+ type: e.detail.type
76
+ })}
77
+ on:loop={() => applyCreateLoop()}
79
78
  />
80
79
  {/if}
81
80
  {#if mod.value.type === 'rawscript'}
82
81
  <div class="mb-2 overflow-hidden">
83
82
  <EditorBar {editor} {websocketAlive} lang={mod.value.language ?? 'deno'} />
84
83
  </div>
85
- <div on:mouseleave={() => loadSchema(i)}>
84
+ <div on:mouseleave={() => reload(mod)}>
86
85
  <Editor
87
86
  bind:websocketAlive
88
87
  bind:this={editor}
@@ -90,15 +89,16 @@ const isTrigger = mode === 'pull' && i === 0;
90
89
  bind:code={mod.value.content}
91
90
  deno={mod.value.language === RawScript.language.DENO}
92
91
  automaticLayout={true}
93
- on:blur={() => loadSchema(i)}
94
- formatAction={() => loadSchema(i)}
92
+ formatAction={() => reload(mod)}
95
93
  />
96
94
  <button
97
95
  class="w-full text-center"
98
96
  on:click={() => {
99
97
  bigEditor = !bigEditor
100
- }}><Icon data={bigEditor ? faChevronUp : faChevronDown} scale={1.0} /></button
98
+ }}
101
99
  >
100
+ <Icon data={bigEditor ? faChevronUp : faChevronDown} scale={1.0} />
101
+ </button>
102
102
  </div>
103
103
  <div class="mt-2 mb-8">
104
104
  <p class="text-gray-500 italic">
@@ -110,43 +110,21 @@ const isTrigger = mode === 'pull' && i === 0;
110
110
  {#if !shouldPick}
111
111
  <p class="text-lg font-bold text-gray-900 mb-2">Step inputs</p>
112
112
  <SchemaForm
113
- inputTransform={true}
114
113
  {schema}
115
- {extraLib}
116
- {i}
117
- bind:pickableProperties
114
+ inputTransform={true}
115
+ importPath={String(indexes.join('-'))}
116
+ bind:pickableProperties={stepPropPicker.pickableProperties}
118
117
  bind:args={mod.input_transform}
118
+ bind:extraLib={stepPropPicker.extraLib}
119
119
  />
120
120
  {/if}
121
- </div>
122
121
 
123
- {#if !shouldPick}
124
- <div class="border-b border-gray-200" />
125
- <div class="p-3">
126
- <FlowPreview
127
- bind:args
128
- flow={$flowStore}
129
- {i}
130
- {mode}
131
- schemas={$schemasStore}
132
- on:change={(e) => {
133
- previewResults.set(jobsToResults(e.detail))
134
- }}
135
- />
136
- </div>
137
- {/if}
138
- {/if}
139
- {#if open == i}
140
- <div>
141
- <button class="w-full h-full" on:click={() => (open = -1)}>
142
- <Icon data={faChevronUp} scale={1.0} />
143
- </button>
144
- </div>
145
- {:else}
146
- <div>
147
- <button class="w-full h-full" on:click={() => (open = i)}>
148
- <Icon data={faChevronDown} scale={1.0} />
149
- </button>
122
+ {#if !shouldPick}
123
+ <div class="border-b border-gray-200" />
124
+ <div class="pt-2">
125
+ <FlowPreview bind:args flow={$flowStore} {i} {schema} />
126
+ </div>
127
+ {/if}
150
128
  </div>
151
129
  {/if}
152
130
  </div>
@@ -1,15 +1,18 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import { type FlowModule } from '../gen';
3
- import { type FlowMode } from './flows/flowStore';
3
+ import type { Schema } from '../common';
4
+ import { type FlowModuleSchema } from './flows/flowState';
4
5
  declare const __propDef: {
5
6
  props: {
6
- open: number;
7
- mode: FlowMode;
8
- i: number;
7
+ indexes: number[];
9
8
  mod: FlowModule;
10
9
  args?: Record<string, any> | undefined;
10
+ schema: Schema;
11
+ childFlowModules?: FlowModuleSchema[] | undefined;
11
12
  };
12
13
  events: {
14
+ delete: CustomEvent<any>;
15
+ } & {
13
16
  [evt: string]: CustomEvent<any>;
14
17
  };
15
18
  slots: {};
@@ -4,6 +4,7 @@ import { GroupService } from '../gen';
4
4
  import Tooltip from './Tooltip.svelte';
5
5
  import { userStore, workspaceStore } from '../stores';
6
6
  import { sleep } from '../utils';
7
+ import { createEventDispatcher } from 'svelte';
7
8
  export let meta = {
8
9
  ownerKind: 'user',
9
10
  owner: '',
@@ -14,13 +15,22 @@ export let initialPath;
14
15
  export let path = '';
15
16
  export let error = '';
16
17
  export let kind;
18
+ const dispatch = createEventDispatcher();
17
19
  let groups = [];
18
- $: {
19
- path = [meta.ownerKind === 'group' ? 'g' : 'u', meta.owner, meta.name].join('/');
20
+ $: path = metaToPath(meta);
21
+ function metaToPath(meta) {
22
+ return [meta.ownerKind === 'group' ? 'g' : 'u', meta.owner, meta.name].join('/');
20
23
  }
21
24
  export function getPath() {
22
25
  return path;
23
26
  }
27
+ function handleKeyUp(event) {
28
+ const key = event.key;
29
+ if (key === 'Enter') {
30
+ event.preventDefault();
31
+ dispatch('enter');
32
+ }
33
+ }
24
34
  export async function reset() {
25
35
  if (path == '' || path == 'u//') {
26
36
  meta.ownerKind = 'user';
@@ -28,7 +38,12 @@ export async function reset() {
28
38
  await sleep(500);
29
39
  }
30
40
  meta.owner = $userStore.username;
31
- meta.name = '';
41
+ meta.name = namePlaceholder;
42
+ let i = 1;
43
+ while (await pathExists(metaToPath(meta), kind)) {
44
+ meta.name = `${namePlaceholder}_${i}`;
45
+ i += 1;
46
+ }
32
47
  }
33
48
  else {
34
49
  meta = pathToMeta(path);
@@ -40,55 +55,60 @@ async function loadGroups() {
40
55
  meta.owner = meta.owner;
41
56
  }
42
57
  async function validate(meta, path, kind) {
43
- validateName(meta) && (await validatePath(path, kind));
58
+ error = '';
59
+ validateName(meta) && validatePath(path, kind);
44
60
  }
45
61
  let validateTimeout = undefined;
46
62
  async function validatePath(path, kind) {
47
- if (initialPath != '' && initialPath != path) {
48
- if (validateTimeout) {
49
- clearTimeout(validateTimeout);
63
+ if (validateTimeout) {
64
+ clearTimeout(validateTimeout);
65
+ }
66
+ validateTimeout = setTimeout(async () => {
67
+ if ((path == '' || path != initialPath) && (await pathExists(path, kind))) {
68
+ error = 'path already used';
69
+ }
70
+ else if (validateName(meta)) {
71
+ error = '';
50
72
  }
51
- validateTimeout = setTimeout(async () => {
52
- if (initialPath != '' &&
53
- initialPath != path &&
54
- ((kind == 'flow' &&
55
- (await FlowService.existsFlowByPath({ workspace: $workspaceStore, path: path }))) ||
56
- (kind == 'script' &&
57
- (await ScriptService.existsScriptByPath({
58
- workspace: $workspaceStore,
59
- path: path
60
- }))) ||
61
- (kind == 'resource' &&
62
- (await ResourceService.existsResource({
63
- workspace: $workspaceStore,
64
- path: path
65
- }))) ||
66
- (kind == 'variable' &&
67
- (await VariableService.existsVariable({
68
- workspace: $workspaceStore,
69
- path: path
70
- }))) ||
71
- (kind == 'schedule' &&
72
- (await ScheduleService.existsSchedule({ workspace: $workspaceStore, path: path }))))) {
73
- error = 'path already used';
74
- }
75
- else if (validateName(meta)) {
76
- error = '';
77
- }
78
- validateTimeout = undefined;
79
- }, 500);
73
+ validateTimeout = undefined;
74
+ }, 500);
75
+ }
76
+ async function pathExists(path, kind) {
77
+ if (kind == 'flow') {
78
+ return await FlowService.existsFlowByPath({ workspace: $workspaceStore, path: path });
79
+ }
80
+ else if (kind == 'script') {
81
+ return await ScriptService.existsScriptByPath({
82
+ workspace: $workspaceStore,
83
+ path: path
84
+ });
85
+ }
86
+ else if (kind == 'resource') {
87
+ return await ResourceService.existsResource({
88
+ workspace: $workspaceStore,
89
+ path: path
90
+ });
91
+ }
92
+ else if (kind == 'variable') {
93
+ return await VariableService.existsVariable({
94
+ workspace: $workspaceStore,
95
+ path: path
96
+ });
97
+ }
98
+ else if (kind == 'schedule') {
99
+ return await ScheduleService.existsSchedule({ workspace: $workspaceStore, path: path });
80
100
  }
81
101
  else {
82
- error = '';
102
+ return false;
83
103
  }
84
104
  }
85
105
  function validateName(meta) {
86
106
  if (meta.name == undefined || meta.name == '') {
87
- error = 'choose a name';
107
+ error = 'Choose a name';
88
108
  return false;
89
109
  }
90
110
  else if (!/^[\w-]+(\/[\w-]+)*$/.test(meta.name)) {
91
- error = 'This name is not valid.';
111
+ error = 'This name is not valid';
92
112
  return false;
93
113
  }
94
114
  else {
@@ -156,6 +176,8 @@ $: {
156
176
  <span class="text-gray-700 text-sm">Name<span class="text-red-600 text-sm">*</span></span>
157
177
  <input
158
178
  autofocus
179
+ autocomplete="off"
180
+ on:keyup={handleKeyUp}
159
181
  bind:value={meta.name}
160
182
  placeholder={namePlaceholder}
161
183
  class={error === ''
@@ -165,7 +187,7 @@ $: {
165
187
  </label>
166
188
  </div>
167
189
  <div class="pt-0 text-xs px-1 flex flex-col-reverse sm:grid sm:grid-cols-4 sm:gap-4 w-full">
168
- <div class="col-span-2">Path: <span class="font-mono">{path}</span></div>
190
+ <div class="col-span-2"><span class="font-mono">{path}</span></div>
169
191
  <div class="text-purple-500 text-2xs col-span-2">{error}</div>
170
192
  </div>
171
193
  </div>
@@ -12,6 +12,8 @@ declare const __propDef: {
12
12
  reset?: (() => Promise<void>) | undefined;
13
13
  };
14
14
  events: {
15
+ enter: CustomEvent<any>;
16
+ } & {
15
17
  [evt: string]: CustomEvent<any>;
16
18
  };
17
19
  slots: {
@@ -0,0 +1,31 @@
1
+ <script>import ProgressBarPart from './ProgressBarPart.svelte';
2
+ export let i = -1;
3
+ export let steps = 0;
4
+ $: series = Array.from(Array(steps).keys()).map((x) => Math.floor(((100 / steps) * x) / 100));
5
+ function toggle() {
6
+ toggled[i] = true;
7
+ }
8
+ $: toggled = series.map(() => false);
9
+ $: text = i < series.length ? `Step ${i + 1}` : 'Done';
10
+ $: toggled[i] === false && toggle();
11
+ </script>
12
+
13
+ <div>
14
+ <div class="flex justify-between mb-1">
15
+ <span class="text-base font-medium text-blue-700 dark:text-white">{text}</span>
16
+ <span class="text-sm font-medium text-blue-700 dark:text-white">
17
+ {series.slice(0, i).reduce((x, y) => y + x, 0)}%
18
+ </span>
19
+ </div>
20
+ <div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700 relative">
21
+ {#each series as serie, index}
22
+ <ProgressBarPart
23
+ isFirst={index === 0}
24
+ isLast={index === series.length - 1}
25
+ sumUpTo={series.slice(0, index).reduce((x, y) => y + x, 0)}
26
+ length={serie}
27
+ shouldToggle={toggled[index]}
28
+ />
29
+ {/each}
30
+ </div>
31
+ </div>
@@ -0,0 +1,17 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ i?: number | undefined;
5
+ steps?: number | undefined;
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ };
12
+ export declare type ProgressBarProps = typeof __propDef.props;
13
+ export declare type ProgressBarEvents = typeof __propDef.events;
14
+ export declare type ProgressBarSlots = typeof __propDef.slots;
15
+ export default class ProgressBar extends SvelteComponentTyped<ProgressBarProps, ProgressBarEvents, ProgressBarSlots> {
16
+ }
17
+ export {};
@@ -0,0 +1,20 @@
1
+ <script>import { tweened } from 'svelte/motion';
2
+ import { cubicOut } from 'svelte/easing';
3
+ const progress = tweened(0, {
4
+ duration: 400,
5
+ easing: cubicOut
6
+ });
7
+ export let isFirst;
8
+ export let isLast;
9
+ export let sumUpTo;
10
+ export let length;
11
+ export let shouldToggle;
12
+ $: shouldToggle && progress.set(length);
13
+ </script>
14
+
15
+ <div
16
+ class={`bg-blue-200 h-2.5 absolute ${isFirst ? 'rounded-l-full' : ''} ${
17
+ isLast ? 'rounded-r-full' : ''
18
+ }`}
19
+ style={`${isFirst ? 'left:0%;' : `left:${sumUpTo}%;`} width: ${$progress}%`}
20
+ />
@@ -0,0 +1,20 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ isFirst: boolean;
5
+ isLast: boolean;
6
+ sumUpTo: number;
7
+ length: number;
8
+ shouldToggle: boolean;
9
+ };
10
+ events: {
11
+ [evt: string]: CustomEvent<any>;
12
+ };
13
+ slots: {};
14
+ };
15
+ export declare type ProgressBarPartProps = typeof __propDef.props;
16
+ export declare type ProgressBarPartEvents = typeof __propDef.events;
17
+ export declare type ProgressBarPartSlots = typeof __propDef.slots;
18
+ export default class ProgressBarPart extends SvelteComponentTyped<ProgressBarPartProps, ProgressBarPartEvents, ProgressBarPartSlots> {
19
+ }
20
+ export {};
@@ -114,7 +114,7 @@ $: isValid = allTrue(inputCheck) ?? false;
114
114
  bind:error={pathError}
115
115
  bind:path
116
116
  {initialPath}
117
- namePlaceholder="my/resource"
117
+ namePlaceholder="my_resource"
118
118
  kind="resource"
119
119
  >
120
120
  <div slot="ownerToolkit">
@@ -164,6 +164,7 @@ $: isValid = allTrue(inputCheck) ?? false;
164
164
  enum_={resourceSchema.properties[fieldName]?.enum}
165
165
  contentEncoding={resourceSchema.properties[fieldName]?.contentEncoding}
166
166
  itemsType={resourceSchema.properties[fieldName]?.items}
167
+ properties={resourceSchema.properties[fieldName]?.properties}
167
168
  format={resourceSchema.properties[fieldName]?.format}
168
169
  />
169
170
  <div class="pb-3 ml-2 relative">
@@ -32,6 +32,15 @@ $: dispatch('change', value);
32
32
  <a class="text-xs hover:underline" target="_blank" href="/resources?connect_app={resourceType}"
33
33
  >Connect the app {resourceType} to an account (if available)</a
34
34
  >
35
+ <button
36
+ class="text-xs text-blue-500"
37
+ type="button"
38
+ on:click={() => {
39
+ loadResources(resourceType)
40
+ }}
41
+ >
42
+ refresh
43
+ </button>
35
44
  <button
36
45
  class="text-xs text-blue-500"
37
46
  type="button"
@@ -8,17 +8,21 @@ export let editableSchema = false;
8
8
  export let isValid = true;
9
9
  export let pickableProperties = undefined;
10
10
  export let extraLib = 'missing extraLib';
11
- export let i = undefined;
11
+ export let importPath = undefined;
12
12
  let inputCheck = {};
13
13
  $: isValid = allTrue(inputCheck) ?? false;
14
+ $: if (args == undefined) {
15
+ args = {};
16
+ }
14
17
  function removeExtraKey() {
15
- Object.keys(args).forEach((key) => {
18
+ Object.keys(args ?? {}).forEach((key) => {
16
19
  if (!Object.keys(schema?.properties ?? {}).includes(key)) {
17
20
  delete args[key];
21
+ delete inputCheck[key];
18
22
  }
19
23
  });
20
24
  }
21
- $: Object.keys(schema?.properties ?? {}).length > 0 && removeExtraKey();
25
+ $: schema?.properties && removeExtraKey();
22
26
  </script>
23
27
 
24
28
  <div class="w-full">
@@ -32,7 +36,7 @@ $: Object.keys(schema?.properties ?? {}).length > 0 && removeExtraKey();
32
36
  bind:inputCheck
33
37
  bind:pickableProperties
34
38
  bind:extraLib
35
- bind:i
39
+ bind:importPath
36
40
  />
37
41
  {:else}
38
42
  <ArgInput
@@ -47,6 +51,7 @@ $: Object.keys(schema?.properties ?? {}).length > 0 && removeExtraKey();
47
51
  bind:enum_={schema.properties[argName].enum}
48
52
  bind:format={schema.properties[argName].format}
49
53
  contentEncoding={schema.properties[argName].contentEncoding}
54
+ properties={schema.properties[argName].properties}
50
55
  bind:itemsType={schema.properties[argName].items}
51
56
  {editableSchema}
52
57
  />
@@ -9,7 +9,7 @@ declare const __propDef: {
9
9
  isValid?: boolean | undefined;
10
10
  pickableProperties?: Object | undefined;
11
11
  extraLib?: string | undefined;
12
- i?: number | undefined;
12
+ importPath?: string | undefined;
13
13
  };
14
14
  events: {
15
15
  [evt: string]: CustomEvent<any>;
@@ -55,17 +55,33 @@ function clearModal() {
55
55
  $: if (property.selectedType == 'object' && resource_type) {
56
56
  property.format = resource_type ? `$res:${resource_type}` : undefined;
57
57
  }
58
+ $: if (property.name == '') {
59
+ error = 'Name is required';
60
+ }
61
+ else {
62
+ error = '';
63
+ }
58
64
  </script>
59
65
 
60
66
  <Modal bind:this={modal} on:close={clearModal}>
61
67
  <div slot="title">Add an argument</div>
62
68
  <div slot="content">
63
69
  <div class="flex flex-col px-6 py-3 bg-gray-50">
64
- <div class="text-purple-500 text-2xs grow">{error}</div>
65
- <label class="mb-2 font-semibold text-gray-700"
70
+ <label class="font-semibold text-gray-700"
66
71
  >Name<Required required={true} />
67
- <input type="text" placeholder="Argument name" class="" bind:value={property.name} />
72
+ <input
73
+ autofocus
74
+ autocomplete="off"
75
+ type="text"
76
+ placeholder="name"
77
+ bind:value={property.name}
78
+ class={error === ''
79
+ ? ''
80
+ : 'border border-red-700 bg-red-100 border-opacity-30 focus:border-red-700 focus:border-opacity-30 focus-visible:ring-red-700 focus-visible:ring-opacity-25 focus-visible:border-red-700'}
81
+ />
68
82
  </label>
83
+ <div class="mb-2 text-purple-500 text-2xs">{error}</div>
84
+
69
85
  <label class="mb-2 font-semibold text-gray-700">
70
86
  Description
71
87
  <textarea
@@ -136,6 +152,7 @@ $: if (property.selectedType == 'object' && resource_type) {
136
152
  </div>
137
153
 
138
154
  <button
155
+ disabled={!property.name || !property.selectedType || error != ''}
139
156
  slot="submission"
140
157
  class="px-4 py-2 text-white font-semibold bg-blue-500 rounded"
141
158
  on:click={() => {