windmill-components 1.28.1 → 1.28.2
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/DisplayResult.svelte +5 -8
- package/components/FlowBuilder.svelte +20 -14
- package/components/FlowViewer.svelte +5 -1
- package/components/InputTransformsViewer.svelte +19 -0
- package/components/InputTransformsViewer.svelte.d.ts +17 -0
- package/components/flows/utils.js +14 -7
- package/package.json +3 -2
- package/script_helpers.d.ts +1 -1
- package/script_helpers.js +4 -7
|
@@ -4,15 +4,12 @@ import TableCustom from './TableCustom.svelte';
|
|
|
4
4
|
import { truncate } from '../utils';
|
|
5
5
|
export let result;
|
|
6
6
|
let resultKind = inferResultKind(result);
|
|
7
|
-
function isArray(obj) {
|
|
8
|
-
return Object.prototype.toString.call(obj) === '[object Array]';
|
|
9
|
-
}
|
|
10
7
|
function isRectangularArray(obj) {
|
|
11
|
-
if (!isArray(obj) || obj.length == 0) {
|
|
8
|
+
if (!Array.isArray(obj) || obj.length == 0) {
|
|
12
9
|
return false;
|
|
13
10
|
}
|
|
14
11
|
if (!Object.values(obj)
|
|
15
|
-
.map(isArray)
|
|
12
|
+
.map(Array.isArray)
|
|
16
13
|
.reduce((a, b) => a && b)) {
|
|
17
14
|
return false;
|
|
18
15
|
}
|
|
@@ -28,10 +25,10 @@ function inferResultKind(result) {
|
|
|
28
25
|
if (result) {
|
|
29
26
|
try {
|
|
30
27
|
let keys = Object.keys(result);
|
|
31
|
-
if (
|
|
28
|
+
if (isRectangularArray(result)) {
|
|
32
29
|
return 'table-row';
|
|
33
30
|
}
|
|
34
|
-
else if (keys.map((k) => isArray(result[k])).reduce((a, b) => a && b)) {
|
|
31
|
+
else if (keys.map((k) => Array.isArray(result[k])).reduce((a, b) => a && b)) {
|
|
35
32
|
return 'table-col';
|
|
36
33
|
}
|
|
37
34
|
else if (keys.length == 1 && keys[0] == 'png') {
|
|
@@ -51,7 +48,7 @@ function inferResultKind(result) {
|
|
|
51
48
|
</script>
|
|
52
49
|
|
|
53
50
|
{#if result}
|
|
54
|
-
{#if Object.keys(result).length > 0}<div>
|
|
51
|
+
{#if typeof result == 'object' && Object.keys(result).length > 0}<div>
|
|
55
52
|
The result keys are: <b>{Object.keys(result).join(', ')}</b>
|
|
56
53
|
</div>
|
|
57
54
|
{/if}
|
|
@@ -102,6 +102,9 @@ async function saveFlow() {
|
|
|
102
102
|
goto(`/flows/get/${$flowStore.path}`);
|
|
103
103
|
}
|
|
104
104
|
async function changeStep(step) {
|
|
105
|
+
if (step === 2 && previewOpen) {
|
|
106
|
+
previewOpen = false;
|
|
107
|
+
}
|
|
105
108
|
goto(`?step=${step}`);
|
|
106
109
|
}
|
|
107
110
|
flowStore.subscribe((flow) => {
|
|
@@ -120,7 +123,7 @@ onDestroy(() => {
|
|
|
120
123
|
</script>
|
|
121
124
|
|
|
122
125
|
<div class="flex flex-row w-full h-full justify-between">
|
|
123
|
-
<div class=
|
|
126
|
+
<div class={`flex flex-col mb-96 m-auto w-1/2`}>
|
|
124
127
|
<!-- Nav between steps-->
|
|
125
128
|
<div class="justify-between flex flex-row w-full my-4">
|
|
126
129
|
<Breadcrumb>
|
|
@@ -186,19 +189,6 @@ onDestroy(() => {
|
|
|
186
189
|
|
|
187
190
|
<Icon data={faPlay} class="ml-2" />
|
|
188
191
|
</Button>
|
|
189
|
-
<div class={`relative h-screen w-1/3 ${previewOpen ? '' : 'hidden'}`}>
|
|
190
|
-
<div class="absolute top-0 h-full">
|
|
191
|
-
<div class="fixed border-l-2 right-0 h-screen w-1/3">
|
|
192
|
-
<FlowPreviewContent
|
|
193
|
-
bind:args={scheduleArgs}
|
|
194
|
-
on:close={() => (previewOpen = !previewOpen)}
|
|
195
|
-
on:change={(e) => {
|
|
196
|
-
previewResults.set(jobsToResults(e.detail))
|
|
197
|
-
}}
|
|
198
|
-
/>
|
|
199
|
-
</div>
|
|
200
|
-
</div>
|
|
201
|
-
</div>
|
|
202
192
|
{:else if step === 2}
|
|
203
193
|
<ScriptSchema
|
|
204
194
|
synchronizedHeader={false}
|
|
@@ -211,4 +201,20 @@ onDestroy(() => {
|
|
|
211
201
|
<p>Loading</p>
|
|
212
202
|
{/if}
|
|
213
203
|
</div>
|
|
204
|
+
|
|
205
|
+
<div class={`relative h-screen w-1/3 ${previewOpen ? '' : 'hidden'}`}>
|
|
206
|
+
<div class="absolute top-0 h-full">
|
|
207
|
+
{#if $flowStore && step === 1}
|
|
208
|
+
<div class="fixed border-l-2 right-0 h-screen w-1/3">
|
|
209
|
+
<FlowPreviewContent
|
|
210
|
+
bind:args={scheduleArgs}
|
|
211
|
+
on:close={() => (previewOpen = !previewOpen)}
|
|
212
|
+
on:change={(e) => {
|
|
213
|
+
previewResults.set(jobsToResults(e.detail))
|
|
214
|
+
}}
|
|
215
|
+
/>
|
|
216
|
+
</div>
|
|
217
|
+
{/if}
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
214
220
|
</div>
|
|
@@ -7,6 +7,7 @@ import { slide } from 'svelte/transition';
|
|
|
7
7
|
import Tabs from './Tabs.svelte';
|
|
8
8
|
import SchemaViewer from './SchemaViewer.svelte';
|
|
9
9
|
import FieldHeader from './FieldHeader.svelte';
|
|
10
|
+
import InputTransformsViewer from './InputTransformsViewer.svelte';
|
|
10
11
|
export let flow;
|
|
11
12
|
let flowFiltered = {
|
|
12
13
|
summary: flow.summary,
|
|
@@ -104,9 +105,10 @@ function toAny(x) {
|
|
|
104
105
|
}}
|
|
105
106
|
class="mb-2 underline text-black"
|
|
106
107
|
>
|
|
107
|
-
View code {open[i] ? '(-)' : '(+)'}</button
|
|
108
|
+
View code and inputs {open[i] ? '(-)' : '(+)'}</button
|
|
108
109
|
>
|
|
109
110
|
{#if open[i]}
|
|
111
|
+
<InputTransformsViewer inputTransforms={mod?.input_transform} />
|
|
110
112
|
<div class="w-full h-full">
|
|
111
113
|
<iframe
|
|
112
114
|
style="height: 400px;"
|
|
@@ -131,6 +133,8 @@ function toAny(x) {
|
|
|
131
133
|
|
|
132
134
|
{#if open[i]}
|
|
133
135
|
<div transition:slide class="border border-black p-2 bg-gray-50 w-full">
|
|
136
|
+
<InputTransformsViewer inputTransforms={mod?.input_transform} />
|
|
137
|
+
|
|
134
138
|
<Highlight
|
|
135
139
|
language={mod?.value?.language == 'deno' ? typescript : python}
|
|
136
140
|
code={mod?.value?.content}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script>import { Highlight } from 'svelte-highlight';
|
|
2
|
+
import ObjectViewer from './propertyPicker/ObjectViewer.svelte';
|
|
3
|
+
import typescript from 'svelte-highlight/languages/typescript';
|
|
4
|
+
export let inputTransforms;
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<ul class="mb-1">
|
|
8
|
+
{#each Object.entries(inputTransforms) as [key, val]}
|
|
9
|
+
<li>
|
|
10
|
+
<span class="font-black text-gray-700">{key}</span>: {#if val.type == 'static'}<ObjectViewer
|
|
11
|
+
json={val.value}
|
|
12
|
+
/>{:else}
|
|
13
|
+
<span class="inline-block inline-highlight">
|
|
14
|
+
<Highlight offsetTop={0} language={typescript} code={val.expr} />
|
|
15
|
+
</span>
|
|
16
|
+
{/if}
|
|
17
|
+
</li>
|
|
18
|
+
{/each}
|
|
19
|
+
</ul>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { InputTransform } from '../gen';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
inputTransforms: Record<string, InputTransform>;
|
|
6
|
+
};
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {};
|
|
11
|
+
};
|
|
12
|
+
export declare type InputTransformsViewerProps = typeof __propDef.props;
|
|
13
|
+
export declare type InputTransformsViewerEvents = typeof __propDef.events;
|
|
14
|
+
export declare type InputTransformsViewerSlots = typeof __propDef.slots;
|
|
15
|
+
export default class InputTransformsViewer extends SvelteComponentTyped<InputTransformsViewerProps, InputTransformsViewerEvents, InputTransformsViewerSlots> {
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -13,6 +13,9 @@ export function flowToMode(flow, mode) {
|
|
|
13
13
|
if (inp.type == 'javascript') {
|
|
14
14
|
//@ts-ignore
|
|
15
15
|
inp.value = undefined;
|
|
16
|
+
inp.expr = inp.expr.split('\n')
|
|
17
|
+
.filter((x) => x != '' && !x.startsWith(`import { previous_result, flow_input, step, variable, resource, params } from 'windmill@`))
|
|
18
|
+
.join('\n');
|
|
16
19
|
}
|
|
17
20
|
else {
|
|
18
21
|
//@ts-ignore
|
|
@@ -24,7 +27,7 @@ export function flowToMode(flow, mode) {
|
|
|
24
27
|
const triggerModule = newFlow.value.modules[0];
|
|
25
28
|
const oldModules = newFlow.value.modules.slice(1);
|
|
26
29
|
if (triggerModule) {
|
|
27
|
-
triggerModule.stop_after_if_expr = 'result.
|
|
30
|
+
triggerModule.stop_after_if_expr = 'result.length == 0';
|
|
28
31
|
triggerModule.skip_if_stopped = true;
|
|
29
32
|
}
|
|
30
33
|
newFlow.value.modules = newFlow.value.modules.slice(0, 1);
|
|
@@ -33,7 +36,7 @@ export function flowToMode(flow, mode) {
|
|
|
33
36
|
input_transform: oldModules[0].input_transform,
|
|
34
37
|
value: {
|
|
35
38
|
type: 'forloopflow',
|
|
36
|
-
iterator: { type: 'javascript', expr: 'result
|
|
39
|
+
iterator: { type: 'javascript', expr: 'result' },
|
|
37
40
|
value: {
|
|
38
41
|
modules: oldModules
|
|
39
42
|
},
|
|
@@ -192,13 +195,17 @@ export async function runFlowPreview(args, flow) {
|
|
|
192
195
|
});
|
|
193
196
|
}
|
|
194
197
|
function computeFlowInputPull(previewResult, flowInputAsObject) {
|
|
195
|
-
const iteratorValues = (previewResult
|
|
198
|
+
const iteratorValues = (previewResult && Array.isArray(previewResult)) ?
|
|
196
199
|
{
|
|
197
|
-
|
|
198
|
-
|
|
200
|
+
iter: {
|
|
201
|
+
value: previewResult[0],
|
|
202
|
+
index: `The current index of the iteration as a number (here from 0 to ${previewResult.length - 1})`
|
|
203
|
+
}
|
|
199
204
|
} : {
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
iter: {
|
|
206
|
+
value: 'The current value of the iteration as an object',
|
|
207
|
+
index: 'The current index of the iteration as a number'
|
|
208
|
+
}
|
|
202
209
|
};
|
|
203
210
|
return Object.assign(Object.assign(flowInputAsObject, previewResult), iteratorValues);
|
|
204
211
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "windmill-components",
|
|
3
|
-
"version": "1.28.
|
|
3
|
+
"version": "1.28.2",
|
|
4
4
|
"devDependencies": {
|
|
5
5
|
"@playwright/test": "^1.24.2",
|
|
6
6
|
"@sveltejs/adapter-static": "^1.0.0-next.37",
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
"./components/GroupModal.svelte": "./components/GroupModal.svelte",
|
|
83
83
|
"./components/IconedResourceType.svelte": "./components/IconedResourceType.svelte",
|
|
84
84
|
"./components/InputTransformForm.svelte": "./components/InputTransformForm.svelte",
|
|
85
|
+
"./components/InputTransformsViewer.svelte": "./components/InputTransformsViewer.svelte",
|
|
85
86
|
"./components/InviteGlobalUser.svelte": "./components/InviteGlobalUser.svelte",
|
|
86
87
|
"./components/InviteUser.svelte": "./components/InviteUser.svelte",
|
|
87
88
|
"./components/ItemPicker.svelte": "./components/ItemPicker.svelte",
|
|
@@ -273,4 +274,4 @@
|
|
|
273
274
|
"./user": "./user.js",
|
|
274
275
|
"./utils": "./utils.js"
|
|
275
276
|
}
|
|
276
|
-
}
|
|
277
|
+
}
|
package/script_helpers.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const PYTHON_INIT_CODE = "import os\nimport wmill\nfrom datetime import datetime\n
|
|
1
|
+
export declare const PYTHON_INIT_CODE = "import os\nimport wmill\nfrom datetime import datetime\n\n\"\"\"\nUse Cmd/Ctrl + S to autoformat the code.\nThe client is used to interact with windmill itself through its standard API.\nOne can explore the methods available through autocompletion of `wmill.XXX`.\n\"\"\"\n\ndef main(name: str = \"Nicolas Bourbaki\",\n age: int = 42,\n obj: dict = {\"even\": \"dicts\"},\n l: list = [\"or\", \"lists!\"],\n file_: bytes = bytes(0),\n dtime: datetime = datetime.now()):\n \"\"\"A main function is required for the script to be able to accept arguments.\n Types are recommended.\"\"\"\n print(f\"Hello World and a warm welcome especially to {name}\")\n print(\"and its acolytes..\", age, obj, l, len(file_), dtime)\n # retrieve variables, including secrets by querying the windmill platform.\n # secret fetching is audited by windmill.\n secret = wmill.get_variable(\"g/all/pretty_secret\")\n print(f\"The env variable at `g/all/pretty_secret`: {secret}\")\n # interact with the windmill platform to get the version\n version = wmill.get_version()\n # fetch reserved variables as environment variables\n user = os.environ.get(\"WM_USERNAME\")\n # the return value is then parsed and can be retrieved by other scripts conveniently\n return {\"version\": version, \"splitted\": name.split(), \"user\": user}\n";
|
|
2
2
|
export declare const DENO_INIT_CODE: string;
|
|
3
3
|
export declare const DENO_INIT_CODE_TRIGGER: string;
|
|
4
4
|
export declare function initialCode(language: 'deno' | 'python3', is_trigger: boolean): string;
|
package/script_helpers.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
export const PYTHON_INIT_CODE = `import os
|
|
2
2
|
import wmill
|
|
3
3
|
from datetime import datetime
|
|
4
|
-
|
|
5
|
-
# and the autoformatter Black in our servers. Use Cmd/Ctrl + S to autoformat the code.
|
|
6
|
-
# Beware that the code is only saved when you click Save and not across reload.
|
|
7
|
-
# You can however navigate to any steps safely.
|
|
4
|
+
|
|
8
5
|
"""
|
|
6
|
+
Use Cmd/Ctrl + S to autoformat the code.
|
|
9
7
|
The client is used to interact with windmill itself through its standard API.
|
|
10
|
-
One can explore the methods available through autocompletion of \`
|
|
11
|
-
Only the most common methods are included for ease of use. Request more as
|
|
12
|
-
feedback if you feel you are missing important ones.
|
|
8
|
+
One can explore the methods available through autocompletion of \`wmill.XXX\`.
|
|
13
9
|
"""
|
|
10
|
+
|
|
14
11
|
def main(name: str = "Nicolas Bourbaki",
|
|
15
12
|
age: int = 42,
|
|
16
13
|
obj: dict = {"even": "dicts"},
|