mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-09 00:04:10 +00:00
* runs on svelte 5 * Line component from svelte-chartjs * Replaced all svelte-chartjs occurrences with custom wrapper * Fix props mistake * Fix illegal table structures * self-closing-tags fix * aria labels * Fixed trivial warnings and errors * @tanstack/svelte-table fix * upgrade to vite 6 * svelte-kit sync before running svelte-check * Remove on:clear which is actually on:removeAll and already handled by on:change * fix worker tags not displaying in Autoscaling * Try to fix svelte-kit sync not working during CI * remove warnings * Fix add flow page crashing * access worldStore before assignment fix * fix infinite recursions in App Editor * Replaced JSON.stringify with proper deepEqual * component mount api changed (no longer classes) * fix ci errors * Fix infinite loops in background runnable panel * factored effect on deep equal logic in onObjChange * fix "Add" not working in AgGrid Table * Replaced legacy component.$set api * Fix multiselect infinite value reaction * Fix flow input fields resetting when opening their edit tab * fix date input resetting when typing year * Remove !p-0 affecting subgrid dotted borders * fix missing debounceTemplate causing hundreds of updates * Fix AgGrid action refreshes and disppearing * resolve getItems generating random ids every rerun * fix cannot access items before init * fix sort lambda arguments being undefined * Revert "Remove !p-0 affecting subgrid dotted borders" This reverts commit c62809bb45d682a48376b071680645ed4e1c601b. * fix input not updating in decision tree editor * Update frontend/src/lib/components/schema/EditableSchemaWrapper.svelte Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * Re-added padding affecting subgrid dotted borders (#5479) * remove !p-0 in preset components * removed extra padding on accordion tabs subgrid * Fix non-reactive SchemaForm * dirty fix for the oneOf bug * Fix warnings and update svelte-exmarkdown for svelte 5 * fix dnd not working * don't mount component like objects --------- Co-authored-by: Diego Imbert <diegoimbert@protonmail.com> Co-authored-by: Diego Imbert <70353967+diegoimbert@users.noreply.github.com> Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
214 lines
6.2 KiB
Svelte
214 lines
6.2 KiB
Svelte
<script lang="ts">
|
|
import SavedInputsPicker from '$lib/components/SavedInputsPicker.svelte'
|
|
import { createEventDispatcher, tick } from 'svelte'
|
|
import HistoricInputs from '$lib/components/HistoricInputs.svelte'
|
|
import { type RunnableType } from '$lib/gen/types.gen.js'
|
|
import { Pane, Splitpanes } from 'svelte-splitpanes'
|
|
import Section from '$lib/components/Section.svelte'
|
|
import SaveInputsButton from '$lib/components/SaveInputsButton.svelte'
|
|
import { Button } from './common'
|
|
import { ExternalLink, Search } from 'lucide-svelte'
|
|
import { Popover } from './meltComponents'
|
|
import SchemaForm from './SchemaForm.svelte'
|
|
import MultiSelect from './multiselect/MultiSelectWrapper.svelte'
|
|
const dispatch = createEventDispatcher()
|
|
|
|
export let scriptHash: string | null = null
|
|
export let scriptPath: string | null = null
|
|
export let flowPath: string | null = null
|
|
export let inputSelected: 'saved' | 'history' | undefined = undefined
|
|
export let jsonView: boolean = false
|
|
export let schema: any
|
|
// Are the current Inputs valid and able to be saved?
|
|
export let isValid: boolean
|
|
export let args: object
|
|
|
|
export function resetSelected() {
|
|
historicInputs?.resetSelected(true)
|
|
savedInputsPicker?.resetSelected(true)
|
|
}
|
|
|
|
let savedArgs: any = undefined
|
|
let runnableType: RunnableType | undefined = undefined
|
|
let savedInputsPicker: SavedInputsPicker | undefined = undefined
|
|
let historicInputs: HistoricInputs | undefined = undefined
|
|
|
|
$: runnableId = scriptHash || scriptPath || flowPath || undefined
|
|
$: runnableType = scriptHash
|
|
? 'ScriptHash'
|
|
: scriptPath
|
|
? 'ScriptPath'
|
|
: flowPath
|
|
? 'FlowPath'
|
|
: undefined
|
|
|
|
function selectArgs(selected_args: any, type: 'saved' | 'history' | undefined) {
|
|
if (selected_args) {
|
|
if (!inputSelected) {
|
|
savedArgs = args
|
|
}
|
|
inputSelected = type
|
|
dispatch('selected_args', selected_args)
|
|
} else if (savedArgs) {
|
|
inputSelected = type
|
|
dispatch('selected_args', savedArgs)
|
|
}
|
|
}
|
|
|
|
let searchArgs = {}
|
|
let appliedSearchArgs = {}
|
|
|
|
let searchArgsFields = [] as string[]
|
|
|
|
$: emptySearchArgs = Object.keys(appliedSearchArgs).length === 0
|
|
|
|
$: filteredSchema = {
|
|
properties: Object.fromEntries(
|
|
Object.entries(schema?.properties ?? {}).filter(([key]) => searchArgsFields.includes(key))
|
|
)
|
|
}
|
|
</script>
|
|
|
|
<div class="min-w-[300px] h-full flex flex-col">
|
|
<Splitpanes horizontal={true}>
|
|
<Pane class="px-4 py-2 h-full">
|
|
<Section
|
|
label="Saved Inputs"
|
|
tooltip="Shared inputs are available to anyone with access to the script"
|
|
wrapperClass="h-full"
|
|
small={true}
|
|
>
|
|
<svelte:fragment slot="action">
|
|
<SaveInputsButton
|
|
{args}
|
|
disabled={!isValid || jsonView}
|
|
{runnableId}
|
|
{runnableType}
|
|
on:update={() => {
|
|
savedInputsPicker?.refresh()
|
|
}}
|
|
/>
|
|
</svelte:fragment>
|
|
|
|
<SavedInputsPicker
|
|
bind:this={savedInputsPicker}
|
|
previewArgs={args}
|
|
{runnableId}
|
|
{runnableType}
|
|
{isValid}
|
|
on:select={(e) => {
|
|
if (e.detail) historicInputs?.resetSelected()
|
|
selectArgs(e.detail, e.detail ? 'saved' : undefined)
|
|
}}
|
|
noButton={true}
|
|
/>
|
|
</Section>
|
|
</Pane>
|
|
|
|
<Pane class="px-4 py-4 h-full">
|
|
<Section label="History" wrapperClass="h-full" small={true}>
|
|
<svelte:fragment slot="action">
|
|
<div class="flex space-x-2">
|
|
<Popover
|
|
class="w-fit"
|
|
usePointerDownOutside
|
|
closeOnOtherPopoverOpen
|
|
on:click={(e) => {
|
|
e.stopPropagation()
|
|
}}
|
|
floatingConfig={{ placement: 'top-end' }}
|
|
>
|
|
<svelte:fragment slot="trigger">
|
|
<Button
|
|
variant="contained"
|
|
size="xs2"
|
|
color={emptySearchArgs ? 'light' : 'dark'}
|
|
nonCaptureEvent
|
|
title="Search history"
|
|
iconOnly={emptySearchArgs}
|
|
endIcon={{ icon: Search }}
|
|
>
|
|
{emptySearchArgs ? '' : 'Active filters'}
|
|
</Button>
|
|
</svelte:fragment>
|
|
|
|
<svelte:fragment slot="content">
|
|
<div id="multi-select-search"></div>
|
|
<div class="p-2 overflow-auto max-h-[400px] min-h-[300px] w-[400px]">
|
|
<div class="flex items-center flex-wrap gap-x-2 justify-between">
|
|
<div class="text-sm text-secondary">Search by args</div>
|
|
<div class="flex flex-wrap gap-x-2">
|
|
{#if !emptySearchArgs}
|
|
<Button
|
|
on:click={async () => {
|
|
searchArgs = {}
|
|
appliedSearchArgs = {}
|
|
await tick()
|
|
historicInputs?.refresh(true)
|
|
}}
|
|
variant="contained"
|
|
size="xs2"
|
|
color="light">Reset filters</Button
|
|
>
|
|
{/if}
|
|
<Button
|
|
on:click={async () => {
|
|
appliedSearchArgs = structuredClone(searchArgs)
|
|
await tick()
|
|
historicInputs?.refresh(true)
|
|
}}
|
|
endIcon={{ icon: Search }}
|
|
variant="contained"
|
|
size="xs2"
|
|
color="dark">Search</Button
|
|
>
|
|
</div>
|
|
</div>
|
|
<div class="my-2">
|
|
<MultiSelect
|
|
topPlacement
|
|
target="#multi-select-search"
|
|
placeholder="arg fields to filter on"
|
|
items={Object.keys(schema?.properties ?? {})}
|
|
bind:value={searchArgsFields}
|
|
/>
|
|
</div>
|
|
{#key filteredSchema}
|
|
<SchemaForm shouldHideNoInputs schema={filteredSchema} bind:args={searchArgs} />
|
|
{/key}
|
|
{#if searchArgsFields.length === 0}
|
|
<div class="text-secondary text-sm my-8 mx-auto">No filters</div>
|
|
{/if}
|
|
</div>
|
|
</svelte:fragment>
|
|
</Popover>
|
|
<Button
|
|
size="xs2"
|
|
color="light"
|
|
btnClasses="!text-tertiary"
|
|
endIcon={{ icon: ExternalLink }}
|
|
on:click={() => {
|
|
window.open(`/runs/${runnableId}`, '_blank')
|
|
}}
|
|
>
|
|
All runs
|
|
</Button>
|
|
</div>
|
|
</svelte:fragment>
|
|
<HistoricInputs
|
|
bind:this={historicInputs}
|
|
{runnableId}
|
|
{runnableType}
|
|
on:select={(e) => {
|
|
if (e.detail) savedInputsPicker?.resetSelected()
|
|
selectArgs(e.detail?.args, e.detail ? 'history' : undefined)
|
|
}}
|
|
searchArgs={emptySearchArgs ? undefined : appliedSearchArgs}
|
|
showAuthor
|
|
placement="top-end"
|
|
/>
|
|
</Section>
|
|
</Pane>
|
|
</Splitpanes>
|
|
</div>
|