mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 08:01:35 +00:00
app reactivity improvements
This commit is contained in:
@@ -301,6 +301,7 @@ pub struct ListQueueQuery {
|
||||
pub parent_job: Option<String>,
|
||||
pub order_desc: Option<bool>,
|
||||
pub job_kinds: Option<String>,
|
||||
pub suspended: Option<bool>,
|
||||
}
|
||||
|
||||
fn list_queue_jobs_query(w_id: &str, lq: &ListQueueQuery, fields: &[&str]) -> SqlBuilder {
|
||||
@@ -335,6 +336,13 @@ fn list_queue_jobs_query(w_id: &str, lq: &ListQueueQuery, fields: &[&str]) -> Sq
|
||||
if let Some(dt) = &lq.created_after {
|
||||
sqlb.and_where_gt("created_at", format!("to_timestamp({})", dt.timestamp()));
|
||||
}
|
||||
if let Some(s) = &lq.suspended {
|
||||
if *s {
|
||||
sqlb.and_where_is_not_null("suspend");
|
||||
} else {
|
||||
sqlb.and_where_is_null("suspend");
|
||||
}
|
||||
}
|
||||
if let Some(jk) = &lq.job_kinds {
|
||||
sqlb.and_where_in(
|
||||
"job_kind",
|
||||
@@ -378,6 +386,7 @@ async fn list_jobs(
|
||||
parent_job: lq.parent_job,
|
||||
order_desc: Some(true),
|
||||
job_kinds: lq.job_kinds,
|
||||
suspended: lq.suspended,
|
||||
},
|
||||
&[
|
||||
"'QueuedJob' as typ",
|
||||
@@ -1475,6 +1484,7 @@ pub struct ListCompletedQuery {
|
||||
pub job_kinds: Option<String>,
|
||||
pub is_skipped: Option<bool>,
|
||||
pub is_flow_step: Option<bool>,
|
||||
pub suspended: Option<bool>,
|
||||
}
|
||||
|
||||
async fn list_completed_jobs(
|
||||
|
||||
@@ -421,7 +421,7 @@
|
||||
timeoutModel && clearTimeout(timeoutModel)
|
||||
timeoutModel = setTimeout(() => {
|
||||
code = getCode()
|
||||
dispatch('change')
|
||||
dispatch('change', code)
|
||||
}, 500)
|
||||
})
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
})
|
||||
}
|
||||
|
||||
async function inferSchema() {
|
||||
async function inferSchema(code: string) {
|
||||
let isDefault: string[] = []
|
||||
Object.entries(args).forEach(([k, v]) => {
|
||||
if (schema.properties[k].default == v) {
|
||||
@@ -99,7 +99,7 @@
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
inferSchema()
|
||||
inferSchema(code)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -145,20 +145,22 @@
|
||||
<div
|
||||
class="pl-2 h-full !overflow-visible"
|
||||
on:mouseleave={() => {
|
||||
inferSchema()
|
||||
inferSchema(code)
|
||||
}}
|
||||
>
|
||||
<Editor
|
||||
bind:code
|
||||
bind:websocketAlive
|
||||
bind:this={editor}
|
||||
on:change={() => inferSchema()}
|
||||
on:change={(e) => {
|
||||
inferSchema(e.detail)
|
||||
}}
|
||||
cmdEnterAction={async () => {
|
||||
await inferSchema()
|
||||
await inferSchema(code)
|
||||
runTest()
|
||||
}}
|
||||
formatAction={async () => {
|
||||
await inferSchema()
|
||||
await inferSchema(code)
|
||||
localStorage.setItem(path ?? 'last_save', code)
|
||||
lastSave = code
|
||||
}}
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
}
|
||||
})
|
||||
|
||||
args = nargs
|
||||
if (JSON.stringify(args) != JSON.stringify(nargs)) {
|
||||
args = nargs
|
||||
}
|
||||
}
|
||||
|
||||
$: fields && setStaticInputsToArgs()
|
||||
@@ -102,7 +104,8 @@
|
||||
return loadSchema(workspace, path, runType) ?? emptySchema()
|
||||
}
|
||||
|
||||
$: runnable && loadSchemaAndInputsByName()
|
||||
$: runnable?.type === 'runnableByName' && loadSchemaAndInputsByName()
|
||||
$: !schema && runnable?.type === 'runnableByPath' && loadSchemaAndInputsByPath()
|
||||
|
||||
async function loadSchemaAndInputsByName() {
|
||||
if (runnable?.type === 'runnableByName') {
|
||||
@@ -112,7 +115,7 @@
|
||||
const newSchema = inlineScript.schema
|
||||
schema = newSchema
|
||||
|
||||
const newFields = reloadInputs()
|
||||
const newFields = reloadInputs(newSchema)
|
||||
|
||||
if (JSON.stringify(newFields) !== JSON.stringify(fields)) {
|
||||
fields = newFields
|
||||
@@ -142,11 +145,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: !schema && runnable?.type === 'runnableByPath' && loadSchemaAndInputsByPath()
|
||||
|
||||
// When the schema is loaded, we need to update the inputs spec
|
||||
// in order to render the inputs the component panel
|
||||
function reloadInputs() {
|
||||
function reloadInputs(schema: Schema) {
|
||||
let schemaWithoutExtraQueries: Schema = JSON.parse(JSON.stringify(schema))
|
||||
|
||||
// Remove extra query params from the schema, which are not directly configurable by the user
|
||||
@@ -156,7 +157,6 @@
|
||||
|
||||
const result = {}
|
||||
const newInputs = schemaToInputsSpec(schemaWithoutExtraQueries)
|
||||
|
||||
if (!fields) {
|
||||
return newInputs
|
||||
}
|
||||
|
||||
@@ -83,6 +83,14 @@
|
||||
)
|
||||
}
|
||||
|
||||
function renderCell(x: any, props: any) {
|
||||
try {
|
||||
return flexRender(x, props)
|
||||
} catch (e) {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
let filteredResult: Array<Record<string, any>> = []
|
||||
|
||||
$: filteredResult && setOptions(filteredResult)
|
||||
@@ -122,13 +130,17 @@
|
||||
{#each $table.getHeaderGroups() as headerGroup}
|
||||
<tr class="divide-x">
|
||||
{#each headerGroup.headers as header}
|
||||
<th class="px-4 py-4 text-sm font-semibold">
|
||||
{#if !header.isPlaceholder}
|
||||
<svelte:component
|
||||
this={flexRender(header.column.columnDef.header, header.getContext())}
|
||||
/>
|
||||
{#if header?.column?.columnDef?.header}
|
||||
{@const context = header?.getContext()}
|
||||
{#if context}
|
||||
{@const component = renderCell(header.column.columnDef.header, context)}
|
||||
<th class="px-4 py-4 text-sm font-semibold">
|
||||
{#if !header.isPlaceholder && component}
|
||||
<svelte:component this={component} />
|
||||
{/if}
|
||||
</th>
|
||||
{/if}
|
||||
</th>
|
||||
{/if}
|
||||
{/each}
|
||||
{#if actionButtons.length > 0}
|
||||
<th class="px-4 py-4 text-sm font-semibold">Actions</th>
|
||||
@@ -151,14 +163,20 @@
|
||||
)}
|
||||
>
|
||||
{#each row.getVisibleCells() as cell, index (index)}
|
||||
<td
|
||||
on:click={() => toggleRow(row, rowIndex)}
|
||||
class="p-4 whitespace-nowrap text-xs text-gray-900"
|
||||
>
|
||||
<svelte:component
|
||||
this={flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
/>
|
||||
</td>
|
||||
{#if cell?.column?.columnDef?.header}
|
||||
{@const context = cell?.getContext()}
|
||||
{#if context}
|
||||
{@const component = renderCell(cell.column.columnDef.cell, context)}
|
||||
<td
|
||||
on:click={() => toggleRow(row, rowIndex)}
|
||||
class="p-4 whitespace-nowrap text-xs text-gray-900"
|
||||
>
|
||||
{#if component != undefined}
|
||||
<svelte:component this={component} />
|
||||
{/if}
|
||||
</td>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
{#if actionButtons.length > 0}
|
||||
|
||||
+10
-10
@@ -18,6 +18,8 @@
|
||||
export let inlineScript: InlineScript
|
||||
export let name: string | undefined = undefined
|
||||
|
||||
let editor: Editor
|
||||
|
||||
let validCode = false
|
||||
|
||||
async function inferInlineScriptSchema(
|
||||
@@ -48,7 +50,7 @@
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<InlineScriptEditorDrawer bind:this={inlineScriptEditorDrawer} bind:inlineScript />
|
||||
<InlineScriptEditorDrawer {editor} bind:this={inlineScriptEditorDrawer} bind:inlineScript />
|
||||
|
||||
<div class="h-full p-4 flex flex-col gap-2" transition:fly={{ duration: 50 }}>
|
||||
<div class="flex justify-between w-full gap-1 flex-row items-center">
|
||||
@@ -91,20 +93,18 @@
|
||||
|
||||
<div class="border h-full">
|
||||
<Editor
|
||||
bind:this={editor}
|
||||
class="flex flex-1 grow h-full"
|
||||
lang={scriptLangToEditorLang(inlineScript?.language)}
|
||||
bind:code={inlineScript.content}
|
||||
fixedOverflowWidgets={false}
|
||||
on:change={async () => {
|
||||
on:change={async (e) => {
|
||||
if (inlineScript) {
|
||||
let schema = await inferInlineScriptSchema(
|
||||
inlineScript?.language,
|
||||
inlineScript.content,
|
||||
inlineScript.schema
|
||||
)
|
||||
|
||||
inlineScript.schema = schema
|
||||
inlineScript = inlineScript
|
||||
const oldSchema = JSON.stringify(inlineScript.schema)
|
||||
await inferInlineScriptSchema(inlineScript?.language, e.detail, inlineScript.schema)
|
||||
if (JSON.stringify(inlineScript.schema) != oldSchema) {
|
||||
inlineScript = inlineScript
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
+6
-1
@@ -1,11 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { Button, Drawer, DrawerContent } from '$lib/components/common'
|
||||
import type Editor from '$lib/components/Editor.svelte'
|
||||
import ScriptEditor from '$lib/components/ScriptEditor.svelte'
|
||||
import { faSave } from '@fortawesome/free-solid-svg-icons'
|
||||
import type { InlineScript } from '../../types'
|
||||
|
||||
let scriptEditorDrawer: Drawer
|
||||
export let inlineScript: InlineScript
|
||||
export let editor: Editor | undefined = undefined
|
||||
|
||||
export function openDrawer() {
|
||||
scriptEditorDrawer.openDrawer?.()
|
||||
@@ -17,7 +19,10 @@
|
||||
title="Script Editor"
|
||||
noPadding
|
||||
forceOverflowVisible
|
||||
on:close={scriptEditorDrawer.closeDrawer}
|
||||
on:close={() => {
|
||||
scriptEditorDrawer.closeDrawer()
|
||||
editor?.setCode(inlineScript.content)
|
||||
}}
|
||||
>
|
||||
{#if inlineScript}
|
||||
<ScriptEditor
|
||||
|
||||
@@ -203,6 +203,8 @@ export function isScriptByPathDefined(appInput: AppInput | undefined): boolean {
|
||||
|
||||
export function clearResultAppInput(appInput: ResultAppInput): ResultAppInput {
|
||||
appInput.runnable = undefined
|
||||
appInput.fields = {}
|
||||
if (Object.keys(appInput.fields).length > 0) {
|
||||
appInput.fields = {}
|
||||
}
|
||||
return appInput
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import { flowStateStore } from '../flowState'
|
||||
import { schemaToObject, scriptLangToEditorLang } from '$lib/utils'
|
||||
import PropPickerWrapper from '../propPicker/PropPickerWrapper.svelte'
|
||||
import { afterUpdate, getContext, setContext } from 'svelte'
|
||||
import { afterUpdate, getContext } from 'svelte'
|
||||
import type { FlowEditorContext } from '../types'
|
||||
import { loadSchemaFromModule } from '../utils'
|
||||
import FlowModuleScript from './FlowModuleScript.svelte'
|
||||
@@ -181,6 +181,9 @@
|
||||
modulePreview?.runTestWithStepArgs()
|
||||
}}
|
||||
on:change={async (event) => {
|
||||
if (flowModule.value.type === 'rawscript') {
|
||||
flowModule.value.content = event.detail
|
||||
}
|
||||
await reload(flowModule)
|
||||
}}
|
||||
formatAction={() => reload(flowModule)}
|
||||
|
||||
@@ -38,6 +38,7 @@ export async function inferArgs(
|
||||
loadSchemaLastRun.set([code, inferedSchema])
|
||||
}
|
||||
|
||||
|
||||
schema.required = []
|
||||
const oldProperties = Object.assign({}, schema.properties)
|
||||
schema.properties = {}
|
||||
|
||||
Reference in New Issue
Block a user