windmill-components 1.13.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.
- package/LICENSE +661 -0
- package/common.d.ts +29 -0
- package/components/ArgInfo.svelte +48 -0
- package/components/ArgInput.svelte +277 -0
- package/components/AutosizedTextarea.svelte +34 -0
- package/components/Badge.svelte +12 -0
- package/components/Button.svelte +82 -0
- package/components/ButtonAndDropdown.svelte +25 -0
- package/components/CenteredPage.svelte +5 -0
- package/components/ChevronButton.svelte +21 -0
- package/components/DisplayResult.svelte +101 -0
- package/components/Dropdown.svelte +108 -0
- package/components/Editor.svelte +370 -0
- package/components/FieldHeader.svelte +21 -0
- package/components/FlowBuilder.svelte +202 -0
- package/components/FlowEditor.svelte +95 -0
- package/components/FlowPreview.svelte +141 -0
- package/components/FlowStatusViewer.svelte +137 -0
- package/components/GroupModal.svelte +90 -0
- package/components/IconedResourceType.svelte +32 -0
- package/components/InviteGlobalUser.svelte +56 -0
- package/components/InviteUser.svelte +48 -0
- package/components/ItemPicker.svelte +58 -0
- package/components/JobStatus.svelte +38 -0
- package/components/Modal.svelte +94 -0
- package/components/ModuleStep.svelte +64 -0
- package/components/Multiselect.svelte +327 -0
- package/components/ObjectResourceInput.svelte +62 -0
- package/components/ObjectTypeNarrowing.svelte +25 -0
- package/components/PageHeader.svelte +29 -0
- package/components/Password.svelte +45 -0
- package/components/Path.svelte +129 -0
- package/components/RadioButton.svelte +117 -0
- package/components/Required.svelte +11 -0
- package/components/ResourceEditor.svelte +260 -0
- package/components/ResourcePicker.svelte +21 -0
- package/components/ResourceTypePicker.svelte +71 -0
- package/components/RunForm.svelte +127 -0
- package/components/SchemaEditor.svelte +221 -0
- package/components/SchemaForm.svelte +166 -0
- package/components/SchemaModal.svelte +160 -0
- package/components/SchemaViewer.svelte +76 -0
- package/components/ScriptBuilder.svelte +293 -0
- package/components/ScriptEditor.svelte +669 -0
- package/components/ScriptPicker.svelte +110 -0
- package/components/ScriptSchema.svelte +71 -0
- package/components/ShareModal.svelte +135 -0
- package/components/SharedBadge.svelte +54 -0
- package/components/StringTypeNarrowing.svelte +101 -0
- package/components/Switch.svelte +61 -0
- package/components/TableCustom.svelte +39 -0
- package/components/TableSimple.svelte +66 -0
- package/components/Tabs.svelte +21 -0
- package/components/Tooltip.svelte +93 -0
- package/components/VariableEditor.svelte +159 -0
- package/components/icons/DbIcon.svelte +12 -0
- package/components/icons/Mail.svelte +62 -0
- package/components/icons/Mysql.svelte +77 -0
- package/components/icons/PostgresIcon.svelte +57 -0
- package/components/icons/Slack.svelte +26 -0
- package/gen/core/ApiError.d.ts +8 -0
- package/gen/core/ApiRequestOptions.d.ts +13 -0
- package/gen/core/ApiResult.d.ts +7 -0
- package/gen/core/CancelablePromise.d.ts +26 -0
- package/gen/core/OpenAPI.d.ts +16 -0
- package/gen/core/request.d.ts +13 -0
- package/gen/index.d.ts +59 -0
- package/gen/models/AuditLog.d.ts +32 -0
- package/gen/models/CompletedJob.d.ts +48 -0
- package/gen/models/ContextualVariable.d.ts +5 -0
- package/gen/models/CreateResource.d.ts +6 -0
- package/gen/models/CreateVariable.d.ts +6 -0
- package/gen/models/CreateWorkspace.d.ts +6 -0
- package/gen/models/EditResource.d.ts +5 -0
- package/gen/models/EditResourceType.d.ts +4 -0
- package/gen/models/EditSchedule.d.ts +7 -0
- package/gen/models/EditVariable.d.ts +6 -0
- package/gen/models/EditWorkspaceUser.d.ts +3 -0
- package/gen/models/Flow.d.ts +13 -0
- package/gen/models/FlowModule.d.ts +6 -0
- package/gen/models/FlowModuleValue.d.ts +10 -0
- package/gen/models/FlowPreview.d.ts +7 -0
- package/gen/models/FlowStatus.d.ts +6 -0
- package/gen/models/FlowStatusModule.d.ts +15 -0
- package/gen/models/FlowValue.d.ts +5 -0
- package/gen/models/GlobalUserInfo.d.ts +14 -0
- package/gen/models/Group.d.ts +6 -0
- package/gen/models/InputTransform.d.ts +12 -0
- package/gen/models/Job.d.ts +11 -0
- package/gen/models/ListableVariable.d.ts +8 -0
- package/gen/models/Login.d.ts +4 -0
- package/gen/models/MainArgSignature.d.ts +14 -0
- package/gen/models/NewSchedule.d.ts +9 -0
- package/gen/models/NewToken.d.ts +4 -0
- package/gen/models/NewUser.d.ts +5 -0
- package/gen/models/Preview.d.ts +13 -0
- package/gen/models/QueuedJob.d.ts +47 -0
- package/gen/models/Resource.d.ts +8 -0
- package/gen/models/ResourceType.d.ts +6 -0
- package/gen/models/Schedule.d.ts +13 -0
- package/gen/models/Script.d.ts +29 -0
- package/gen/models/ScriptArgs.d.ts +1 -0
- package/gen/models/TruncatedToken.d.ts +7 -0
- package/gen/models/User.d.ts +10 -0
- package/gen/models/UserWorkspaceList.d.ts +8 -0
- package/gen/models/WorkerPing.d.ts +8 -0
- package/gen/models/Workspace.d.ts +6 -0
- package/gen/models/WorkspaceInvite.d.ts +5 -0
- package/gen/services/AdminService.d.ts +35 -0
- package/gen/services/AuditService.d.ts +37 -0
- package/gen/services/FlowService.d.ts +82 -0
- package/gen/services/GranularAclService.d.ts +42 -0
- package/gen/services/GroupService.d.ts +94 -0
- package/gen/services/JobService.d.ts +217 -0
- package/gen/services/ResourceService.d.ts +116 -0
- package/gen/services/ScheduleService.d.ts +73 -0
- package/gen/services/ScriptService.d.ts +165 -0
- package/gen/services/SettingsService.d.ts +15 -0
- package/gen/services/UserService.d.ts +211 -0
- package/gen/services/VariableService.d.ts +66 -0
- package/gen/services/WorkerService.d.ts +15 -0
- package/gen/services/WorkspaceService.d.ts +137 -0
- package/infer.d.ts +2 -0
- package/lib/components/ArgInfo.svelte.d.ts +16 -0
- package/lib/components/ArgInput.svelte.d.ts +37 -0
- package/lib/components/AutosizedTextarea.svelte.d.ts +19 -0
- package/lib/components/Badge.svelte.d.ts +20 -0
- package/lib/components/Button.svelte.d.ts +23 -0
- package/lib/components/ButtonAndDropdown.svelte.d.ts +23 -0
- package/lib/components/CenteredPage.svelte.d.ts +23 -0
- package/lib/components/ChevronButton.svelte.d.ts +19 -0
- package/lib/components/DisplayResult.svelte.d.ts +16 -0
- package/lib/components/Dropdown.svelte.d.ts +22 -0
- package/lib/components/Editor.svelte.d.ts +38 -0
- package/lib/components/FieldHeader.svelte.d.ts +23 -0
- package/lib/components/FlowBuilder.svelte.d.ts +18 -0
- package/lib/components/FlowEditor.svelte.d.ts +19 -0
- package/lib/components/FlowPreview.svelte.d.ts +21 -0
- package/lib/components/FlowStatusViewer.svelte.d.ts +18 -0
- package/lib/components/GroupModal.svelte.d.ts +17 -0
- package/lib/components/IconedResourceType.svelte.d.ts +19 -0
- package/lib/components/InviteGlobalUser.svelte.d.ts +19 -0
- package/lib/components/InviteUser.svelte.d.ts +19 -0
- package/lib/components/ItemPicker.svelte.d.ts +24 -0
- package/lib/components/JobStatus.svelte.d.ts +17 -0
- package/lib/components/Modal.svelte.d.ts +28 -0
- package/lib/components/ModuleStep.svelte.d.ts +26 -0
- package/lib/components/Multiselect.svelte.d.ts +33 -0
- package/lib/components/ObjectResourceInput.svelte.d.ts +17 -0
- package/lib/components/ObjectTypeNarrowing.svelte.d.ts +16 -0
- package/lib/components/PageHeader.svelte.d.ts +20 -0
- package/lib/components/Password.svelte.d.ts +18 -0
- package/lib/components/Path.svelte.d.ts +26 -0
- package/lib/components/RadioButton.svelte.d.ts +21 -0
- package/lib/components/Required.svelte.d.ts +17 -0
- package/lib/components/ResourceEditor.svelte.d.ts +22 -0
- package/lib/components/ResourcePicker.svelte.d.ts +17 -0
- package/lib/components/ResourceTypePicker.svelte.d.ts +19 -0
- package/lib/components/RunForm.svelte.d.ts +22 -0
- package/lib/components/SchemaEditor.svelte.d.ts +22 -0
- package/lib/components/SchemaForm.svelte.d.ts +23 -0
- package/lib/components/SchemaModal.svelte.d.ts +44 -0
- package/lib/components/SchemaViewer.svelte.d.ts +17 -0
- package/lib/components/ScriptBuilder.svelte.d.ts +20 -0
- package/lib/components/ScriptEditor.svelte.d.ts +28 -0
- package/lib/components/ScriptPicker.svelte.d.ts +21 -0
- package/lib/components/ScriptSchema.svelte.d.ts +22 -0
- package/lib/components/ShareModal.svelte.d.ts +21 -0
- package/lib/components/SharedBadge.svelte.d.ts +17 -0
- package/lib/components/StringTypeNarrowing.svelte.d.ts +18 -0
- package/lib/components/Switch.svelte.d.ts +31 -0
- package/lib/components/TableCustom.svelte.d.ts +25 -0
- package/lib/components/TableSimple.svelte.d.ts +24 -0
- package/lib/components/Tabs.svelte.d.ts +20 -0
- package/lib/components/Tooltip.svelte.d.ts +20 -0
- package/lib/components/VariableEditor.svelte.d.ts +21 -0
- package/lib/components/icons/DbIcon.svelte.d.ts +17 -0
- package/lib/components/icons/Mail.svelte.d.ts +17 -0
- package/lib/components/icons/Mysql.svelte.d.ts +17 -0
- package/lib/components/icons/PostgresIcon.svelte.d.ts +17 -0
- package/lib/components/icons/Slack.svelte.d.ts +17 -0
- package/package.json +110 -0
- package/stores.d.ts +19 -0
- package/utils.d.ts +60 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<script>import { page } from '$app/stores';
|
|
2
|
+
import { getToday } from '../../utils';
|
|
3
|
+
import { slide } from 'svelte/transition';
|
|
4
|
+
import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
|
|
5
|
+
import Icon from 'svelte-awesome';
|
|
6
|
+
import Tooltip from './Tooltip.svelte';
|
|
7
|
+
import SvelteMarkdown from 'svelte-markdown';
|
|
8
|
+
import SchemaForm from './SchemaForm.svelte';
|
|
9
|
+
export let runnable;
|
|
10
|
+
export let runAction;
|
|
11
|
+
export let buttonText = 'Run';
|
|
12
|
+
export let schedulable = true;
|
|
13
|
+
export let detailed = true;
|
|
14
|
+
export let args = {};
|
|
15
|
+
let isValid = true;
|
|
16
|
+
let queryArgs = $page.url.searchParams.get('args');
|
|
17
|
+
if (queryArgs) {
|
|
18
|
+
const parsed = JSON.parse(atob(queryArgs));
|
|
19
|
+
Object.entries(parsed).forEach(([k, v]) => {
|
|
20
|
+
if (v == '<function call>') {
|
|
21
|
+
parsed[k] = undefined;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
console.log(parsed);
|
|
25
|
+
args = parsed;
|
|
26
|
+
}
|
|
27
|
+
// Run later
|
|
28
|
+
let viewOptions = false;
|
|
29
|
+
let scheduledForStr;
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<div class="max-w-5xl">
|
|
33
|
+
{#if detailed}
|
|
34
|
+
<div class="grid grid-cols-3 gap-2">
|
|
35
|
+
<div>
|
|
36
|
+
<h2 class="mb-1">Summary</h2>
|
|
37
|
+
<div class="mb-2 md:mb-3 text-sm">
|
|
38
|
+
{runnable?.summary ? runnable?.summary : 'No summary'}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
<div class="col-span-2">
|
|
42
|
+
<h2 class="mb-1">Description</h2>
|
|
43
|
+
<div class="mb-2 md:mb-6">
|
|
44
|
+
<div class="prose text-sm">
|
|
45
|
+
<SvelteMarkdown
|
|
46
|
+
source={runnable?.description ? runnable?.description : 'No description'}
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
{/if}
|
|
53
|
+
{#if runnable?.schema}
|
|
54
|
+
{#if detailed}
|
|
55
|
+
<h2>
|
|
56
|
+
Arguments<Tooltip class="px-2 mb-6"
|
|
57
|
+
>Optioal fields, if left blank, will use the placeholder value as default.</Tooltip
|
|
58
|
+
>
|
|
59
|
+
</h2>
|
|
60
|
+
{/if}
|
|
61
|
+
{#if !runnable.schema.properties || Object.keys(runnable.schema.properties).length === 0}
|
|
62
|
+
<div class="text-sm">No arguments</div>
|
|
63
|
+
{:else}
|
|
64
|
+
<div
|
|
65
|
+
class="bg-gray-50 border border shadow-md shadow-blue-100 shadow-inner rounded border-gray-300 p-6"
|
|
66
|
+
>
|
|
67
|
+
<SchemaForm schema={runnable.schema} bind:isValid bind:args />
|
|
68
|
+
</div>
|
|
69
|
+
{/if}
|
|
70
|
+
{:else}
|
|
71
|
+
<div class="text-sm">No schema</div>
|
|
72
|
+
{/if}
|
|
73
|
+
{#if viewOptions}
|
|
74
|
+
<div transition:slide class="mt-6">
|
|
75
|
+
<h2>Run later</h2>
|
|
76
|
+
<div class="border rounded-md p-3 pt-4">
|
|
77
|
+
<div class="flex flex-row items-end">
|
|
78
|
+
<div class="w-max md:w-2/3 mt-2 mb-1">
|
|
79
|
+
<label for="run-time" />
|
|
80
|
+
<input
|
|
81
|
+
class="inline-block"
|
|
82
|
+
type="datetime-local"
|
|
83
|
+
id="run-time"
|
|
84
|
+
name="run-scheduled-time"
|
|
85
|
+
bind:value={scheduledForStr}
|
|
86
|
+
min={getToday().toISOString().slice(0, 16)}
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
<button
|
|
90
|
+
class="default-button-secondary mx-2 mb-1"
|
|
91
|
+
on:click={() => {
|
|
92
|
+
scheduledForStr = undefined
|
|
93
|
+
}}>clear</button
|
|
94
|
+
>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
{/if}
|
|
99
|
+
<div class="flex justify-between mt-2 md:mt-6 mb-6">
|
|
100
|
+
<button
|
|
101
|
+
type="submit"
|
|
102
|
+
class="mr-6 text-sm underline text-gray-700 inline-flex items-center"
|
|
103
|
+
on:click={() => {
|
|
104
|
+
viewOptions = !viewOptions
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
{#if schedulable}
|
|
108
|
+
<div>
|
|
109
|
+
schedule to run later <Icon
|
|
110
|
+
data={viewOptions ? faChevronUp : faChevronDown}
|
|
111
|
+
scale={0.5}
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
{/if}
|
|
115
|
+
</button>
|
|
116
|
+
<button
|
|
117
|
+
type="submit"
|
|
118
|
+
disabled={!isValid}
|
|
119
|
+
class="{isValid ? 'default-button' : 'default-button-disabled'} w-min px-6"
|
|
120
|
+
on:click={() => {
|
|
121
|
+
runAction(scheduledForStr, args)
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
{scheduledForStr ? 'Schedule run to a later time' : buttonText}
|
|
125
|
+
</button>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
<script>import SchemaModal, { DEFAULT_PROPERTY, modalToSchema, schemaToModal } from './SchemaModal.svelte';
|
|
2
|
+
import Editor from './Editor.svelte';
|
|
3
|
+
import { emptySchema, sendUserToast } from '../../utils';
|
|
4
|
+
import Tooltip from './Tooltip.svelte';
|
|
5
|
+
import TableCustom from './TableCustom.svelte';
|
|
6
|
+
export let schema = emptySchema();
|
|
7
|
+
let schemaModal;
|
|
8
|
+
let schemaString = '';
|
|
9
|
+
// Internal state: bound to args builder modal
|
|
10
|
+
let modalProperty = Object.assign({}, DEFAULT_PROPERTY);
|
|
11
|
+
let argError = '';
|
|
12
|
+
let editing = false;
|
|
13
|
+
let oldArgName; // when editing argument and changing name
|
|
14
|
+
let viewJsonSchema = false;
|
|
15
|
+
let editor;
|
|
16
|
+
$: schemaString = JSON.stringify(schema, null, '\t');
|
|
17
|
+
export function getEditor() {
|
|
18
|
+
return editor;
|
|
19
|
+
}
|
|
20
|
+
// Binding is not enough because monaco Editor does not support two-way binding
|
|
21
|
+
export function getSchema() {
|
|
22
|
+
if (viewJsonSchema) {
|
|
23
|
+
try {
|
|
24
|
+
schema = JSON.parse(editor.getCode());
|
|
25
|
+
return schema;
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
throw Error(`Error: input is not a valid schema: ${err}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
try {
|
|
33
|
+
editor.setCode(JSON.stringify(schema, null, '\t'));
|
|
34
|
+
return schema;
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
throw Error(`Error: input is not a valid schema: ${err}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function handleAddOrEditArgument() {
|
|
42
|
+
// If editing the arg's name, oldName containing the old argument name must be provided
|
|
43
|
+
argError = '';
|
|
44
|
+
if (modalProperty.name.length === 0) {
|
|
45
|
+
argError = 'Arguments need to have a name';
|
|
46
|
+
}
|
|
47
|
+
else if (Object.keys(schema.properties).includes(modalProperty.name) && !editing) {
|
|
48
|
+
argError = 'There is already an argument with this name';
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
schema.properties[modalProperty.name] = modalToSchema(modalProperty);
|
|
52
|
+
if (modalProperty.required) {
|
|
53
|
+
schema.required = [...schema.required, modalProperty.name];
|
|
54
|
+
}
|
|
55
|
+
else if (schema.required.includes(modalProperty.name)) {
|
|
56
|
+
const index = schema.required.indexOf(modalProperty.name, 0);
|
|
57
|
+
if (index > -1) {
|
|
58
|
+
schema.required.splice(index, 1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (editing && oldArgName && oldArgName !== modalProperty.name) {
|
|
62
|
+
handleDeleteArgument(oldArgName);
|
|
63
|
+
}
|
|
64
|
+
modalProperty = Object.assign({}, DEFAULT_PROPERTY);
|
|
65
|
+
editing = false;
|
|
66
|
+
oldArgName = undefined;
|
|
67
|
+
schemaModal.closeModal();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function startEditArgument(argName) {
|
|
71
|
+
argError = '';
|
|
72
|
+
if (Object.keys(schema.properties).includes(argName)) {
|
|
73
|
+
schemaModal.openModal();
|
|
74
|
+
editing = true;
|
|
75
|
+
modalProperty = schemaToModal(schema.properties[argName], argName, schema.required.includes(argName));
|
|
76
|
+
oldArgName = argName;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
sendUserToast(`This argument does not exist and can't be edited`, true);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function handleDeleteArgument(argName) {
|
|
83
|
+
try {
|
|
84
|
+
if (Object.keys(schema.properties).includes(argName)) {
|
|
85
|
+
delete schema.properties[argName];
|
|
86
|
+
schema = schema; //needed for reactivity, see https://svelte.dev/tutorial/updating-arrays-and-objects
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
throw Error('Argument not found!');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
console.error(err);
|
|
94
|
+
sendUserToast(`Could not delete argument: ${err}`, true);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function switchTab() {
|
|
98
|
+
if (viewJsonSchema) {
|
|
99
|
+
let schemaString = editor.getCode();
|
|
100
|
+
if (schemaString === '') {
|
|
101
|
+
schemaString = JSON.stringify(emptySchema(), null, 4);
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
schema = JSON.parse(schemaString);
|
|
105
|
+
viewJsonSchema = false;
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
sendUserToast(err, true);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
try {
|
|
113
|
+
editor.setCode(JSON.stringify(schema, null, '\t'));
|
|
114
|
+
viewJsonSchema = true;
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
sendUserToast(err, true);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
</script>
|
|
122
|
+
|
|
123
|
+
<div class="flex flex-col">
|
|
124
|
+
<div class="w-full">
|
|
125
|
+
<div class="flex flex-row text-base">
|
|
126
|
+
<button
|
|
127
|
+
class="text-xs sm:text-base py-1 px-6 block hover:text-blue-500 focus:outline-noneborder-gray-200 {viewJsonSchema
|
|
128
|
+
? 'text-gray-500 '
|
|
129
|
+
: 'text-gray-700 font-semibold '}"
|
|
130
|
+
on:click={() => (viewJsonSchema ? switchTab() : null)}
|
|
131
|
+
>
|
|
132
|
+
arguments
|
|
133
|
+
</button><button
|
|
134
|
+
class="py-1 px-6 block hover:text-blue-500 focus:outline-none border-gray-200 {viewJsonSchema
|
|
135
|
+
? 'text-gray-700 font-semibold '
|
|
136
|
+
: 'text-gray-500'}"
|
|
137
|
+
on:click={() => (viewJsonSchema ? null : switchTab())}
|
|
138
|
+
>
|
|
139
|
+
advanced <Tooltip
|
|
140
|
+
>Arguments can be edited either using the wizard, or by editing their json-schema <a
|
|
141
|
+
href="https://docs.windmill.dev/docs/reference/script_arguments_reference">docs</a
|
|
142
|
+
></Tooltip
|
|
143
|
+
>
|
|
144
|
+
</button>
|
|
145
|
+
<button
|
|
146
|
+
class="default-button-secondary grow"
|
|
147
|
+
on:click={() => {
|
|
148
|
+
modalProperty = Object.assign({}, DEFAULT_PROPERTY)
|
|
149
|
+
schemaModal.openModal()
|
|
150
|
+
}}>Add argument</button
|
|
151
|
+
>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
<!--json schema or table view-->
|
|
155
|
+
<div class="border-t py-1 h-full overflow-y-auto">
|
|
156
|
+
<div class="h-full {viewJsonSchema ? 'hidden' : ''}">
|
|
157
|
+
{#if schema.properties && Object.keys(schema.properties).length > 0 && schema.required}
|
|
158
|
+
<TableCustom class="w-full min-h-full">
|
|
159
|
+
<tr slot="header-row" class="underline">
|
|
160
|
+
<th>name</th>
|
|
161
|
+
<th>type</th>
|
|
162
|
+
<th>description</th>
|
|
163
|
+
<th>default</th>
|
|
164
|
+
<th>required</th>
|
|
165
|
+
</tr>
|
|
166
|
+
<tbody slot="body">
|
|
167
|
+
{#each Object.entries(schema.properties) as [name, property] (name)}
|
|
168
|
+
<tr>
|
|
169
|
+
<td>{name}</td>
|
|
170
|
+
<td
|
|
171
|
+
>{#if !property.type} any {:else} {property.type} {/if}</td
|
|
172
|
+
>
|
|
173
|
+
<td>{property.description}</td>
|
|
174
|
+
<td>{JSON.stringify(property.default) ?? ''}</td>
|
|
175
|
+
<td>{schema.required.includes(name) ? 'required' : 'optional'}</td>
|
|
176
|
+
<td class="">
|
|
177
|
+
<button class="mr-2" on:click={() => handleDeleteArgument(name)}
|
|
178
|
+
><svg
|
|
179
|
+
class="w-4 h-4"
|
|
180
|
+
fill="none"
|
|
181
|
+
stroke="currentColor"
|
|
182
|
+
viewBox="0 0 24 14"
|
|
183
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
184
|
+
>
|
|
185
|
+
<path
|
|
186
|
+
stroke-linecap="round"
|
|
187
|
+
stroke-linejoin="round"
|
|
188
|
+
stroke-width="2"
|
|
189
|
+
d="M6 18L18 6M6 6l12 12"
|
|
190
|
+
/>
|
|
191
|
+
</svg></button
|
|
192
|
+
>
|
|
193
|
+
<button
|
|
194
|
+
class="default-button-secondary text-xs inline-flex"
|
|
195
|
+
on:click={() => {
|
|
196
|
+
startEditArgument(name)
|
|
197
|
+
}}>edit</button
|
|
198
|
+
></td
|
|
199
|
+
>
|
|
200
|
+
</tr>
|
|
201
|
+
{/each}
|
|
202
|
+
</tbody>
|
|
203
|
+
</TableCustom>
|
|
204
|
+
{:else}
|
|
205
|
+
<div class="text-gray-700 text-xs italic">This script has no argument</div>
|
|
206
|
+
{/if}
|
|
207
|
+
</div>
|
|
208
|
+
<div class={viewJsonSchema ? '' : 'hidden'}>
|
|
209
|
+
<Editor code={schemaString} bind:this={editor} lang={'json'} class="small-editor" />
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<SchemaModal
|
|
215
|
+
bind:this={schemaModal}
|
|
216
|
+
bind:property={modalProperty}
|
|
217
|
+
bind:error={argError}
|
|
218
|
+
on:save={handleAddOrEditArgument}
|
|
219
|
+
bind:editing
|
|
220
|
+
bind:oldArgName
|
|
221
|
+
/>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<script>import { allTrue } from '../../utils';
|
|
2
|
+
import { slide } from 'svelte/transition';
|
|
3
|
+
import ArgInput from './ArgInput.svelte';
|
|
4
|
+
import RadioButton from './RadioButton.svelte';
|
|
5
|
+
import Editor from './Editor.svelte';
|
|
6
|
+
import FieldHeader from './FieldHeader.svelte';
|
|
7
|
+
import Icon from 'svelte-awesome';
|
|
8
|
+
import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
|
|
9
|
+
export let inputTransform = false;
|
|
10
|
+
export let schema;
|
|
11
|
+
export let args = {};
|
|
12
|
+
export let isValid = true;
|
|
13
|
+
export let editableSchema = false;
|
|
14
|
+
let inputCheck = {};
|
|
15
|
+
let seeHelp = {};
|
|
16
|
+
export function setArgs(nargs) {
|
|
17
|
+
args = nargs;
|
|
18
|
+
}
|
|
19
|
+
$: isValid = allTrue(inputCheck) ?? false;
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<div class="w-full">
|
|
23
|
+
{#if Object.keys(schema?.properties ?? {}).length > 0}
|
|
24
|
+
{#each Object.keys(schema?.properties ?? {}) as argName}
|
|
25
|
+
{#if inputTransform && args[argName] != undefined}
|
|
26
|
+
<div class="mt-10" />
|
|
27
|
+
<FieldHeader
|
|
28
|
+
label={argName}
|
|
29
|
+
format={schema.properties[argName].format}
|
|
30
|
+
contentEncoding={schema.properties[argName].contentEncoding}
|
|
31
|
+
required={schema.required.includes(argName)}
|
|
32
|
+
type={schema.properties[argName].type}
|
|
33
|
+
itemsType={schema.properties[argName].items}
|
|
34
|
+
/>
|
|
35
|
+
<div class="max-w-xs">
|
|
36
|
+
<RadioButton
|
|
37
|
+
options={[
|
|
38
|
+
['Static', 'static'],
|
|
39
|
+
['Dynamic (JS)', 'javascript']
|
|
40
|
+
]}
|
|
41
|
+
small={true}
|
|
42
|
+
bind:value={args[argName].type}
|
|
43
|
+
on:change={(e) => {
|
|
44
|
+
console.log(e.detail)
|
|
45
|
+
args[argName].expr =
|
|
46
|
+
e.detail == 'javascript'
|
|
47
|
+
? `import { previous_result, flow_input, step, variable, resource, params } from 'windmill'
|
|
48
|
+
|
|
49
|
+
previous_result.myfield`
|
|
50
|
+
: undefined
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
{#if args[argName].type == 'static'}
|
|
55
|
+
<ArgInput
|
|
56
|
+
label={argName}
|
|
57
|
+
bind:description={schema.properties[argName].description}
|
|
58
|
+
bind:value={args[argName].value}
|
|
59
|
+
type={schema.properties[argName].type}
|
|
60
|
+
required={schema.required.includes(argName)}
|
|
61
|
+
bind:pattern={schema.properties[argName].pattern}
|
|
62
|
+
bind:valid={inputCheck[argName]}
|
|
63
|
+
defaultValue={schema.properties[argName].default}
|
|
64
|
+
bind:enum_={schema.properties[argName].enum}
|
|
65
|
+
bind:format={schema.properties[argName].format}
|
|
66
|
+
contentEncoding={schema.properties[argName].contentEncoding}
|
|
67
|
+
bind:itemsType={schema.properties[argName].items}
|
|
68
|
+
displayHeader={false}
|
|
69
|
+
/>
|
|
70
|
+
{:else if args[argName].type == 'javascript'}
|
|
71
|
+
{#if args[argName].expr != undefined}
|
|
72
|
+
<div class="border rounded p-2 mt-2 border-gray-500">
|
|
73
|
+
<Editor bind:code={args[argName].expr} lang="typescript" class="few-lines-editor" />
|
|
74
|
+
</div>
|
|
75
|
+
<div class="text-xs flex flex-row-reverse">
|
|
76
|
+
<span
|
|
77
|
+
class="underline mr-4"
|
|
78
|
+
on:click={() => {
|
|
79
|
+
seeHelp[argName] = seeHelp[argName] == undefined ? true : !seeHelp[argName]
|
|
80
|
+
}}
|
|
81
|
+
>Help<Icon
|
|
82
|
+
class="ml-2"
|
|
83
|
+
data={seeHelp[argName] ? faChevronUp : faChevronDown}
|
|
84
|
+
scale={0.7}
|
|
85
|
+
/></span
|
|
86
|
+
>
|
|
87
|
+
</div>
|
|
88
|
+
{#if seeHelp[argName]}
|
|
89
|
+
<div
|
|
90
|
+
transition:slide
|
|
91
|
+
class="bg-gray-100 border-l-4 border-gray-600 text-gray-700 p-4 m-4"
|
|
92
|
+
role="alert"
|
|
93
|
+
>
|
|
94
|
+
<p class="font-bold">Dynamic arg help</p>
|
|
95
|
+
<p>
|
|
96
|
+
When a field is "dynamic", its value is computed dynamically as the evaluation of
|
|
97
|
+
its corresponding typescript snippet.
|
|
98
|
+
</p>
|
|
99
|
+
That snippet can be single line:
|
|
100
|
+
<pre><code>last_result.myarg</code></pre>
|
|
101
|
+
or multiline:
|
|
102
|
+
<pre><code
|
|
103
|
+
>let x = 5;
|
|
104
|
+
x + 2</code
|
|
105
|
+
></pre>
|
|
106
|
+
<p>
|
|
107
|
+
If it is multiline, the last statement before the final expression<b
|
|
108
|
+
>MUST END WITH ; and a newline</b
|
|
109
|
+
>
|
|
110
|
+
</p>
|
|
111
|
+
The snippet can also be a string template:
|
|
112
|
+
<pre><code
|
|
113
|
+
>`Hello ${params.name}, all your base ${previous_result.base_name}
|
|
114
|
+
belong to us`</code
|
|
115
|
+
></pre>
|
|
116
|
+
However, the last line must always be the final expression.
|
|
117
|
+
<p>
|
|
118
|
+
The snippet can use any typescript primitives, and the following flow specific
|
|
119
|
+
objects and functions:
|
|
120
|
+
</p>
|
|
121
|
+
<ul class="ml-4">
|
|
122
|
+
<li>
|
|
123
|
+
<b>previous_result</b>: the object containing the result of the previous step
|
|
124
|
+
</li>
|
|
125
|
+
<li><b>flow_input</b>: the object containing the flow input arguments</li>
|
|
126
|
+
<li><b>params</b>: the object containing the current step static values</li>
|
|
127
|
+
<li>
|
|
128
|
+
<b>step(n)</b>: the function returning the result of step number n. One can also
|
|
129
|
+
use a negative n. step(0) == flow_input , step(-1) == previous_result
|
|
130
|
+
</li>
|
|
131
|
+
<li>
|
|
132
|
+
<b>variable(path)</b>: the function returning the variable (including secrets)
|
|
133
|
+
at given path as a string
|
|
134
|
+
</li>
|
|
135
|
+
<li>
|
|
136
|
+
<b>resource(path)</b>: the function returning the resource at a given path as an
|
|
137
|
+
object
|
|
138
|
+
</li>
|
|
139
|
+
</ul>
|
|
140
|
+
</div>
|
|
141
|
+
{/if}
|
|
142
|
+
{/if}
|
|
143
|
+
{:else}
|
|
144
|
+
<p>Not recognized arg type {args[argName].type}</p>
|
|
145
|
+
{/if}
|
|
146
|
+
{:else}
|
|
147
|
+
<ArgInput
|
|
148
|
+
label={argName}
|
|
149
|
+
bind:description={schema.properties[argName].description}
|
|
150
|
+
bind:value={args[argName]}
|
|
151
|
+
type={schema.properties[argName].type}
|
|
152
|
+
required={schema.required.includes(argName)}
|
|
153
|
+
bind:pattern={schema.properties[argName].pattern}
|
|
154
|
+
bind:valid={inputCheck[argName]}
|
|
155
|
+
defaultValue={schema.properties[argName].default}
|
|
156
|
+
bind:enum_={schema.properties[argName].enum}
|
|
157
|
+
bind:format={schema.properties[argName].format}
|
|
158
|
+
contentEncoding={schema.properties[argName].contentEncoding}
|
|
159
|
+
bind:itemsType={schema.properties[argName].items}
|
|
160
|
+
{editableSchema}
|
|
161
|
+
/>{/if}
|
|
162
|
+
{/each}
|
|
163
|
+
{:else}
|
|
164
|
+
<p class="italic text-sm">No settable input</p>
|
|
165
|
+
{/if}
|
|
166
|
+
</div>
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<script context="module">import Modal from './Modal.svelte';
|
|
2
|
+
export const ARG_TYPES = ['integer', 'number', 'string', 'boolean', 'object', 'array'];
|
|
3
|
+
export function modalToSchema(schema) {
|
|
4
|
+
return {
|
|
5
|
+
type: schema.selectedType,
|
|
6
|
+
description: schema.description,
|
|
7
|
+
pattern: schema.pattern,
|
|
8
|
+
default: schema.default,
|
|
9
|
+
enum: schema.enum_,
|
|
10
|
+
items: schema.items
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function schemaToModal(schema, name, required) {
|
|
14
|
+
return {
|
|
15
|
+
name,
|
|
16
|
+
selectedType: schema.type,
|
|
17
|
+
description: schema.description,
|
|
18
|
+
pattern: schema.pattern,
|
|
19
|
+
default: schema.default,
|
|
20
|
+
required
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export const DEFAULT_PROPERTY = {
|
|
24
|
+
selectedType: 'string',
|
|
25
|
+
description: '',
|
|
26
|
+
name: '',
|
|
27
|
+
required: false
|
|
28
|
+
};
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<script>import Switch from './Switch.svelte';
|
|
32
|
+
import { createEventDispatcher } from 'svelte';
|
|
33
|
+
import ArgInput from './ArgInput.svelte';
|
|
34
|
+
import StringTypeNarrowing from './StringTypeNarrowing.svelte';
|
|
35
|
+
import Required from './Required.svelte';
|
|
36
|
+
export let property = DEFAULT_PROPERTY;
|
|
37
|
+
export let error = '';
|
|
38
|
+
export let editing = false;
|
|
39
|
+
export let oldArgName;
|
|
40
|
+
const dispatch = createEventDispatcher();
|
|
41
|
+
let modal;
|
|
42
|
+
export function openModal() {
|
|
43
|
+
modal.openModal();
|
|
44
|
+
}
|
|
45
|
+
export function closeModal() {
|
|
46
|
+
modal.closeModal();
|
|
47
|
+
}
|
|
48
|
+
function clearModal() {
|
|
49
|
+
error = '';
|
|
50
|
+
editing = false;
|
|
51
|
+
oldArgName = undefined;
|
|
52
|
+
property.name = DEFAULT_PROPERTY.name;
|
|
53
|
+
property.default = DEFAULT_PROPERTY.default;
|
|
54
|
+
property.description = DEFAULT_PROPERTY.description;
|
|
55
|
+
property.required = DEFAULT_PROPERTY.required;
|
|
56
|
+
property.selectedType = DEFAULT_PROPERTY.selectedType;
|
|
57
|
+
}
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<Modal bind:this={modal} on:close={clearModal}>
|
|
61
|
+
<div slot="title">Add an argument</div>
|
|
62
|
+
<div slot="content">
|
|
63
|
+
<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"
|
|
66
|
+
>Name<Required required={true} />
|
|
67
|
+
<input type="text" placeholder="Argument name" class="" bind:value={property.name} />
|
|
68
|
+
</label>
|
|
69
|
+
<label class="mb-2 font-semibold text-gray-700">
|
|
70
|
+
Description
|
|
71
|
+
<textarea
|
|
72
|
+
class="mb-1"
|
|
73
|
+
type="text"
|
|
74
|
+
placeholder="Type message..."
|
|
75
|
+
rows="3"
|
|
76
|
+
bind:value={property.description}
|
|
77
|
+
/>
|
|
78
|
+
</label>
|
|
79
|
+
<h3 class="font-semibold text-gray-700">Type<Required required={true} /></h3>
|
|
80
|
+
<div class="grid sm:grid-cols-3 md:grid-cols-4 gap-x-2 gap-y-1 items-center mb-2">
|
|
81
|
+
{#each ARG_TYPES as argType}
|
|
82
|
+
<button
|
|
83
|
+
class={argType == property.selectedType ? 'item-button-selected' : 'item-button'}
|
|
84
|
+
on:click={() => {
|
|
85
|
+
property.selectedType = argType
|
|
86
|
+
}}>{argType}</button
|
|
87
|
+
>
|
|
88
|
+
{/each}
|
|
89
|
+
<button
|
|
90
|
+
class={!property.selectedType ? 'item-button-selected' : 'item-button'}
|
|
91
|
+
on:click={() => {
|
|
92
|
+
property.selectedType = undefined
|
|
93
|
+
}}>any</button
|
|
94
|
+
>
|
|
95
|
+
</div>
|
|
96
|
+
<Switch
|
|
97
|
+
label={'Required'}
|
|
98
|
+
textFormat={'text-md font-semibold text-gray-700'}
|
|
99
|
+
class="my-2"
|
|
100
|
+
bind:checked={property.required}
|
|
101
|
+
/>
|
|
102
|
+
<ArgInput
|
|
103
|
+
label="Default"
|
|
104
|
+
bind:value={property.default}
|
|
105
|
+
type={property.selectedType}
|
|
106
|
+
pattern={property.pattern}
|
|
107
|
+
/>
|
|
108
|
+
{#if property.selectedType !== 'boolean'}
|
|
109
|
+
<h2 class="mb-2">Advanced</h2>
|
|
110
|
+
|
|
111
|
+
{#if property.selectedType == 'string'}
|
|
112
|
+
<StringTypeNarrowing
|
|
113
|
+
bind:format={property.format}
|
|
114
|
+
bind:pattern={property.pattern}
|
|
115
|
+
bind:enum_={property.enum_}
|
|
116
|
+
/>
|
|
117
|
+
{:else if property.selectedType == 'array'}
|
|
118
|
+
<select bind:value={property.items}>
|
|
119
|
+
<option value={undefined}>No specific item type</option>
|
|
120
|
+
<option value={{ type: 'string' }}> Items are strings</option>
|
|
121
|
+
<option value={{ type: 'number' }}>Items are numbers</option>
|
|
122
|
+
</select>
|
|
123
|
+
{:else}
|
|
124
|
+
<p>No advanced configuration for this type</p>
|
|
125
|
+
{/if}
|
|
126
|
+
{/if}
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<button
|
|
131
|
+
slot="submission"
|
|
132
|
+
class="px-4 py-2 text-white font-semibold bg-blue-500 rounded"
|
|
133
|
+
on:click={() => {
|
|
134
|
+
dispatch('save')
|
|
135
|
+
}}
|
|
136
|
+
>
|
|
137
|
+
Save
|
|
138
|
+
</button>
|
|
139
|
+
</Modal>
|
|
140
|
+
|
|
141
|
+
<style>
|
|
142
|
+
.item-button {
|
|
143
|
+
padding-top: 0.25rem;
|
|
144
|
+
padding-bottom: 0.25rem;
|
|
145
|
+
border-width: 1px;
|
|
146
|
+
border-radius: 0.125rem
|
|
147
|
+
}
|
|
148
|
+
.item-button-selected {
|
|
149
|
+
-webkit-text-decoration-line: underline;
|
|
150
|
+
text-decoration-line: underline;
|
|
151
|
+
font-weight: 700;
|
|
152
|
+
padding-top: 0.25rem;
|
|
153
|
+
padding-bottom: 0.25rem;
|
|
154
|
+
border-width: 1px;
|
|
155
|
+
--tw-border-opacity: 1;
|
|
156
|
+
border-color: rgb(59 130 246 / var(--tw-border-opacity));
|
|
157
|
+
--tw-bg-opacity: 1;
|
|
158
|
+
background-color: rgb(239 246 255 / var(--tw-bg-opacity));
|
|
159
|
+
border-radius: 0.125rem
|
|
160
|
+
}</style>
|