mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 00:02:23 +00:00
Flow fix property picker (#326)
* Fix property picker * Fix property picker
This commit is contained in:
@@ -41,7 +41,6 @@
|
||||
| { type?: 'string' | 'number' | 'bytes'; contentEncoding?: 'base64' }
|
||||
| undefined = undefined
|
||||
export let displayHeader = true
|
||||
export let numberAsString = false
|
||||
|
||||
let seeEditable: boolean = enum_ != undefined || pattern != undefined
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -188,7 +187,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex space-x-1">
|
||||
{#if inputCat == 'number' && !numberAsString}
|
||||
{#if inputCat == 'number'}
|
||||
<input
|
||||
{disabled}
|
||||
type="number"
|
||||
@@ -303,7 +302,7 @@
|
||||
? format.substring('resource-'.length)
|
||||
: undefined}
|
||||
/>
|
||||
{:else if inputCat == 'string' || (inputCat == 'number' && numberAsString)}
|
||||
{:else if inputCat == 'string'}
|
||||
<textarea
|
||||
on:focus={() => dispatch('focus')}
|
||||
on:blur={() => dispatch('blur')}
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
import FieldHeader from './FieldHeader.svelte'
|
||||
import DynamicInputHelpBox from './flows/DynamicInputHelpBox.svelte'
|
||||
import { codeToStaticTemplate } from './flows/flowStore'
|
||||
import { getCodeInjectionExpr, getDefaultExpr, isCodeInjection } from './flows/utils'
|
||||
import ClickablePropertyPicker from './propertyPicker/ClickablePropertyPicker.svelte'
|
||||
import { getDefaultExpr, isCodeInjection } from './flows/utils'
|
||||
import OverlayPropertyPicker from './propertyPicker/OverlayPropertyPicker.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
|
||||
@@ -39,21 +38,18 @@
|
||||
return type
|
||||
}
|
||||
|
||||
function setPropertyType(id: string, rawValue: string, isRaw: boolean) {
|
||||
function setPropertyType(rawValue: string) {
|
||||
if (!arg) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isCodeInjection(rawValue)) {
|
||||
arg.expr = getCodeInjectionExpr(rawValue, isRaw)
|
||||
arg.expr = getDefaultExpr(i!, argName, `\`${rawValue}\``)
|
||||
arg.type = 'javascript'
|
||||
propertyType = 'static'
|
||||
} else {
|
||||
if (arg.type === 'javascript' && propertyType === 'static') {
|
||||
arg.type = 'static'
|
||||
if (inputCats[id] == 'number') {
|
||||
arg.value = Number(arg.value)
|
||||
}
|
||||
}
|
||||
if (arg.type) {
|
||||
propertyType = arg.type
|
||||
@@ -62,12 +58,12 @@
|
||||
}
|
||||
|
||||
function isStaticTemplate(inputCat: InputCat) {
|
||||
return inputCat === 'string' || inputCat === 'number' || inputCat === 'sql'
|
||||
return inputCat === 'string' || inputCat === 'sql'
|
||||
}
|
||||
|
||||
function focusProp(argName: string) {
|
||||
function focusProp(argName: string, monacoEditor: boolean = false) {
|
||||
Object.keys(overlays).forEach((k) => {
|
||||
if (k == argName) {
|
||||
if (k == argName && (isStaticTemplate(inputCats[argName]) || monacoEditor)) {
|
||||
overlays[k].focus()
|
||||
} else {
|
||||
overlays[k].unfocus()
|
||||
@@ -75,15 +71,13 @@
|
||||
})
|
||||
}
|
||||
|
||||
function onPropertyLink(argName: string, rawValue: string) {
|
||||
function connectProperty(argName: string, rawValue: string) {
|
||||
if (isStaticTemplate(inputCats[argName])) {
|
||||
arg.value = `\$\{${rawValue}}`
|
||||
setPropertyType(argName, arg.value, false)
|
||||
setPropertyType(arg.value)
|
||||
} else {
|
||||
arg.expr = getDefaultExpr(i ?? -1, undefined, rawValue)
|
||||
|
||||
arg.type = 'javascript'
|
||||
|
||||
propertyType = 'javascript'
|
||||
}
|
||||
|
||||
@@ -125,8 +119,9 @@
|
||||
arg.expr = getDefaultExpr(
|
||||
i ?? -1,
|
||||
argName,
|
||||
staticTemplate ? `\`${arg.value ?? ''}\`` : undefined
|
||||
staticTemplate ? `\`${arg.value ?? ''}\`` : arg.value
|
||||
)
|
||||
|
||||
arg.value = undefined
|
||||
propertyType = 'javascript'
|
||||
} else {
|
||||
@@ -144,16 +139,21 @@
|
||||
|
||||
{#if propertyType === undefined || !checked}
|
||||
<OverlayPropertyPicker
|
||||
bind:this={overlays[argName]}
|
||||
{pickableProperties}
|
||||
disabled={!isStaticTemplate(inputCats[argName])}
|
||||
on:select={(event) => {
|
||||
const toAppend = `\$\{${event.detail}}`
|
||||
arg.value = `${arg.value ?? ''}${toAppend}`
|
||||
if (monacos[argName]) {
|
||||
monacos[argName].setCode(arg.value)
|
||||
bind:this={overlays[argName]}
|
||||
on:select={({ detail }) => {
|
||||
if (detail.pickerVariation === 'connect') {
|
||||
connectProperty(argName, detail.propPath)
|
||||
} else {
|
||||
const toAppend = `\$\{${detail.propPath}}`
|
||||
arg.value = `${arg.value ?? ''}${toAppend}`
|
||||
if (monacos[argName]) {
|
||||
monacos[argName].setCode(arg.value)
|
||||
}
|
||||
if (isStaticTemplate(inputCats[argName])) {
|
||||
setPropertyType(arg.value)
|
||||
}
|
||||
}
|
||||
setPropertyType(argName, arg.value, false)
|
||||
}}
|
||||
>
|
||||
<ArgInput
|
||||
@@ -173,24 +173,20 @@
|
||||
bind:itemsType={schema.properties[argName].items}
|
||||
displayHeader={false}
|
||||
bind:inputCat={inputCats[argName]}
|
||||
numberAsString={true}
|
||||
on:input={(e) => {
|
||||
if (isStaticTemplate(inputCats[argName])) {
|
||||
setPropertyType(argName, e.detail.rawValue, e.detail.isRaw)
|
||||
setPropertyType(e.detail.rawValue)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div slot="actions">
|
||||
<ClickablePropertyPicker
|
||||
bind:pickableProperties
|
||||
on:select={(event) => onPropertyLink(argName, event.detail)}
|
||||
>
|
||||
<div on:click={() => overlays[argName]?.focus('connect')}>
|
||||
<Tooltip placement="bottom" content="Input connect">
|
||||
<Button color="blue" size="sm" class="h-8">
|
||||
<Icon data={faChain} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</ClickablePropertyPicker>
|
||||
</div>
|
||||
</div>
|
||||
</ArgInput>
|
||||
</OverlayPropertyPicker>
|
||||
@@ -200,13 +196,13 @@
|
||||
bind:this={overlays[argName]}
|
||||
{pickableProperties}
|
||||
on:select={(event) => {
|
||||
monacos[argName].insertAtCursor(event.detail)
|
||||
monacos[argName].insertAtCursor(event.detail.propPath)
|
||||
}}
|
||||
>
|
||||
<div class="border rounded p-2 mt-2 border-gray-300">
|
||||
<Editor
|
||||
bind:this={monacos[argName]}
|
||||
on:focus={() => focusProp(argName)}
|
||||
on:focus={() => focusProp(argName, true)}
|
||||
bind:code={arg.expr}
|
||||
lang="javascript"
|
||||
class="few-lines-editor"
|
||||
|
||||
@@ -153,17 +153,8 @@ export function isCodeInjection(expr: string | undefined): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
export function getCodeInjectionExpr(code: string, isRaw: boolean): string {
|
||||
let expr = `\`${code}\``
|
||||
if (isRaw) {
|
||||
expr = `JSON.parse(${expr})`
|
||||
}
|
||||
return `import { previous_result, flow_input, step, variable, resource, params } from 'windmill'
|
||||
|
||||
${expr}`
|
||||
}
|
||||
|
||||
export function getDefaultExpr(i: number, key: string = 'myfield', previousExpr?: string) {
|
||||
console.log(key, previousExpr)
|
||||
const expr = previousExpr ?? `previous_result.${key}`
|
||||
return `import { previous_result, flow_input, step, variable, resource, params } from 'windmill@${i}'
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { createPopperActions } from 'svelte-popperjs'
|
||||
import PropPicker from './PropPicker.svelte'
|
||||
|
||||
const [popperRef, popperContent] = createPopperActions({
|
||||
placement: 'bottom-end',
|
||||
strategy: 'fixed'
|
||||
})
|
||||
|
||||
export let pickableProperties: Object | undefined
|
||||
export let disabled = false
|
||||
let isOpen = false
|
||||
|
||||
function toggle() {
|
||||
isOpen = !isOpen
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
{#if !disabled}
|
||||
<div class="w-full">
|
||||
<div use:popperRef on:click={toggle}>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
{#if isOpen}
|
||||
<div class="content" use:popperContent>
|
||||
<PropPicker
|
||||
bind:pickableProperties
|
||||
on:select={(event) => {
|
||||
isOpen = false
|
||||
dispatch('select', event.detail)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<slot />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.content {
|
||||
@apply drop-shadow-xl;
|
||||
@apply w-full;
|
||||
@apply max-w-4xl;
|
||||
@apply px-6;
|
||||
@apply z-50;
|
||||
}
|
||||
</style>
|
||||
@@ -9,17 +9,22 @@
|
||||
})
|
||||
|
||||
export let pickableProperties: Object | undefined
|
||||
export let disabled = false
|
||||
let isOpen = false
|
||||
let isFocused = false
|
||||
|
||||
let timeout: NodeJS.Timeout
|
||||
|
||||
type PickerVariation = 'append' | 'connect'
|
||||
let pickerVariation: PickerVariation = 'append'
|
||||
|
||||
export function unfocus() {
|
||||
isFocused = false
|
||||
close()
|
||||
}
|
||||
export function focus() {
|
||||
export function focus(newPickerVariation?: PickerVariation) {
|
||||
if (newPickerVariation) {
|
||||
pickerVariation = newPickerVariation
|
||||
}
|
||||
isFocused = true
|
||||
open()
|
||||
}
|
||||
@@ -31,40 +36,42 @@
|
||||
}
|
||||
}
|
||||
function close() {
|
||||
if (pickerVariation === 'append') {
|
||||
timeout = setTimeout(() => (isOpen = false), 50)
|
||||
}
|
||||
}
|
||||
|
||||
function closePropertyPicker() {
|
||||
timeout = setTimeout(() => (isOpen = false), 50)
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
{#if !disabled}
|
||||
<div class="w-full">
|
||||
<div use:popperRef on:mouseleave={close}>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
{#if isOpen}
|
||||
<div class="content" use:popperContent on:mouseenter={open} on:mouseleave={close}>
|
||||
<PropPicker
|
||||
bind:pickableProperties
|
||||
on:select={(event) => {
|
||||
isOpen = false
|
||||
dispatch('select', event.detail)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="w-full">
|
||||
<div use:popperRef on:mouseleave={close}>
|
||||
<slot />
|
||||
</div>
|
||||
{:else}
|
||||
<slot />
|
||||
{/if}
|
||||
|
||||
{#if isOpen}
|
||||
<div class="content" use:popperContent on:mouseenter={open} on:mouseleave={closePropertyPicker}>
|
||||
<PropPicker
|
||||
bind:pickableProperties
|
||||
on:select={(event) => {
|
||||
dispatch('select', { propPath: event.detail, pickerVariation })
|
||||
isOpen = false
|
||||
pickerVariation = 'append'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
@apply drop-shadow-xl;
|
||||
@apply w-full;
|
||||
@apply max-w-4xl;
|
||||
|
||||
@apply px-6;
|
||||
@apply z-50;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user