windmill-components 1.28.3 → 1.28.6
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.
- package/components/ArgInput.svelte +27 -16
- package/components/Editor.svelte +21 -17
- package/components/FlowBuilder.svelte +2 -2
- package/components/FlowPreview.svelte +12 -8
- package/components/FlowPreviewContent.svelte +6 -6
- package/components/FlowStatusViewer.svelte +3 -0
- package/components/FlowViewer.svelte +14 -11
- package/components/InputTransformForm.svelte +2 -2
- package/components/InputTransformsViewer.svelte +1 -1
- package/components/ModuleStep.svelte +1 -1
- package/components/ObjectResourceInput.svelte +2 -2
- package/components/RadioButton.svelte +4 -2
- package/components/SchemaEditor.svelte +7 -3
- package/components/SchemaEditorProperty.svelte +9 -7
- package/components/SchemaViewer.svelte +5 -1
- package/components/ScriptEditor.svelte +7 -1
- package/components/flows/DynamicInputHelpBox.svelte +15 -10
- package/components/flows/DynamicInputHelpBox.svelte.d.ts +3 -1
- package/components/flows/FlowSettings.svelte +2 -1
- package/components/flows/utils.js +2 -6
- package/gen/core/OpenAPI.js +1 -1
- package/gen/models/FlowModule.d.ts +1 -0
- package/logout.d.ts +1 -1
- package/logout.js +11 -9
- package/package.json +1 -1
|
@@ -50,14 +50,16 @@ $: {
|
|
|
50
50
|
evalValueToRaw();
|
|
51
51
|
validateInput(pattern, value);
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
}
|
|
54
|
+
$: {
|
|
55
|
+
defaultValue && recomputeRowSize(JSON.stringify(defaultValue, null, 4));
|
|
56
|
+
}
|
|
57
|
+
function recomputeRowSize(str) {
|
|
58
|
+
if (str.length > 50) {
|
|
59
|
+
minRows = 3;
|
|
60
|
+
}
|
|
61
|
+
if (type != 'string') {
|
|
62
|
+
minRows = Math.max(minRows, Math.min(str.split(/\r\n|\r|\n/).length + 1, maxRows));
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
export function evalValueToRaw() {
|
|
@@ -112,7 +114,7 @@ export let inputCat = 'string';
|
|
|
112
114
|
$: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncoding);
|
|
113
115
|
</script>
|
|
114
116
|
|
|
115
|
-
<div class="flex flex-col w-full">
|
|
117
|
+
<div class="flex flex-col w-full mb-2">
|
|
116
118
|
<div>
|
|
117
119
|
{#if displayHeader}
|
|
118
120
|
<FieldHeader {label} {required} {type} {contentEncoding} {format} {itemsType} />
|
|
@@ -156,13 +158,18 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
|
|
|
156
158
|
{/if}
|
|
157
159
|
|
|
158
160
|
<div class="grid grid-cols-2">
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
{error === '' ? '
|
|
164
|
-
|
|
161
|
+
{#if description || error}
|
|
162
|
+
<div class="text-sm italic pb-1">
|
|
163
|
+
{description}
|
|
164
|
+
</div>
|
|
165
|
+
<div class="text-right text-xs {error === '' ? 'text-white' : 'font-bold text-red-600'}">
|
|
166
|
+
{error === '' ? '...' : error}
|
|
167
|
+
</div>
|
|
168
|
+
{:else}
|
|
169
|
+
<div class="mt-1" />
|
|
170
|
+
{/if}
|
|
165
171
|
</div>
|
|
172
|
+
|
|
166
173
|
<div class="flex space-x-1">
|
|
167
174
|
{#if inputCat == 'number'}
|
|
168
175
|
<input
|
|
@@ -240,6 +247,7 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
|
|
|
240
247
|
<textarea
|
|
241
248
|
{disabled}
|
|
242
249
|
style="min-height: {minHeight}; max-height: {maxHeight}"
|
|
250
|
+
on:input={async () => recomputeRowSize(rawValue ?? '')}
|
|
243
251
|
class="col-span-10 {valid
|
|
244
252
|
? ''
|
|
245
253
|
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}"
|
|
@@ -290,7 +298,10 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
|
|
|
290
298
|
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}"
|
|
291
299
|
placeholder={defaultValue ?? ''}
|
|
292
300
|
bind:value
|
|
293
|
-
on:input={() =>
|
|
301
|
+
on:input={async () => {
|
|
302
|
+
recomputeRowSize(value)
|
|
303
|
+
dispatch('input', { rawValue: value, isRaw: false })
|
|
304
|
+
}}
|
|
294
305
|
/>
|
|
295
306
|
{/if}
|
|
296
307
|
{#if !required && inputCat != 'resource-object'}
|
package/components/Editor.svelte
CHANGED
|
@@ -179,13 +179,32 @@ export async function reloadWebsocket() {
|
|
|
179
179
|
async function connectToLanguageServer(url, name, options) {
|
|
180
180
|
try {
|
|
181
181
|
const webSocket = new WebSocket(url);
|
|
182
|
-
webSocket.onopen = () => {
|
|
182
|
+
webSocket.onopen = async () => {
|
|
183
183
|
const socket = toSocket(webSocket);
|
|
184
184
|
const reader = new WebSocketMessageReader(socket);
|
|
185
185
|
const writer = new WebSocketMessageWriter(socket);
|
|
186
186
|
const languageClient = createLanguageClient({ reader, writer }, name, options);
|
|
187
187
|
websockets.push([languageClient, webSocket]);
|
|
188
|
-
|
|
188
|
+
reader.onClose(async () => {
|
|
189
|
+
try {
|
|
190
|
+
console.log('CLOSE');
|
|
191
|
+
websocketAlive[name] = false;
|
|
192
|
+
await languageClient.stop();
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
console.error(err);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
socket.onClose((_code, _reason) => {
|
|
199
|
+
websocketAlive[name] = false;
|
|
200
|
+
});
|
|
201
|
+
try {
|
|
202
|
+
await languageClient.start();
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
console.error(err);
|
|
206
|
+
throw new Error(err);
|
|
207
|
+
}
|
|
189
208
|
lastWsAttempt = new Date();
|
|
190
209
|
nbWsAttempt = 0;
|
|
191
210
|
if (name == 'deno') {
|
|
@@ -200,18 +219,6 @@ export async function reloadWebsocket() {
|
|
|
200
219
|
}
|
|
201
220
|
});
|
|
202
221
|
}
|
|
203
|
-
reader.onClose(() => {
|
|
204
|
-
try {
|
|
205
|
-
console.log('CLOSE');
|
|
206
|
-
languageClient.stop();
|
|
207
|
-
}
|
|
208
|
-
catch (err) {
|
|
209
|
-
console.error(err);
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
socket.onClose((_code, _reason) => {
|
|
213
|
-
websocketAlive[name] = false;
|
|
214
|
-
});
|
|
215
222
|
websocketAlive[name] = true;
|
|
216
223
|
};
|
|
217
224
|
}
|
|
@@ -329,9 +336,6 @@ async function loadMonaco() {
|
|
|
329
336
|
minimap: {
|
|
330
337
|
enabled: false
|
|
331
338
|
},
|
|
332
|
-
scrollbar: {
|
|
333
|
-
alwaysConsumeMouseWheel: false
|
|
334
|
-
},
|
|
335
339
|
lightbulb: {
|
|
336
340
|
enabled: true
|
|
337
341
|
}
|
|
@@ -123,7 +123,7 @@ onDestroy(() => {
|
|
|
123
123
|
</script>
|
|
124
124
|
|
|
125
125
|
<div class="flex flex-row w-full h-full justify-between">
|
|
126
|
-
<div class={`flex flex-col mb-96 m-auto w-1/2`}>
|
|
126
|
+
<div class={`flex flex-col mb-96 m-auto w-full sm:w-3/4 lg:w-2/3 xl:w-1/2`}>
|
|
127
127
|
<!-- Nav between steps-->
|
|
128
128
|
<div class="justify-between flex flex-row w-full my-4">
|
|
129
129
|
<Breadcrumb>
|
|
@@ -205,7 +205,7 @@ onDestroy(() => {
|
|
|
205
205
|
<div class={`relative h-screen w-1/3 ${previewOpen ? '' : 'hidden'}`}>
|
|
206
206
|
<div class="absolute top-0 h-full">
|
|
207
207
|
{#if $flowStore && step === 1}
|
|
208
|
-
<div class="fixed border-l-2 right-0 h-screen w-1/3">
|
|
208
|
+
<div class="fixed border-l-2 right-0 h-screen w-1/2 sm:w-1/3">
|
|
209
209
|
<FlowPreviewContent
|
|
210
210
|
bind:args={scheduleArgs}
|
|
211
211
|
on:close={() => (previewOpen = !previewOpen)}
|
|
@@ -27,8 +27,7 @@ $: dispatch('change', jobs);
|
|
|
27
27
|
export async function runPreview(args) {
|
|
28
28
|
viewPreview = true;
|
|
29
29
|
intervalId && clearInterval(intervalId);
|
|
30
|
-
let newFlow =
|
|
31
|
-
newFlow = tab == 'upto' ? truncateFlow(newFlow) : extractStep(newFlow);
|
|
30
|
+
let newFlow = tab == 'upto' ? truncateFlow(flow) : setInputTransformFromArgs(extractStep(flow), args);
|
|
32
31
|
jobId = await runFlowPreview(args, newFlow);
|
|
33
32
|
jobs = [];
|
|
34
33
|
intervalId = setInterval(loadJob, 1000);
|
|
@@ -43,14 +42,19 @@ function extractStep(flow) {
|
|
|
43
42
|
const localFlow = JSON.parse(JSON.stringify(flow));
|
|
44
43
|
localFlow.value.modules = flow.value.modules.slice(i, i + 1);
|
|
45
44
|
localFlow.schema = schemas[i];
|
|
46
|
-
stepArgs = {};
|
|
47
|
-
Object.entries(flow.value.modules[i].input_transform).forEach((x) => {
|
|
48
|
-
if (x[1].type == 'static') {
|
|
49
|
-
stepArgs[x[0]] = x[1].value;
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
45
|
return localFlow;
|
|
53
46
|
}
|
|
47
|
+
function setInputTransformFromArgs(flow, args) {
|
|
48
|
+
let input_transform = {};
|
|
49
|
+
Object.entries(args).forEach(([key, value]) => {
|
|
50
|
+
input_transform[key] = {
|
|
51
|
+
type: 'static',
|
|
52
|
+
value: value
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
flow.value.modules[0].input_transform = input_transform;
|
|
56
|
+
return flow;
|
|
57
|
+
}
|
|
54
58
|
async function loadJob() {
|
|
55
59
|
try {
|
|
56
60
|
job = await JobService.getJob({ workspace: $workspaceStore, id: jobId });
|
|
@@ -41,8 +41,8 @@ onDestroy(() => {
|
|
|
41
41
|
});
|
|
42
42
|
</script>
|
|
43
43
|
|
|
44
|
-
<div class="flex flex-col space-y-4 h-screen bg-white
|
|
45
|
-
<div class="flex flex-col space-y-4 p-6 border-b-2">
|
|
44
|
+
<div class="flex flex-col space-y-4 h-screen bg-white">
|
|
45
|
+
<div class="flex flex-col space-y-4 p-6 border-b-2 overflow-y-auto grow">
|
|
46
46
|
<div class="flex justify-between">
|
|
47
47
|
<h3 class="text-lg leading-6 font-bold text-gray-900">Flow Preview</h3>
|
|
48
48
|
|
|
@@ -51,11 +51,11 @@ onDestroy(() => {
|
|
|
51
51
|
</Button>
|
|
52
52
|
</div>
|
|
53
53
|
<SchemaForm schema={$flowStore.schema} bind:isValid bind:args />
|
|
54
|
-
<Button disabled={!isValid} class="blue-button" on:click={() => runPreview(args)} size="md">
|
|
55
|
-
Preview
|
|
56
|
-
</Button>
|
|
57
54
|
</div>
|
|
58
|
-
<
|
|
55
|
+
<Button disabled={!isValid} class="blue-button mx-4" on:click={() => runPreview(args)} size="md">
|
|
56
|
+
Preview
|
|
57
|
+
</Button>
|
|
58
|
+
<div class="h-full overflow-y-auto mb-16 grow">
|
|
59
59
|
{#if job}
|
|
60
60
|
<div class="w-full">
|
|
61
61
|
<FlowStatusViewer {job} bind:jobs />
|
|
@@ -94,6 +94,7 @@ function toAny(x) {
|
|
|
94
94
|
</div>
|
|
95
95
|
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4 w-full">
|
|
96
96
|
<div class="w-full">
|
|
97
|
+
<span class="text-black">{mod?.summary ?? ''}</span>
|
|
97
98
|
<p class="text-sm text-gray-500">
|
|
98
99
|
{#if mod?.value?.type == 'script'}
|
|
99
100
|
Script at path <a
|
|
@@ -112,17 +113,19 @@ function toAny(x) {
|
|
|
112
113
|
View code and inputs {open[i] ? '(-)' : '(+)'}</button
|
|
113
114
|
>
|
|
114
115
|
{#if open[i]}
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
116
|
+
<div class="border border-black p-2 bg-gray-50 divide-y">
|
|
117
|
+
<InputTransformsViewer inputTransforms={mod?.input_transform} />
|
|
118
|
+
<div class="w-full h-full mt-6">
|
|
119
|
+
<iframe
|
|
120
|
+
style="height: 400px;"
|
|
121
|
+
class="w-full h-full text-sm"
|
|
122
|
+
title="embedded script from hub"
|
|
123
|
+
frameborder="0"
|
|
124
|
+
src="https://hub.windmill.dev/embed/script/{mod?.value?.path?.substring(
|
|
125
|
+
4
|
|
126
|
+
)}"
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
126
129
|
</div>
|
|
127
130
|
{/if}
|
|
128
131
|
</div>
|
|
@@ -78,7 +78,7 @@ $: checked = propertyType == 'javascript';
|
|
|
78
78
|
</script>
|
|
79
79
|
|
|
80
80
|
{#if arg != undefined}
|
|
81
|
-
<div class="flex justify-between items-center">
|
|
81
|
+
<div class="flex justify-between items-center mb-2">
|
|
82
82
|
<div class="flex items-center">
|
|
83
83
|
<FieldHeader
|
|
84
84
|
label={argName}
|
|
@@ -199,7 +199,7 @@ $: checked = propertyType == 'javascript';
|
|
|
199
199
|
/>
|
|
200
200
|
</div>
|
|
201
201
|
</OverlayPropertyPicker>
|
|
202
|
-
<DynamicInputHelpBox />
|
|
202
|
+
<DynamicInputHelpBox {i} />
|
|
203
203
|
{/if}
|
|
204
204
|
{:else}
|
|
205
205
|
<p>Not recognized arg type {arg.type}</p>
|
|
@@ -10,7 +10,7 @@ export let inputTransforms;
|
|
|
10
10
|
<span class="font-black text-gray-700">{key}</span>: {#if val.type == 'static'}<ObjectViewer
|
|
11
11
|
json={val.value}
|
|
12
12
|
/>{:else}
|
|
13
|
-
<span class="inline-
|
|
13
|
+
<span class="inline-highlight">
|
|
14
14
|
<Highlight offsetTop={0} language={typescript} code={val.expr} />
|
|
15
15
|
</span>
|
|
16
16
|
{/if}
|
|
@@ -82,7 +82,7 @@ const isTrigger = mode === 'pull' && i === 0;
|
|
|
82
82
|
<div class="mb-2 overflow-hidden">
|
|
83
83
|
<EditorBar {editor} {websocketAlive} lang={mod.value.language ?? 'deno'} />
|
|
84
84
|
</div>
|
|
85
|
-
<div>
|
|
85
|
+
<div on:mouseleave={() => loadSchema(i)}>
|
|
86
86
|
<Editor
|
|
87
87
|
bind:websocketAlive
|
|
88
88
|
bind:this={editor}
|
|
@@ -42,8 +42,8 @@ function valueToPath() {
|
|
|
42
42
|
$: value && valueToPath();
|
|
43
43
|
</script>
|
|
44
44
|
|
|
45
|
-
<div class="flex flex-row w-full gap-2">
|
|
46
|
-
<div class="shrink
|
|
45
|
+
<div class="flex flex-row w-full flex-wrap gap-x-2">
|
|
46
|
+
<div class="shrink">
|
|
47
47
|
<RadioButton
|
|
48
48
|
options={[
|
|
49
49
|
[`Resource (${resourceTypeName})`, 'resource'],
|
|
@@ -12,7 +12,7 @@ const dispatch = createEventDispatcher();
|
|
|
12
12
|
{#each options as [label, val]}
|
|
13
13
|
<label
|
|
14
14
|
class:item-button-selected={val == value}
|
|
15
|
-
class="item-button text-center text-sm h-full p-2 grow"
|
|
15
|
+
class="item-button text-center text-sm h-full p-2 grow whitespace-nowrap"
|
|
16
16
|
>
|
|
17
17
|
<input
|
|
18
18
|
type="radio"
|
|
@@ -23,7 +23,9 @@ const dispatch = createEventDispatcher();
|
|
|
23
23
|
on:click={() => dispatch('change', val)}
|
|
24
24
|
/>
|
|
25
25
|
<p>
|
|
26
|
-
{#if typeof label !== 'string'}
|
|
26
|
+
{#if typeof label !== 'string'}
|
|
27
|
+
{label.title}
|
|
28
|
+
<Tooltip>{label.desc}</Tooltip>
|
|
27
29
|
{:else}{label}{/if}
|
|
28
30
|
</p>
|
|
29
31
|
</label>
|
|
@@ -126,7 +126,7 @@ function switchTab() {
|
|
|
126
126
|
</script>
|
|
127
127
|
|
|
128
128
|
<div class="flex flex-col">
|
|
129
|
-
<div class="flex justify-between">
|
|
129
|
+
<div class="flex justify-between gap-x-2">
|
|
130
130
|
<Button
|
|
131
131
|
on:click={() => {
|
|
132
132
|
modalProperty = Object.assign({}, DEFAULT_PROPERTY)
|
|
@@ -176,8 +176,12 @@ function switchTab() {
|
|
|
176
176
|
<SchemaEditorProperty {property} />
|
|
177
177
|
</td>
|
|
178
178
|
<td>{property.description}</td>
|
|
179
|
-
<td>{JSON.stringify(property.default)
|
|
180
|
-
<td
|
|
179
|
+
<td>{property.default ? JSON.stringify(property.default) : ''}</td>
|
|
180
|
+
<td
|
|
181
|
+
>{#if schema.required.includes(name)}
|
|
182
|
+
<span class="text-red-600 font-bold text-lg">*</span>
|
|
183
|
+
{/if}</td
|
|
184
|
+
>
|
|
181
185
|
<td class="justify-end flex">
|
|
182
186
|
<Button
|
|
183
187
|
color="red"
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
export let property;
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
|
-
<
|
|
6
|
-
{
|
|
7
|
-
|
|
8
|
-
{
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
{
|
|
5
|
+
<div class="flex flex-row flex-wrap gap-1">
|
|
6
|
+
<Badge color="blue">{property.type?.toUpperCase() ?? 'ANY'}</Badge>
|
|
7
|
+
{#if property.format}
|
|
8
|
+
<Badge color="green">{property.format?.toUpperCase()}</Badge>
|
|
9
|
+
{/if}
|
|
10
|
+
{#if property.contentEncoding}
|
|
11
|
+
<Badge color="indigo">{property.contentEncoding?.toUpperCase()}</Badge>
|
|
12
|
+
{/if}
|
|
13
|
+
</div>
|
|
@@ -58,7 +58,11 @@ let viewJsonSchema = false;
|
|
|
58
58
|
>{property.format ?? ''}
|
|
59
59
|
{property.contentEncoding ? `(encoding: ${property.contentEncoding})` : ''}</td
|
|
60
60
|
>
|
|
61
|
-
<td
|
|
61
|
+
<td
|
|
62
|
+
>{#if schema.required.includes(name)}
|
|
63
|
+
<span class="text-red-600 font-bold text-lg">*</span>
|
|
64
|
+
{/if}</td
|
|
65
|
+
>
|
|
62
66
|
</tr>
|
|
63
67
|
{/each}
|
|
64
68
|
</tbody>
|
|
@@ -206,7 +206,13 @@ onDestroy(() => {
|
|
|
206
206
|
<div class="header">
|
|
207
207
|
<EditorBar {editor} {lang} {websocketAlive} />
|
|
208
208
|
</div>
|
|
209
|
-
<div
|
|
209
|
+
<div
|
|
210
|
+
class="flex-1 overflow-hidden border p-2 rounded"
|
|
211
|
+
on:mouseleave={() => {
|
|
212
|
+
code = getEditor().getCode()
|
|
213
|
+
inferSchema()
|
|
214
|
+
}}
|
|
215
|
+
>
|
|
210
216
|
<Editor
|
|
211
217
|
{code}
|
|
212
218
|
bind:websocketAlive
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script>import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
|
|
2
2
|
import Icon from 'svelte-awesome';
|
|
3
3
|
import { slide } from 'svelte/transition';
|
|
4
|
+
export let i = 1;
|
|
4
5
|
$: opened = false;
|
|
5
6
|
</script>
|
|
6
7
|
|
|
@@ -25,29 +26,29 @@ $: opened = false;
|
|
|
25
26
|
>
|
|
26
27
|
<p class="font-bold">Dynamic arg help</p>
|
|
27
28
|
<p>
|
|
28
|
-
When a field is "
|
|
29
|
-
corresponding
|
|
29
|
+
When a field is using the "Raw Javascript Editor", its value is computed dynamically as the
|
|
30
|
+
evaluation of its corresponding javascript snippet.
|
|
30
31
|
</p>
|
|
31
|
-
That snippet can be single line:
|
|
32
|
+
That snippet can be a single line:
|
|
32
33
|
<pre><code>last_result.myarg</code></pre>
|
|
33
|
-
or multiline:
|
|
34
|
+
or a multiline:
|
|
34
35
|
<pre><code
|
|
35
36
|
>let x = 5;
|
|
36
37
|
x + 2</code
|
|
37
38
|
></pre>
|
|
38
39
|
<p>
|
|
39
|
-
If it is multiline, the
|
|
40
|
+
If it is multiline, the statement before the final expression <b
|
|
40
41
|
>MUST END WITH ; and a newline</b
|
|
41
42
|
>
|
|
42
43
|
</p>
|
|
43
44
|
The snippet can also be a string template:
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
<code
|
|
46
|
+
>`Hello ${params.name}, all your base ${previous_result.base_name} belong
|
|
47
|
+
to us`</code
|
|
48
|
+
>
|
|
48
49
|
However, the last line must always be the final expression.
|
|
49
50
|
<p>
|
|
50
|
-
The snippet can use any
|
|
51
|
+
The snippet can use any javascript primitives, and the following flow specific objects and
|
|
51
52
|
functions:
|
|
52
53
|
</p>
|
|
53
54
|
<ul class="ml-4">
|
|
@@ -68,5 +69,9 @@ belong to us`</code
|
|
|
68
69
|
<b>resource(path)</b>: the function returning the resource at a given path as an object
|
|
69
70
|
</li>
|
|
70
71
|
</ul>
|
|
72
|
+
<p>To re-enable editor assistance, import the helper functions types using:</p>
|
|
73
|
+
<code
|
|
74
|
+
>{`import { previous_result, flow_input, step, variable, resource, params } from 'windmill@${i}'`}</code
|
|
75
|
+
>
|
|
71
76
|
</div>
|
|
72
77
|
{/if}
|
|
@@ -161,12 +161,13 @@ let jsonValue = '';
|
|
|
161
161
|
right: 'enabled'
|
|
162
162
|
}}
|
|
163
163
|
/>
|
|
164
|
-
<div class="p-2
|
|
164
|
+
<div class="p-2 my-2 rounded" class:bg-gray-300={!scheduleEnabled}>
|
|
165
165
|
{#if !scheduleEnabled}
|
|
166
166
|
<span class="font-black">No next scheduled run when disabled</span>
|
|
167
167
|
{/if}
|
|
168
168
|
<CronInput bind:schedule={scheduleCron} />
|
|
169
169
|
</div>
|
|
170
|
+
|
|
170
171
|
<SchemaForm schema={$flowStore.schema} bind:args={scheduleArgs} />
|
|
171
172
|
</CollapseLink>
|
|
172
173
|
{/if}
|
|
@@ -123,18 +123,14 @@ export async function loadSchemaFromModule(module) {
|
|
|
123
123
|
schema: emptySchema()
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
|
+
const returnStatementRegex = new RegExp(/\$\{(.*)\}/);
|
|
126
127
|
export function isCodeInjection(expr) {
|
|
127
128
|
if (!expr) {
|
|
128
129
|
return false;
|
|
129
130
|
}
|
|
130
131
|
const lines = expr.split('\n');
|
|
131
132
|
const [returnStatement] = lines.reverse();
|
|
132
|
-
|
|
133
|
-
if (returnStatementRegex.test(returnStatement)) {
|
|
134
|
-
const [_, argName] = returnStatement.split(returnStatementRegex);
|
|
135
|
-
return Boolean(argName);
|
|
136
|
-
}
|
|
137
|
-
return false;
|
|
133
|
+
return returnStatementRegex.test(returnStatement);
|
|
138
134
|
}
|
|
139
135
|
export function getDefaultExpr(i, key = 'myfield', previousExpr) {
|
|
140
136
|
const expr = previousExpr ?? `previous_result.${key}`;
|
package/gen/core/OpenAPI.js
CHANGED
package/logout.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare function logoutWithRedirect(rd?: string): void;
|
|
2
|
-
export declare function logout(
|
|
2
|
+
export declare function logout(): Promise<void>;
|
package/logout.js
CHANGED
|
@@ -6,22 +6,24 @@ function clearCookies() {
|
|
|
6
6
|
document.cookie.split(";").forEach(function (c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); });
|
|
7
7
|
}
|
|
8
8
|
export function logoutWithRedirect(rd) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
if (rd?.split('?')[0] != '/user/login') {
|
|
10
|
+
const error = document.cookie.includes('token')
|
|
11
|
+
? `error=${encodeURIComponent('You have been logged out because your session has expired.')}&`
|
|
12
|
+
: '';
|
|
13
|
+
clearCookies();
|
|
14
|
+
goto(`/user/login?${error}${rd ? 'rd=' + encodeURIComponent(rd) : ''}`);
|
|
15
|
+
}
|
|
14
16
|
}
|
|
15
|
-
export async function logout(
|
|
17
|
+
export async function logout() {
|
|
16
18
|
try {
|
|
17
19
|
clearStores();
|
|
18
20
|
await UserService.logout();
|
|
19
21
|
clearCookies();
|
|
20
|
-
goto(`/user/login${logoutMessage ? '?error=' + encodeURIComponent(logoutMessage) : ''}`);
|
|
21
|
-
sendUserToast('you have been logged out');
|
|
22
22
|
}
|
|
23
23
|
catch (error) {
|
|
24
|
-
goto('/user/login');
|
|
25
24
|
console.error(error);
|
|
25
|
+
clearCookies();
|
|
26
26
|
}
|
|
27
|
+
goto(`/user/login`);
|
|
28
|
+
sendUserToast('you have been logged out');
|
|
27
29
|
}
|