windmill-components 1.57.1 → 1.57.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/Tooltip.svelte +1 -1
- package/components/apps/components/DisplayComponent.svelte +1 -1
- package/components/apps/components/dataDisplay/AppText.svelte +6 -2
- package/components/apps/components/form/AppForm.svelte +8 -13
- package/components/apps/components/helpers/RunnableComponent.svelte +16 -7
- package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +1 -0
- package/components/apps/components/helpers/RunnableWrapper.svelte +6 -1
- package/components/apps/components/helpers/RunnableWrapper.svelte.d.ts +1 -0
- package/components/apps/editor/AppEditor.svelte +3 -1
- package/components/apps/editor/AppEditorHeader.svelte +28 -18
- package/components/apps/editor/AppExportButton.svelte +1 -1
- package/components/apps/editor/AppPreview.svelte +3 -1
- package/components/apps/editor/AppPreview.svelte.d.ts +1 -0
- package/components/apps/editor/AppPublishButton.svelte +3 -10
- package/components/apps/editor/AppPublishButton.svelte.d.ts +1 -0
- package/components/apps/editor/ComponentHeader.svelte +7 -7
- package/components/apps/editor/GridEditor.svelte +2 -1
- package/components/apps/editor/componentsPanel/ComponentList.svelte +1 -1
- package/components/apps/editor/settingsPanel/PickInlineScript.svelte +0 -1
- package/components/apps/editor/settingsPanel/SelectedRunnable.svelte +6 -5
- package/components/apps/editor/settingsPanel/inputEditor/ConnectedInputEditor.svelte +53 -49
- package/components/apps/editor/settingsPanel/inputEditor/ConnectedInputEditor.svelte.d.ts +2 -2
- package/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte +6 -4
- package/components/apps/inputType.d.ts +1 -0
- package/components/apps/types.d.ts +1 -0
- package/components/common/table/RowIcon.svelte +1 -1
- package/components/common/toggleButton/ToggleButtonGroup.svelte +3 -3
- package/components/flows/pickers/PickHubApp.svelte +73 -0
- package/components/flows/pickers/PickHubApp.svelte.d.ts +20 -0
- package/components/flows/pickers/PickHubFlow.svelte +3 -1
- package/components/flows/pickers/PickHubScript.svelte +1 -0
- package/gen/services/AppService.d.ts +32 -0
- package/gen/services/AppService.js +25 -0
- package/package.json +501 -502
- package/utils.d.ts +8 -0
- package/utils.js +11 -1
- package/components/apps/editor/settingsPanel/SectionPanel.svelte +0 -70
- package/components/apps/editor/settingsPanel/SectionPanel.svelte.d.ts +0 -19
- package/components/apps/editor/settingsPanel/UserInputEditor.svelte +0 -2
- package/components/apps/editor/settingsPanel/UserInputEditor.svelte.d.ts +0 -14
|
@@ -6,7 +6,7 @@ let result = undefined;
|
|
|
6
6
|
export const staticOutputs = ['result', 'loading'];
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
|
-
<RunnableWrapper
|
|
9
|
+
<RunnableWrapper bind:result bind:componentInput {id}>
|
|
10
10
|
<div class="w-full border-b px-2 text-xs p-1 font-semibold bg-gray-500 text-white rounded-t-sm">
|
|
11
11
|
Results
|
|
12
12
|
</div>
|
|
@@ -51,9 +51,13 @@ $: style && (classes = getClasses());
|
|
|
51
51
|
<div class="text-gray-400 bg-gray-100 flex justify-center items-center h-full w-full">
|
|
52
52
|
No text
|
|
53
53
|
</div>
|
|
54
|
-
{:else}<svelte:element
|
|
55
|
-
|
|
54
|
+
{:else}<svelte:element
|
|
55
|
+
this={component}
|
|
56
|
+
class="whitespace-pre-wrap {classes}"
|
|
57
|
+
style={extraStyle}
|
|
56
58
|
>
|
|
59
|
+
{String(result)}
|
|
60
|
+
</svelte:element>
|
|
57
61
|
{/if}
|
|
58
62
|
</AlignWrapper>
|
|
59
63
|
</RunnableWrapper>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script>import { Button } from '../../../common';
|
|
2
|
-
import { faArrowRight, faRefresh } from '@fortawesome/free-solid-svg-icons';
|
|
3
2
|
import { getContext } from 'svelte';
|
|
4
3
|
import AlignWrapper from '../helpers/AlignWrapper.svelte';
|
|
5
4
|
import InputValue from '../helpers/InputValue.svelte';
|
|
@@ -17,7 +16,6 @@ let color;
|
|
|
17
16
|
let size;
|
|
18
17
|
let runnableComponent;
|
|
19
18
|
let isLoading = false;
|
|
20
|
-
let ownClick = false;
|
|
21
19
|
$: outputs = $worldStore?.outputsById[id];
|
|
22
20
|
$: if (outputs?.loading != undefined) {
|
|
23
21
|
outputs.loading.set(false, true);
|
|
@@ -25,12 +23,8 @@ $: if (outputs?.loading != undefined) {
|
|
|
25
23
|
$: outputs?.loading.subscribe({
|
|
26
24
|
next: (value) => {
|
|
27
25
|
isLoading = value;
|
|
28
|
-
if (ownClick && !value) {
|
|
29
|
-
ownClick = false;
|
|
30
|
-
}
|
|
31
26
|
}
|
|
32
27
|
});
|
|
33
|
-
$: loading = isLoading && ownClick;
|
|
34
28
|
</script>
|
|
35
29
|
|
|
36
30
|
<InputValue {id} input={configuration.label} bind:value={labelValue} />
|
|
@@ -38,6 +32,7 @@ $: loading = isLoading && ownClick;
|
|
|
38
32
|
<InputValue {id} input={configuration.size} bind:value={size} />
|
|
39
33
|
|
|
40
34
|
<RunnableWrapper
|
|
35
|
+
noMinH
|
|
41
36
|
bind:runnableComponent
|
|
42
37
|
bind:componentInput
|
|
43
38
|
{id}
|
|
@@ -46,19 +41,19 @@ $: loading = isLoading && ownClick;
|
|
|
46
41
|
forceSchemaDisplay={true}
|
|
47
42
|
>
|
|
48
43
|
<AlignWrapper {horizontalAlignment}>
|
|
49
|
-
<div class="flex flex-col gap-2 px-4 w-full">
|
|
44
|
+
<div class="flex flex-col gap-2 px-4 w-full ">
|
|
50
45
|
<div>
|
|
51
46
|
{#if componentInput?.type != 'runnable' || Object.values(componentInput?.fields ?? {}).filter((x) => x.type == 'user').length == 0}
|
|
52
|
-
<span class="text-gray-600 italic text-sm py-2"
|
|
53
|
-
|
|
54
|
-
runnable and set some 'Runnable Inputs' to 'User Input'
|
|
55
|
-
>
|
|
47
|
+
<span class="text-gray-600 italic text-sm py-2">
|
|
48
|
+
Run forms are meant to be associated with a runnable with some user inputs. Pick a
|
|
49
|
+
runnable and set some 'Runnable Inputs' to 'User Input'
|
|
50
|
+
</span>
|
|
56
51
|
{/if}
|
|
57
52
|
</div>
|
|
58
53
|
<div class="flex justify-end">
|
|
59
54
|
<Button
|
|
60
|
-
{
|
|
61
|
-
btnClasses="
|
|
55
|
+
loading={isLoading}
|
|
56
|
+
btnClasses="my-1"
|
|
62
57
|
on:pointerdown={(e) => {
|
|
63
58
|
e?.stopPropagation()
|
|
64
59
|
window.dispatchEvent(new Event('pointerup'))
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import SchemaForm from '../../../SchemaForm.svelte';
|
|
3
3
|
import TestJobLoader from '../../../TestJobLoader.svelte';
|
|
4
4
|
import { AppService } from '../../../../gen';
|
|
5
|
-
import { defaultIfEmptyString, emptySchema } from '../../../../utils';
|
|
5
|
+
import { defaultIfEmptyString, emptySchema, sendUserToast } from '../../../../utils';
|
|
6
6
|
import { getContext, onMount } from 'svelte';
|
|
7
7
|
import { fieldTypeToTsType, schemaToInputsSpec } from '../../utils';
|
|
8
8
|
import InputValue from './InputValue.svelte';
|
|
@@ -15,14 +15,15 @@ export let extraQueryParams = {};
|
|
|
15
15
|
export let autoRefresh = true;
|
|
16
16
|
export let result = undefined;
|
|
17
17
|
export let forceSchemaDisplay = false;
|
|
18
|
-
|
|
18
|
+
export let noMinH = false;
|
|
19
|
+
const { worldStore, runnableComponents, workspace, appPath, isEditor, jobs, noBackend } = getContext('AppEditorContext');
|
|
19
20
|
onMount(() => {
|
|
20
21
|
if (autoRefresh) {
|
|
21
22
|
$runnableComponents[id] = async () => {
|
|
22
|
-
await executeComponent();
|
|
23
|
+
await executeComponent(true);
|
|
23
24
|
};
|
|
25
|
+
executeComponent(true);
|
|
24
26
|
}
|
|
25
|
-
executeComponent();
|
|
26
27
|
});
|
|
27
28
|
let args = {};
|
|
28
29
|
let testIsLoading = false;
|
|
@@ -46,7 +47,9 @@ let currentStaticValues = lazyStaticValues;
|
|
|
46
47
|
$: fields && (currentStaticValues = computeStaticValues());
|
|
47
48
|
$: if (JSON.stringify(currentStaticValues) != JSON.stringify(lazyStaticValues)) {
|
|
48
49
|
lazyStaticValues = currentStaticValues;
|
|
49
|
-
|
|
50
|
+
if (autoRefresh) {
|
|
51
|
+
setDebouncedExecute();
|
|
52
|
+
}
|
|
50
53
|
}
|
|
51
54
|
$: fields && (lazyStaticValues = computeStaticValues());
|
|
52
55
|
$: runnableInputValues &&
|
|
@@ -134,7 +137,12 @@ $: disabledArgs = Object.keys(fields ?? {}).reduce((disabledArgsAccumulator, inp
|
|
|
134
137
|
}
|
|
135
138
|
return disabledArgsAccumulator;
|
|
136
139
|
}, []);
|
|
137
|
-
async function executeComponent() {
|
|
140
|
+
async function executeComponent(noToast = false) {
|
|
141
|
+
if (noBackend) {
|
|
142
|
+
if (!noToast) {
|
|
143
|
+
sendUserToast('This component is not connected to a backendm keeping static value');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
138
146
|
if (runnable?.type === 'runnableByName' && !runnable.inlineScript) {
|
|
139
147
|
return;
|
|
140
148
|
}
|
|
@@ -245,9 +253,10 @@ let lastStartedAt = Date.now();
|
|
|
245
253
|
<Alert type="error" title="Error during execution">
|
|
246
254
|
<pre title={result.error} class="text-2xs whitespace-pre-wrap">{result.error}</pre>
|
|
247
255
|
</Alert>
|
|
256
|
+
<slot />
|
|
248
257
|
</div>
|
|
249
258
|
{:else}
|
|
250
|
-
<div class="grow min-w-1/2 min-h-[66%]">
|
|
259
|
+
<div class="grow min-w-1/2 {noMinH ? '' : 'min-h-[66%]'}">
|
|
251
260
|
<slot />
|
|
252
261
|
</div>
|
|
253
262
|
{/if}
|
|
@@ -5,11 +5,15 @@ import RunnableComponent from './RunnableComponent.svelte';
|
|
|
5
5
|
export let componentInput;
|
|
6
6
|
export let id;
|
|
7
7
|
export let result = undefined;
|
|
8
|
+
export let noMinH = false;
|
|
8
9
|
export let extraQueryParams = {};
|
|
9
10
|
export let autoRefresh = true;
|
|
10
11
|
export let runnableComponent = undefined;
|
|
11
12
|
export let forceSchemaDisplay = false;
|
|
12
|
-
const { staticExporter } = getContext('AppEditorContext');
|
|
13
|
+
const { staticExporter, noBackend } = getContext('AppEditorContext');
|
|
14
|
+
if (noBackend) {
|
|
15
|
+
result = componentInput?.['value'];
|
|
16
|
+
}
|
|
13
17
|
onMount(() => {
|
|
14
18
|
$staticExporter[id] = () => result;
|
|
15
19
|
});
|
|
@@ -30,6 +34,7 @@ function isRunnableDefined() {
|
|
|
30
34
|
{id}
|
|
31
35
|
{extraQueryParams}
|
|
32
36
|
{forceSchemaDisplay}
|
|
37
|
+
{noMinH}
|
|
33
38
|
>
|
|
34
39
|
<slot />
|
|
35
40
|
</RunnableComponent>
|
|
@@ -6,6 +6,7 @@ declare const __propDef: {
|
|
|
6
6
|
componentInput: AppInput | undefined;
|
|
7
7
|
id: string;
|
|
8
8
|
result?: any;
|
|
9
|
+
noMinH?: boolean | undefined;
|
|
9
10
|
extraQueryParams?: Record<string, any> | undefined;
|
|
10
11
|
autoRefresh?: boolean | undefined;
|
|
11
12
|
runnableComponent?: RunnableComponent | undefined;
|
|
@@ -53,7 +53,8 @@ setContext('AppEditorContext', {
|
|
|
53
53
|
onchange: () => saveDraft(),
|
|
54
54
|
isEditor: true,
|
|
55
55
|
jobs: writable([]),
|
|
56
|
-
staticExporter: writable({})
|
|
56
|
+
staticExporter: writable({}),
|
|
57
|
+
noBackend: false
|
|
57
58
|
});
|
|
58
59
|
let timeout = undefined;
|
|
59
60
|
$: $appStore && saveDraft();
|
|
@@ -106,6 +107,7 @@ else {
|
|
|
106
107
|
{policy}
|
|
107
108
|
isEditor
|
|
108
109
|
{context}
|
|
110
|
+
noBackend={false}
|
|
109
111
|
/>
|
|
110
112
|
{:else}
|
|
111
113
|
<SplitPanesWrapper>
|
|
@@ -249,8 +249,9 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
|
|
|
249
249
|
<Drawer bind:open={publishDrawerOpen} size="800px">
|
|
250
250
|
<DrawerContent title="Publish an App" on:close={() => (publishDrawerOpen = false)}>
|
|
251
251
|
{#if appPath == ''}
|
|
252
|
-
<Alert title="Require saving" type="error">
|
|
253
|
-
|
|
252
|
+
<Alert title="Require saving" type="error">
|
|
253
|
+
Save this app once before you can publish it
|
|
254
|
+
</Alert>
|
|
254
255
|
{:else}
|
|
255
256
|
<Alert title="App executed on behalf of publisher">
|
|
256
257
|
A viewer of the app will execute the runnables of the app on behalf of the publisher
|
|
@@ -258,8 +259,8 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
|
|
|
258
259
|
guarantee tight security, a policy is computed at time of saving of the app which only allow
|
|
259
260
|
the scripts/flows referred to in the app to be called on behalf of. Furthermore, static
|
|
260
261
|
parameters are not overridable. Hence, users will only be able to use the app as intended by
|
|
261
|
-
the publisher without risk for leaking resources not used in the app
|
|
262
|
-
>
|
|
262
|
+
the publisher without risk for leaking resources not used in the app.
|
|
263
|
+
</Alert>
|
|
263
264
|
<div class="mt-4" />
|
|
264
265
|
<Toggle
|
|
265
266
|
options={{
|
|
@@ -321,8 +322,8 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
|
|
|
321
322
|
</div>
|
|
322
323
|
</ToggleButton>
|
|
323
324
|
<ToggleButton position="right" value="preview" size="xs">
|
|
324
|
-
<div class="inline-flex gap-1 items-center"> <Eye size={14} /> Preview</div
|
|
325
|
-
>
|
|
325
|
+
<div class="inline-flex gap-1 items-center"> <Eye size={14} /> Preview</div>
|
|
326
|
+
</ToggleButton>
|
|
326
327
|
</ToggleButtonGroup>
|
|
327
328
|
</div>
|
|
328
329
|
<div>
|
|
@@ -330,23 +331,30 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
|
|
|
330
331
|
<ToggleButton position="left" value="sm" size="xs">
|
|
331
332
|
<Smartphone size={14} />
|
|
332
333
|
</ToggleButton>
|
|
333
|
-
<ToggleButton position="right" value="lg" size="xs"
|
|
334
|
+
<ToggleButton position="right" value="lg" size="xs">
|
|
335
|
+
<Laptop2 size={14} />
|
|
336
|
+
</ToggleButton>
|
|
334
337
|
</ToggleButtonGroup>
|
|
335
338
|
</div>
|
|
336
339
|
|
|
337
340
|
<span class="hidden lg:block">
|
|
338
341
|
<ToggleButtonGroup bind:selected={$app.fullscreen}>
|
|
339
|
-
<ToggleButton position="left" value={false} size="xs"
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
342
|
+
<ToggleButton position="left" value={false} size="xs">
|
|
343
|
+
<div class="flex gap-1 justify-start">
|
|
344
|
+
<AlignHorizontalSpaceAround size={14} />
|
|
345
|
+
<Tooltip>
|
|
346
|
+
The max width is 1168px and the content stay centered instead of taking the full page
|
|
347
|
+
width
|
|
348
|
+
</Tooltip>
|
|
349
|
+
</div>
|
|
350
|
+
</ToggleButton>
|
|
351
|
+
<ToggleButton position="right" value={true} size="xs">
|
|
352
|
+
<Expand size={14} />
|
|
353
|
+
</ToggleButton>
|
|
346
354
|
</ToggleButtonGroup>
|
|
347
355
|
</span>
|
|
348
356
|
</div>
|
|
349
|
-
<div class="flex flex-row grow gap-
|
|
357
|
+
<div class="flex flex-row grow gap-2 justify-end items-center">
|
|
350
358
|
<Button
|
|
351
359
|
on:click={() => (jobsDrawerOpen = true)}
|
|
352
360
|
color="light"
|
|
@@ -357,13 +365,13 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
|
|
|
357
365
|
Debug Runs
|
|
358
366
|
</Button>
|
|
359
367
|
<span class="hidden lg:inline-flex gap-1">
|
|
360
|
-
<AppPublishButton staticExporter={$staticExporter} app={$app} />
|
|
368
|
+
<AppPublishButton summary={$summary} staticExporter={$staticExporter} app={$app} />
|
|
361
369
|
<AppExportButton app={$app} />
|
|
362
370
|
</span>
|
|
363
371
|
|
|
364
372
|
<Button
|
|
365
373
|
on:click={() => (publishDrawerOpen = true)}
|
|
366
|
-
color="
|
|
374
|
+
color="light"
|
|
367
375
|
size="xs"
|
|
368
376
|
variant="border"
|
|
369
377
|
startIcon={{ icon: faExternalLink }}
|
|
@@ -375,7 +383,9 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
|
|
|
375
383
|
startIcon={{ icon: faSave }}
|
|
376
384
|
on:click={save}
|
|
377
385
|
color="dark"
|
|
378
|
-
size="xs"
|
|
386
|
+
size="xs"
|
|
379
387
|
>
|
|
388
|
+
Save
|
|
389
|
+
</Button>
|
|
380
390
|
</div>
|
|
381
391
|
</div>
|
|
@@ -10,7 +10,7 @@ let jsonViewerDrawer;
|
|
|
10
10
|
export let app;
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
|
-
<Button size="
|
|
13
|
+
<Button size="xs" variant="border" color="light" on:click={() => jsonViewerDrawer.toggleDrawer()}>
|
|
14
14
|
<Icon data={faFileExport} scale={0.6} class="inline mr-2" />
|
|
15
15
|
JSON
|
|
16
16
|
</Button>
|
|
@@ -11,6 +11,7 @@ export let summary;
|
|
|
11
11
|
export let workspace;
|
|
12
12
|
export let isEditor;
|
|
13
13
|
export let context;
|
|
14
|
+
export let noBackend = false;
|
|
14
15
|
const appStore = writable(app);
|
|
15
16
|
const worldStore = writable(undefined);
|
|
16
17
|
const staticOutputs = writable({});
|
|
@@ -38,7 +39,8 @@ setContext('AppEditorContext', {
|
|
|
38
39
|
onchange: undefined,
|
|
39
40
|
isEditor,
|
|
40
41
|
jobs: writable([]),
|
|
41
|
-
staticExporter: writable({})
|
|
42
|
+
staticExporter: writable({}),
|
|
43
|
+
noBackend
|
|
42
44
|
});
|
|
43
45
|
let mounted = false;
|
|
44
46
|
onMount(() => {
|
|
@@ -9,23 +9,16 @@ import { Button } from '../../common';
|
|
|
9
9
|
let jsonViewerDrawer;
|
|
10
10
|
export let app;
|
|
11
11
|
export let staticExporter;
|
|
12
|
+
export let summary;
|
|
12
13
|
function toStatic() {
|
|
13
14
|
const newApp = JSON.parse(JSON.stringify(app));
|
|
14
15
|
newApp.grid.forEach((x) => {
|
|
15
16
|
let c = x.data;
|
|
16
17
|
if (c.componentInput?.type == 'runnable') {
|
|
17
|
-
c.componentInput =
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
type: 'static',
|
|
20
|
-
value: staticExporter[x.id](),
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
fieldType: c.componentInput.fieldType,
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
subFieldType: c.componentInput.subFieldType
|
|
25
|
-
};
|
|
18
|
+
c.componentInput.value = staticExporter[x.id]();
|
|
26
19
|
}
|
|
27
20
|
});
|
|
28
|
-
return newApp;
|
|
21
|
+
return { app: newApp, summary };
|
|
29
22
|
}
|
|
30
23
|
</script>
|
|
31
24
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>import { classNames } from '../../../utils';
|
|
2
|
-
import { Anchor, Move
|
|
2
|
+
import { Anchor, Move } from 'lucide-svelte';
|
|
3
3
|
import { createEventDispatcher } from 'svelte';
|
|
4
4
|
export let component;
|
|
5
5
|
export let selected;
|
|
@@ -12,7 +12,7 @@ const dispatch = createEventDispatcher();
|
|
|
12
12
|
<span
|
|
13
13
|
title={`Id: ${component.id}`}
|
|
14
14
|
class={classNames(
|
|
15
|
-
'px-2 text-2xs font-bold
|
|
15
|
+
'px-2 text-2xs font-bold w-fit absolute shadow -top-1 -left-2 border z-50',
|
|
16
16
|
selected
|
|
17
17
|
? 'bg-indigo-500/90 border-blue-500 text-white'
|
|
18
18
|
: 'bg-gray-200/90 border-gray-300 text-gray-500'
|
|
@@ -26,13 +26,11 @@ const dispatch = createEventDispatcher();
|
|
|
26
26
|
<button
|
|
27
27
|
title="Position locking"
|
|
28
28
|
class={classNames(
|
|
29
|
-
'text-gray-800 px-1 text-2xs py-0.5 font-bold
|
|
29
|
+
'text-gray-800 px-1 text-2xs py-0.5 font-bold w-fit shadow border border-gray-300 absolute -top-1 right-[2.5rem] z-50 cursor-pointer',
|
|
30
30
|
' hover:bg-gray-300',
|
|
31
31
|
selected ? 'bg-gray-200/80' : 'bg-gray-200/80'
|
|
32
32
|
)}
|
|
33
|
-
on:click={() =>
|
|
34
|
-
dispatch('lock')
|
|
35
|
-
}}
|
|
33
|
+
on:click={() => dispatch('lock')}
|
|
36
34
|
>
|
|
37
35
|
{#if locked}
|
|
38
36
|
<Anchor aria-label="Unlock position" size={14} class="text-orange-500" />
|
|
@@ -49,6 +47,8 @@ const dispatch = createEventDispatcher();
|
|
|
49
47
|
class={classNames(
|
|
50
48
|
'text-gray-600 px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit absolute border border-gray-300 -top-1 shadow right-[4.5rem] z-50 cursor-move',
|
|
51
49
|
'bg-gray-200/80'
|
|
52
|
-
)}
|
|
50
|
+
)}
|
|
53
51
|
>
|
|
52
|
+
<Move size={14} />
|
|
53
|
+
</span>
|
|
54
54
|
{/if}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script>import { getContext
|
|
1
|
+
<script>import { getContext } from 'svelte';
|
|
2
2
|
import Grid from 'svelte-grid';
|
|
3
3
|
import ComponentEditor from './ComponentEditor.svelte';
|
|
4
4
|
import { classNames } from '../../../utils';
|
|
@@ -116,6 +116,7 @@ const onpointerup = () => {
|
|
|
116
116
|
>{dataItem.data.id}</div
|
|
117
117
|
>
|
|
118
118
|
{/if}
|
|
119
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
119
120
|
<div
|
|
120
121
|
on:pointerdown={() => {
|
|
121
122
|
selectComponent(dataItem.data.id)
|
|
@@ -99,7 +99,7 @@ onMount(() => {
|
|
|
99
99
|
class="border w-24 shadow-sm h-16 p-2 flex flex-col gap-2 items-center
|
|
100
100
|
justify-center bg-white rounded-md hover:bg-gray-100 duration-200"
|
|
101
101
|
>
|
|
102
|
-
<svelte:component this={displayData[item.type].icon}
|
|
102
|
+
<svelte:component this={displayData[item.type].icon} />
|
|
103
103
|
<div class="text-xs w-full text-center ellipsize">
|
|
104
104
|
{displayData[item.type].name}
|
|
105
105
|
</div>
|
|
@@ -46,11 +46,12 @@ function clear() {
|
|
|
46
46
|
<Button size="xs" color="light" variant="border" startIcon={{ icon: faEdit }} on:click={edit}>
|
|
47
47
|
Edit
|
|
48
48
|
</Button>
|
|
49
|
-
<Button size="xs" color="light" variant="border" on:click={detach}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
<Button size="xs" color="light" variant="border" on:click={detach}>
|
|
50
|
+
Detach
|
|
51
|
+
<Tooltip>
|
|
52
|
+
Detaching an inline script keep it for later to be reused by another component
|
|
53
|
+
</Tooltip>
|
|
54
|
+
</Button>
|
|
54
55
|
{/if}
|
|
55
56
|
<Button size="xs" color="red" variant="border" startIcon={{ icon: faClose }} on:click={clear}>
|
|
56
57
|
Clear
|
|
@@ -6,7 +6,6 @@ const { connectingInput } = getContext('AppEditorContext');
|
|
|
6
6
|
function applyConnection() {
|
|
7
7
|
if (!$connectingInput.opened &&
|
|
8
8
|
$connectingInput.input !== undefined &&
|
|
9
|
-
componentInput.type === 'connected' &&
|
|
10
9
|
!componentInput.connection) {
|
|
11
10
|
componentInput.connection = $connectingInput.input.connection;
|
|
12
11
|
$connectingInput = {
|
|
@@ -16,56 +15,61 @@ function applyConnection() {
|
|
|
16
15
|
};
|
|
17
16
|
}
|
|
18
17
|
}
|
|
18
|
+
function startConnecting() {
|
|
19
|
+
$connectingInput = {
|
|
20
|
+
opened: true,
|
|
21
|
+
input: undefined,
|
|
22
|
+
hoveredComponent: undefined
|
|
23
|
+
};
|
|
24
|
+
}
|
|
19
25
|
$: $connectingInput && applyConnection();
|
|
20
26
|
</script>
|
|
21
27
|
|
|
22
|
-
{#if componentInput.
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
hoveredComponent: undefined
|
|
64
|
-
}
|
|
28
|
+
{#if componentInput.connection}
|
|
29
|
+
<div class="flex justify-between w-full gap-1">
|
|
30
|
+
<span class="text-xs">Status</span>
|
|
31
|
+
<Badge color="green">Connected</Badge>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="flex justify-between w-full">
|
|
34
|
+
<span class="text-xs">Component</span>
|
|
35
|
+
<Badge color="indigo">{componentInput.connection.componentId}</Badge>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="flex justify-between w-full">
|
|
38
|
+
<span class="text-xs">Path</span>
|
|
39
|
+
<Badge color="indigo">{componentInput.connection.path}</Badge>
|
|
40
|
+
</div>
|
|
41
|
+
<Button
|
|
42
|
+
size="xs"
|
|
43
|
+
startIcon={{ icon: faClose }}
|
|
44
|
+
color="red"
|
|
45
|
+
variant="border"
|
|
46
|
+
on:click={() => {
|
|
47
|
+
if (componentInput.type === 'connected') {
|
|
48
|
+
componentInput.connection = undefined
|
|
49
|
+
}
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
Disconnect
|
|
53
|
+
</Button>
|
|
54
|
+
{:else}
|
|
55
|
+
<div class="flex justify-between w-full gap-1">
|
|
56
|
+
<span class="text-xs">Status</span>
|
|
57
|
+
<Badge color="yellow">Not connected</Badge>
|
|
58
|
+
</div>
|
|
59
|
+
<Button
|
|
60
|
+
size="xs"
|
|
61
|
+
endIcon={{ icon: faArrowRight }}
|
|
62
|
+
color="blue"
|
|
63
|
+
on:click={() => {
|
|
64
|
+
if (componentInput.type === 'connected') {
|
|
65
|
+
$connectingInput = {
|
|
66
|
+
opened: true,
|
|
67
|
+
input: undefined,
|
|
68
|
+
hoveredComponent: undefined
|
|
65
69
|
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
}
|
|
71
|
+
}}
|
|
72
|
+
>
|
|
73
|
+
Connect
|
|
74
|
+
</Button>
|
|
71
75
|
{/if}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ConnectedAppInput } from '../../../inputType';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
|
-
componentInput:
|
|
5
|
+
componentInput: ConnectedAppInput;
|
|
6
6
|
};
|
|
7
7
|
events: {
|
|
8
8
|
[evt: string]: CustomEvent<any>;
|
|
@@ -40,10 +40,12 @@ $: componentInput && onchange?.();
|
|
|
40
40
|
: undefined}
|
|
41
41
|
/>
|
|
42
42
|
{:else}
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
<div class="flex w-full flex-col">
|
|
44
|
+
<JsonEditor
|
|
45
|
+
bind:value={componentInput.value}
|
|
46
|
+
code={JSON.stringify(componentInput.value, null, 2)}
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
47
49
|
{/if}
|
|
48
50
|
{:else if componentInput.fieldType === 'array'}
|
|
49
51
|
<ArrayStaticInputEditor bind:componentInput />
|
|
@@ -41,6 +41,7 @@ export type ResultInput = {
|
|
|
41
41
|
runnable: Runnable;
|
|
42
42
|
fields: Record<string, StaticAppInput | ConnectedAppInput | RowAppInput | UserAppInput>;
|
|
43
43
|
type: 'runnable';
|
|
44
|
+
value?: any;
|
|
44
45
|
};
|
|
45
46
|
type AppInputSpec<T extends InputType, U, V extends InputType = never> = (StaticInput<U> | ConnectedInput | UserInput<U> | RowInput | ResultInput | TemplateInput) & InputConfiguration<T, U, V>;
|
|
46
47
|
type InputConfiguration<T extends InputType, U, V extends InputType> = {
|