mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-28 00:02:42 +00:00
feat: resource type picker in schema modal + proper initialization of raw javascript editor when applicable
This commit is contained in:
@@ -56,6 +56,7 @@
|
||||
}
|
||||
|
||||
.item-button {
|
||||
@apply cursor-pointer;
|
||||
@apply py-1;
|
||||
@apply border border-gray-300;
|
||||
@apply rounded-sm;
|
||||
|
||||
@@ -290,7 +290,7 @@
|
||||
on:input={() => dispatch('input', { rawValue: value, isRaw: false })}
|
||||
/>
|
||||
{/if}
|
||||
{#if !required}
|
||||
{#if !required && inputCat != 'resource-object'}
|
||||
<div class="flex flex-row-reverse">
|
||||
<button
|
||||
{disabled}
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
export let width = '24px'
|
||||
</script>
|
||||
|
||||
<div class="flex flex-row gap-2">
|
||||
<div class="flex flex-row gap-2 justify-center -pl-2 whitespace-nowrap">
|
||||
{#if !after}
|
||||
{name}
|
||||
{/if}
|
||||
|
||||
{#if name === 'postgresql'}
|
||||
<PostgresIcon {height} {width} />
|
||||
{:else if name === 'mysql'}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import ResourcePicker from './ResourcePicker.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import SchemaForm from './SchemaForm.svelte'
|
||||
import RadioButton from './RadioButton.svelte'
|
||||
import RadioButtonV3 from './RadioButtonV3.svelte'
|
||||
|
||||
export let format: string
|
||||
export let value: any
|
||||
@@ -44,30 +44,34 @@
|
||||
$: format.startsWith('resource-') && loadSchema(format)
|
||||
</script>
|
||||
|
||||
<div class="max-w-lg">
|
||||
<RadioButton
|
||||
options={[
|
||||
[`Resource (${resourceTypeName})`, 'resource'],
|
||||
[`Raw object value`, 'raw']
|
||||
]}
|
||||
small={true}
|
||||
bind:value={option}
|
||||
/>
|
||||
</div>
|
||||
<div class="mt-1" />
|
||||
{#if option == 'resource'}
|
||||
<ResourcePicker
|
||||
bind:value={path}
|
||||
resourceType={format.split('-').length > 1 ? format.substring('resource-'.length) : undefined}
|
||||
/>
|
||||
{:else}
|
||||
<div class="border rounded p-5">
|
||||
<h2 class="mb-5">
|
||||
Object of <a target="_blank" href="/resources">resource type</a>
|
||||
{resourceTypeName}
|
||||
</h2>
|
||||
{#if !isString(args)}
|
||||
<SchemaForm {schema} bind:isValid bind:args />
|
||||
<div class="flex flex-row w-full gap-2">
|
||||
<div class="shrink w-40">
|
||||
<RadioButtonV3
|
||||
options={[
|
||||
[`Resource (${resourceTypeName})`, 'resource'],
|
||||
[`Raw object value`, 'raw']
|
||||
]}
|
||||
bind:value={option}
|
||||
/>
|
||||
</div>
|
||||
<div class="grow">
|
||||
{#if option == 'resource'}
|
||||
<ResourcePicker
|
||||
bind:value={path}
|
||||
resourceType={format.split('-').length > 1
|
||||
? format.substring('resource-'.length)
|
||||
: undefined}
|
||||
/>
|
||||
{:else}
|
||||
<div class="border rounded p-5 w-full">
|
||||
<h2 class="mb-5">
|
||||
Object of <a target="_blank" href="/resources">resource type</a>
|
||||
{resourceTypeName}
|
||||
</h2>
|
||||
{#if !isString(args)}
|
||||
<SchemaForm {schema} bind:isValid bind:args />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,30 +1,14 @@
|
||||
<script lang="ts">
|
||||
import RadioButton from './RadioButton.svelte'
|
||||
import ResourceTypePicker from './ResourceTypePicker.svelte'
|
||||
|
||||
export let format: string | undefined
|
||||
|
||||
let kind: 'resource' | 'none' = format?.startsWith('resource') ? 'resource' : 'none'
|
||||
|
||||
let resource: string | undefined = format?.startsWith('resource-')
|
||||
? format.substring('resource-'.length)
|
||||
: undefined
|
||||
|
||||
$: format =
|
||||
kind == 'resource' ? (resource != undefined ? `resource-${resource}` : 'resource') : undefined
|
||||
$: format = resource != undefined ? `resource-${resource}` : undefined
|
||||
</script>
|
||||
|
||||
<RadioButton
|
||||
label="Kind"
|
||||
small={true}
|
||||
options={[
|
||||
['None', 'none'],
|
||||
['Resource Type', 'resource']
|
||||
]}
|
||||
bind:value={kind}
|
||||
/>
|
||||
|
||||
{#if kind == 'resource'}
|
||||
<div class="mt-1" />
|
||||
<ResourceTypePicker bind:value={resource} />
|
||||
{/if}
|
||||
<div class="mt-2" />
|
||||
<ResourceTypePicker bind:value={resource} nonePickable={true} />
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
<script lang="ts">
|
||||
export let label = ''
|
||||
export let options: [string, any][]
|
||||
export let value: any
|
||||
export let small = false
|
||||
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<fieldset>
|
||||
<legend class="sr-only">{label}</legend>
|
||||
<div class="flex flex-row gap-2">
|
||||
{#each options as [label, val]}
|
||||
<label class:selected={val == value} class={`item-button ${small ? 'py-0' : 'py-3'}`}>
|
||||
<input
|
||||
type="radio"
|
||||
value={val}
|
||||
class="sr-only"
|
||||
bind:group={value}
|
||||
aria-labelledby="memory-option-0-label"
|
||||
on:click={() => dispatch('change', val)}
|
||||
/>
|
||||
<p>{label}</p>
|
||||
</label>
|
||||
{/each}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<style>
|
||||
label {
|
||||
@apply rounded-md px-3 flex items-center justify-center text-sm font-medium uppercase sm:flex-1 cursor-pointer focus:outline-none;
|
||||
}
|
||||
|
||||
label.selected {
|
||||
@apply bg-blue-500/70 text-white rounded-md px-3 flex items-center justify-center text-sm font-medium uppercase sm:flex-1 cursor-pointer focus:outline-none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
export let label = ''
|
||||
export let options: ([string, any] | string)[]
|
||||
export let value: any
|
||||
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<fieldset class="w-full">
|
||||
<legend class="sr-only">{label}</legend>
|
||||
<div class="flex flex-row flex-wrap gap-2 items-center mb-2 w-full">
|
||||
{#each options as [label, val]}
|
||||
<label
|
||||
class:item-button-selected={val == value}
|
||||
class="item-button text-center text-sm h-full p-2 grow"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
value={val}
|
||||
class="sr-only"
|
||||
bind:group={value}
|
||||
aria-labelledby="memory-option-0-label"
|
||||
on:click={() => dispatch('change', val)}
|
||||
/>
|
||||
<p>{label}</p>
|
||||
</label>
|
||||
{/each}
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -10,6 +10,7 @@
|
||||
export let value: string | undefined
|
||||
|
||||
export let notPickable = false
|
||||
export let nonePickable = false
|
||||
|
||||
async function loadResources() {
|
||||
resources = await ResourceService.listResourceTypeNames({ workspace: $workspaceStore! })
|
||||
@@ -25,9 +26,24 @@
|
||||
</script>
|
||||
|
||||
<div class="grid sm:grid-cols-2 md:grid-cols-3 gap-x-2 gap-y-1 items-center mb-2">
|
||||
{#if nonePickable}
|
||||
<button
|
||||
class="px-4 h-8 text-center {undefined == value
|
||||
? 'item-button-selected'
|
||||
: notPickable
|
||||
? 'item-button-disabled'
|
||||
: 'item-button'}"
|
||||
on:click={() => {
|
||||
value = undefined
|
||||
dispatch('click')
|
||||
}}
|
||||
>
|
||||
None
|
||||
</button>
|
||||
{/if}
|
||||
{#each resources as r}
|
||||
<button
|
||||
class="px-4 h-8 {r == value
|
||||
class="px-4 h-8 text-center {r == value
|
||||
? 'item-button-selected'
|
||||
: notPickable
|
||||
? 'item-button-disabled'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import SchemaModal, { DEFAULT_PROPERTY, modalToSchema, schemaToModal } from './SchemaModal.svelte'
|
||||
import SchemaModal, { DEFAULT_PROPERTY, schemaToModal } from './SchemaModal.svelte'
|
||||
import type { ModalSchemaProperty } from './SchemaModal.svelte'
|
||||
import type { Schema } from '$lib/common'
|
||||
import type { Schema, SchemaProperty } from '$lib/common'
|
||||
import Editor from './Editor.svelte'
|
||||
import { emptySchema, sendUserToast, truncate } from '$lib/utils'
|
||||
import Tooltip from './Tooltip.svelte'
|
||||
@@ -38,6 +38,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
function modalToSchema(schema: ModalSchemaProperty): SchemaProperty {
|
||||
return {
|
||||
type: schema.selectedType,
|
||||
description: schema.description,
|
||||
pattern: schema.pattern,
|
||||
default: schema.default,
|
||||
enum: schema.enum_,
|
||||
items: schema.items,
|
||||
contentEncoding: schema.contentEncoding,
|
||||
format: schema.format
|
||||
}
|
||||
}
|
||||
function handleAddOrEditArgument(): void {
|
||||
// If editing the arg's name, oldName containing the old argument name must be provided
|
||||
argError = ''
|
||||
@@ -46,6 +58,7 @@
|
||||
} else if (Object.keys(schema.properties).includes(modalProperty.name) && !editing) {
|
||||
argError = 'There is already an argument with this name'
|
||||
} else {
|
||||
console.log('XXXXXX')
|
||||
schema.properties[modalProperty.name] = modalToSchema(modalProperty)
|
||||
if (modalProperty.required) {
|
||||
schema.required = [...schema.required, modalProperty.name]
|
||||
@@ -72,7 +85,6 @@
|
||||
function startEditArgument(argName: string): void {
|
||||
argError = ''
|
||||
if (Object.keys(schema.properties).includes(argName)) {
|
||||
schemaModal.openModal()
|
||||
editing = true
|
||||
modalProperty = schemaToModal(
|
||||
schema.properties[argName],
|
||||
@@ -80,6 +92,7 @@
|
||||
schema.required.includes(argName)
|
||||
)
|
||||
oldArgName = argName
|
||||
schemaModal.openModal()
|
||||
} else {
|
||||
sendUserToast(`This argument does not exist and can't be edited`, true)
|
||||
}
|
||||
@@ -136,7 +149,7 @@
|
||||
>
|
||||
</button>
|
||||
<button
|
||||
class="default-button-secondary grow"
|
||||
class="default-button-secondary grow mb-1"
|
||||
on:click={() => {
|
||||
modalProperty = Object.assign({}, DEFAULT_PROPERTY)
|
||||
schemaModal.openModal()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
export let inputTransform = false
|
||||
export let schema: Schema
|
||||
export let args: Record<string, InputTransform> = {}
|
||||
export let args: Record<string, InputTransform | any> = {}
|
||||
export let editableSchema = false
|
||||
export let extraLib: string = 'missing extraLib'
|
||||
export let isValid: boolean = true
|
||||
@@ -24,9 +24,38 @@
|
||||
let overlays: { [id: string]: OverlayPropertyPicker } = {}
|
||||
$: isValid = allTrue(inputCheck) ?? false
|
||||
|
||||
let propertiesTypes: { [id: string]: InputTransform.type } = {}
|
||||
let propertiesTypes: { [id: string]: InputTransform.type } = inputTransform
|
||||
? Object.keys(args).reduce((acc, key) => {
|
||||
let type = args[key].type
|
||||
if (type == InputTransform.type.JAVASCRIPT) {
|
||||
if (codeToStaticTemplate(args[key].expr)) {
|
||||
type = InputTransform.type.STATIC
|
||||
}
|
||||
}
|
||||
acc[key] = type
|
||||
return acc
|
||||
}, {})
|
||||
: {}
|
||||
|
||||
let inputCats: { [id: string]: InputCat } = {}
|
||||
|
||||
function codeToStaticTemplate(code?: string): string | undefined {
|
||||
if (!code) return undefined
|
||||
|
||||
const lines = code
|
||||
.split('\n')
|
||||
.slice(1)
|
||||
.filter((x) => x != '')
|
||||
|
||||
if (lines.length == 1) {
|
||||
const line = lines[0].trim()
|
||||
if (line[0] == '`' && line.charAt(line.length - 1) == '`') {
|
||||
return line.slice(1, line.length - 1)
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
function setPropertyType(id: string, rawValue: string, isRaw: boolean) {
|
||||
const arg = args[id]
|
||||
if (!arg) {
|
||||
@@ -53,7 +82,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
function hasOverlay(inputCat: InputCat) {
|
||||
function isStaticTemplate(inputCat: InputCat) {
|
||||
return inputCat === 'string' || inputCat === 'number'
|
||||
}
|
||||
</script>
|
||||
@@ -89,12 +118,19 @@
|
||||
}}
|
||||
bind:value={propertiesTypes[argName]}
|
||||
on:change={(e) => {
|
||||
const staticTemplate = isStaticTemplate(inputCats[argName])
|
||||
if (e.detail === InputTransform.type.JAVASCRIPT) {
|
||||
args[argName].expr = getDefaultExpr(i ?? -1, argName, args[argName].value)
|
||||
args[argName].expr = getDefaultExpr(
|
||||
i ?? -1,
|
||||
argName,
|
||||
staticTemplate ? args[argName].value : undefined
|
||||
)
|
||||
args[argName].value = undefined
|
||||
} else {
|
||||
args[argName].value = staticTemplate
|
||||
? codeToStaticTemplate(args[argName].expr)
|
||||
: undefined
|
||||
args[argName].expr = undefined
|
||||
args[argName].value = undefined
|
||||
}
|
||||
|
||||
args[argName].type = e.detail
|
||||
@@ -107,7 +143,7 @@
|
||||
<OverlayPropertyPicker
|
||||
bind:this={overlays[argName]}
|
||||
bind:pickableProperties
|
||||
disabled={!hasOverlay(inputCats[argName])}
|
||||
disabled={!isStaticTemplate(inputCats[argName])}
|
||||
on:select={(event) => {
|
||||
const toAppend = `\$\{${event.detail}}`
|
||||
args[argName].value = `${args[argName].value ?? ''}${toAppend}`
|
||||
@@ -140,7 +176,7 @@
|
||||
bind:inputCat={inputCats[argName]}
|
||||
numberAsString={true}
|
||||
on:input={(e) => {
|
||||
if (hasOverlay(inputCats[argName])) {
|
||||
if (isStaticTemplate(inputCats[argName])) {
|
||||
setPropertyType(argName, e.detail.rawValue, e.detail.isRaw)
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -18,18 +18,6 @@
|
||||
contentEncoding?: 'base64' | 'binary'
|
||||
}
|
||||
|
||||
export function modalToSchema(schema: ModalSchemaProperty): SchemaProperty {
|
||||
return {
|
||||
type: schema.selectedType,
|
||||
description: schema.description,
|
||||
pattern: schema.pattern,
|
||||
default: schema.default,
|
||||
enum: schema.enum_,
|
||||
items: schema.items,
|
||||
contentEncoding: schema.contentEncoding
|
||||
}
|
||||
}
|
||||
|
||||
export function schemaToModal(
|
||||
schema: SchemaProperty,
|
||||
name: string,
|
||||
@@ -42,6 +30,7 @@
|
||||
pattern: schema.pattern,
|
||||
default: schema.default,
|
||||
contentEncoding: schema.contentEncoding,
|
||||
format: schema.format,
|
||||
required
|
||||
}
|
||||
}
|
||||
@@ -60,17 +49,22 @@
|
||||
import ArgInput from './ArgInput.svelte'
|
||||
import StringTypeNarrowing from './StringTypeNarrowing.svelte'
|
||||
import Required from './Required.svelte'
|
||||
import ResourceTypePicker from './ResourceTypePicker.svelte'
|
||||
import ObjectTypeNarrowing from './ObjectTypeNarrowing.svelte'
|
||||
|
||||
export let property: ModalSchemaProperty = DEFAULT_PROPERTY
|
||||
export let error = ''
|
||||
export let editing = false
|
||||
export let oldArgName: string | undefined = undefined
|
||||
|
||||
let resource_type: string | undefined = undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let modal: Modal
|
||||
|
||||
export function openModal(): void {
|
||||
modal.openModal()
|
||||
resource_type = property.format?.substring(5)
|
||||
}
|
||||
|
||||
export function closeModal(): void {
|
||||
@@ -86,6 +80,12 @@
|
||||
property.description = DEFAULT_PROPERTY.description
|
||||
property.required = DEFAULT_PROPERTY.required
|
||||
property.selectedType = DEFAULT_PROPERTY.selectedType
|
||||
property.format = undefined
|
||||
resource_type = undefined
|
||||
}
|
||||
|
||||
$: if (property.selectedType == 'object' && resource_type) {
|
||||
property.format = resource_type ? `$res:${resource_type}` : undefined
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -109,12 +109,16 @@
|
||||
/>
|
||||
</label>
|
||||
<h3 class="font-semibold text-gray-700">Type<Required required={true} /></h3>
|
||||
<div class="grid sm:grid-cols-3 md:grid-cols-4 gap-x-2 gap-y-1 items-center mb-2">
|
||||
<div class="grid sm:grid-cols-3 md:grid-cols-4 gap-x-2 gap-y-1 items-center mb-2 w-full">
|
||||
{#each ARG_TYPES as argType}
|
||||
<button
|
||||
class={argType == property.selectedType ? 'item-button-selected' : 'item-button'}
|
||||
on:click={() => {
|
||||
property.selectedType = argType
|
||||
property.format = undefined
|
||||
property.contentEncoding = undefined
|
||||
property.enum_ = undefined
|
||||
property.pattern = undefined
|
||||
}}>{argType}</button
|
||||
>
|
||||
{/each}
|
||||
@@ -138,7 +142,7 @@
|
||||
pattern={property.pattern}
|
||||
/>
|
||||
{#if property.selectedType !== 'boolean'}
|
||||
<h2 class="mb-2">Advanced</h2>
|
||||
<h2 class="mb-2 mt-4">Advanced</h2>
|
||||
|
||||
{#if property.selectedType == 'string'}
|
||||
<StringTypeNarrowing
|
||||
@@ -153,6 +157,9 @@
|
||||
<option value={{ type: 'string' }}> Items are strings</option>
|
||||
<option value={{ type: 'number' }}>Items are numbers</option>
|
||||
</select>
|
||||
{:else if property.selectedType == 'object'}
|
||||
<h3 class="mb-2 font-bold mt-4">Resource type</h3>
|
||||
<ObjectTypeNarrowing bind:format={property.format} />
|
||||
{:else}
|
||||
<p>No advanced configuration for this type</p>
|
||||
{/if}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
import ScriptSchema from './ScriptSchema.svelte'
|
||||
import { inferArgs } from '$lib/infer'
|
||||
import Required from './Required.svelte'
|
||||
import RadioButton from './RadioButton.svelte'
|
||||
import { DENO_INIT_CODE, DENO_INIT_CODE_TRIGGER, initialCode } from '$lib/script_helpers'
|
||||
import RadioButtonV3 from './RadioButtonV3.svelte'
|
||||
|
||||
let editor: ScriptEditor
|
||||
let scriptSchema: ScriptSchema
|
||||
@@ -179,9 +179,8 @@
|
||||
</Path>
|
||||
<h3 class="text-gray-700 pb-1 border-b">Language</h3>
|
||||
<div class="max-w-md">
|
||||
<RadioButton
|
||||
<RadioButtonV3
|
||||
label="Language"
|
||||
small={true}
|
||||
options={[
|
||||
['Typescript (Deno)', 'deno'],
|
||||
['Python 3.10', 'python3']
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
import { hubScripts, workspaceStore } from '$lib/stores'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import ItemPicker from './ItemPicker.svelte'
|
||||
import RadioButton from './RadioButton.svelte'
|
||||
import Modal from './Modal.svelte'
|
||||
import { Highlight } from 'svelte-highlight'
|
||||
import { python, typescript } from 'svelte-highlight/languages'
|
||||
|
||||
import github from 'svelte-highlight/styles/github'
|
||||
import { getScriptByPath } from '$lib/utils'
|
||||
import RadioButtonV3 from './RadioButtonV3.svelte'
|
||||
|
||||
export let scriptPath: string | undefined = undefined
|
||||
export let allowFlow = false
|
||||
@@ -67,9 +67,11 @@
|
||||
/>
|
||||
|
||||
<div class="flex flex-row items-center space-x-5">
|
||||
{#if options.length > 1}
|
||||
<RadioButton bind:value={itemKind} {options} />
|
||||
{/if}
|
||||
<div class="w-80">
|
||||
{#if options.length > 1}
|
||||
<RadioButtonV3 bind:value={itemKind} {options} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<input type="text" value={scriptPath ?? 'No path chosen yet'} disabled />
|
||||
<button class="default-button text-gray-100" on:click={() => itemPicker.openModal()}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import RadioButton from './RadioButton.svelte'
|
||||
import RadioButtonV3 from './RadioButtonV3.svelte'
|
||||
import ResourceTypePicker from './ResourceTypePicker.svelte'
|
||||
|
||||
export let pattern: string | undefined
|
||||
@@ -31,9 +31,8 @@
|
||||
$: contentEncoding = kind == 'base64' ? 'base64' : undefined
|
||||
</script>
|
||||
|
||||
<RadioButton
|
||||
<RadioButtonV3
|
||||
label="Kind"
|
||||
small={true}
|
||||
options={[
|
||||
['None', 'none'],
|
||||
['File (base64)', 'base64'],
|
||||
@@ -44,6 +43,7 @@
|
||||
]}
|
||||
bind:value={kind}
|
||||
/>
|
||||
<div class="my-2" />
|
||||
|
||||
{#if kind == 'pattern'}
|
||||
<label for="input" class="mb-2 text-gray-700 text-xs"
|
||||
|
||||
@@ -9,6 +9,16 @@ import type { FlowMode } from './flowStore'
|
||||
export function flowToMode(flow: Flow | any, mode: FlowMode): Flow {
|
||||
if (mode == 'pull') {
|
||||
const newFlow: Flow = JSON.parse(JSON.stringify(flow))
|
||||
newFlow.value.modules.forEach((mod) => {
|
||||
Object.values(mod.input_transform).forEach((inp) => {
|
||||
if (inp.type == InputTransform.type.JAVASCRIPT) {
|
||||
inp.value = undefined
|
||||
} else {
|
||||
inp.expr = undefined
|
||||
|
||||
}
|
||||
})
|
||||
})
|
||||
const triggerModule = newFlow.value.modules[0]
|
||||
const oldModules = newFlow.value.modules.slice(1)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores'
|
||||
import { sendUserToast, displayDate, formatCron } from '$lib/utils'
|
||||
import { sendUserToast, formatCron } from '$lib/utils'
|
||||
import { ScriptService, type Script, ScheduleService, type Flow, FlowService } from '$lib/gen'
|
||||
|
||||
import PageHeader from '$lib/components/PageHeader.svelte'
|
||||
@@ -135,7 +135,7 @@
|
||||
{/if}
|
||||
|
||||
<h2 class="my-2 md:mt-6">Script</h2>
|
||||
<p class="text-xs text-gray-600">
|
||||
<p class="text-xs mb-1 text-gray-600">
|
||||
Pick a script or flow to be triggered by the schedule<Required required={true} />
|
||||
</p>
|
||||
<ScriptPicker isTrigger={false} allowFlow={true} bind:itemKind bind:scriptPath={script_path} />
|
||||
|
||||
Reference in New Issue
Block a user