mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
* RunsPage redesign v0 * nit * Remove manualdatepicker * remove shadow * ui nits * nit scrollbar bg * prettier cards * nit * Remove code * command/meta multi select * Shift select * RightClickPopover * nit * Ctrl A * nit card * DropdownMenu * nit * count hint * fix stuck keys * opacity UX * error toasts pickhubscript * Improve UX * fix undefined error * keyboard nav * nit batch rerun fixes * nit fix scroll / height * Batch reruns actions + nits * nit * Cancel selected jobs * Cancel / re-run all filtered jobs * Go to job / flow / script action * nit * add batch actions back * nit * nit * bar on splitpane hover * nit * New Timeframe system * reset btn * nit fixes * dead code * nits * typecheck * naming clarity * Update frontend/src/lib/components/RightClickPopover.svelte Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> * unnecessary json stringify * dedup 'the' * Code deletion to prepare for changes * filter types * ui * fix bug with maxTs * stuck with melt * GenericDropdown * filters onclick * iterate * iter * add all filters * Descriptions * focus position * stash * TaggedTextInput works much much better * placeholder * currentTag suggestion * improve * nit * Keyboard nav * buildRunsFilterSearchbarSchema * nit naming * assignObjInPlace * Escaping + pretty dates * nit empty * fix cursor * nit space * Filter filtering * escape pasted value * nit * escape spaces * nit undefined * add space at end if right arrow * escape all spaces * arrow skips escape chars * escape \ too * delete whole escaped characters * double space to escape tag * code refactor * Ensure cursor visible * fix keyboard nav * safety * filterSchemaRecToZodSchema * URL Sync * fix readonly * fix typing * start replacing old filter logic * use new filter impl * nit * nit reactivity * nit fix * no more localStorage * Add back status and kind toggles * Nit fix * style nit * focus at end on click * clearn btn + fixes * fix broken date uri * nit * useSyncedTimeframe * negative filter button * negative filters helpers rust * Negated filters backed * nit * highlight * New useSearchParams * Accept comma separated list * nit allowNegative * openapi update * Fix trigger kind list/negation not working * nit oipenpai * Presets * DebouncedTempValue * remove presets from list when already applied * UI nit improvements * allowMultiple * hint * validateFilterInstance fn * nit fix * error highlights * nit ux selecting negative list * nit * on clear btn * SimpleEditor for JSON * nit * flop * Pass presets as param * nit delete * preventCursorMoveOnNextSync * responsive layout * Escape \n * Inline calendar input * mm/dd or dd/mm depending on US or not * onClickBehavior * infiniteRange * other nits * Wiring with runs filter * formatDateRange better * inits on right page * style * min hour support * Time input * use our components * Improve SKILL.md * dd mm yyyy numeric input * TimeframeSelect with new date picker * fixes * ensure date is in view when value changes externally * fixes * nit select all on focus * select year + nits * nit layout shift * nit negative when starting with ! * nit * SelectDropdown uses GenericDropdown now * Fix blank select dropdown rendering bug * icons * Reset btn + shorter date range formatting * overflow fix * unnecessary absolute * fix clear btn overlap * Update routes for new filters (assets, schedule, resource, variables) * update openapi * Impl for other pages * ui nits * nit fixes * Fix columns filter * super nits --------- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
174 lines
4.5 KiB
Svelte
174 lines
4.5 KiB
Svelte
<script lang="ts">
|
|
import { type RunnableType } from '$lib/gen/index.js'
|
|
import { sendUserToast } from '$lib/utils.js'
|
|
import RunningJobSchemaPicker from '$lib/components/schema/RunningJobSchemaPicker.svelte'
|
|
import { createEventDispatcher, onDestroy } from 'svelte'
|
|
import { useJobsLoader, type UseJobLoaderArgs } from './runs/useJobsLoader.svelte'
|
|
import { DataTable } from '$lib/components/table'
|
|
import HistoricList from './HistoricList.svelte'
|
|
import { Loader2 } from 'lucide-svelte'
|
|
import { workspaceStore } from '$lib/stores'
|
|
|
|
interface Props {
|
|
runnableId?: string | undefined
|
|
runnableType?: RunnableType | undefined
|
|
selected?: string | undefined
|
|
showAuthor?: boolean
|
|
placement?: 'bottom-start' | 'top-start' | 'bottom-end' | 'top-end'
|
|
limitPayloadSize?: boolean
|
|
searchArgs?: Record<string, any> | undefined
|
|
}
|
|
|
|
let {
|
|
runnableId = undefined,
|
|
runnableType = undefined,
|
|
selected = $bindable(undefined),
|
|
showAuthor = false,
|
|
placement = 'top-end',
|
|
limitPayloadSize = false,
|
|
searchArgs = undefined
|
|
}: Props = $props()
|
|
|
|
let historicList: HistoricList | undefined = $state(undefined)
|
|
const dispatch = createEventDispatcher()
|
|
|
|
let hasMoreCurrentRuns = false
|
|
let page = $state(1)
|
|
|
|
async function handleSelected(data: any) {
|
|
if (selected === data.id) {
|
|
resetSelected(true)
|
|
return
|
|
}
|
|
selected = data.id
|
|
if (data.payloadData === 'WINDMILL_TOO_BIG') {
|
|
const fullPayload = await data.getFullPayload?.()
|
|
dispatch('select', { args: fullPayload, jobId: data.id })
|
|
} else {
|
|
dispatch('select', {
|
|
args: structuredClone($state.snapshot(data.payloadData)),
|
|
jobId: data.id
|
|
})
|
|
}
|
|
}
|
|
|
|
export function loading(): boolean {
|
|
return jobsLoader?.loading ?? false
|
|
}
|
|
|
|
onDestroy(() => {
|
|
resetSelected(false)
|
|
})
|
|
|
|
function handleKeydown(event: KeyboardEvent) {
|
|
if (event.key === 'Escape' && selected) {
|
|
resetSelected(true)
|
|
event.stopPropagation()
|
|
event.preventDefault()
|
|
}
|
|
}
|
|
|
|
function handleError(e: { type: string; error: any }) {
|
|
if (e.type === 'load') {
|
|
sendUserToast(`Failed to load input history: ${e.error}`, true)
|
|
}
|
|
}
|
|
|
|
let jobHovered: string | undefined = undefined
|
|
|
|
export function refresh(clearCurrentRuns: boolean = false) {
|
|
historicList?.refresh(clearCurrentRuns)
|
|
}
|
|
|
|
export function resetSelected(dispatchEvent?: boolean) {
|
|
selected = undefined
|
|
if (dispatchEvent) {
|
|
dispatch('select', undefined)
|
|
}
|
|
}
|
|
|
|
function getJobKinds(runnableType: RunnableType | undefined) {
|
|
if (runnableType === 'FlowPath') {
|
|
return 'flow,flowpreview'
|
|
} else if (runnableType === 'ScriptPath') {
|
|
return 'script,preview'
|
|
} else if (runnableType === 'ScriptHash') {
|
|
return 'script,preview'
|
|
}
|
|
return ''
|
|
}
|
|
|
|
let jobsLoader = useJobsLoader(
|
|
() =>
|
|
({
|
|
filters: {
|
|
show_skipped: false,
|
|
path: runnableId,
|
|
status: 'running',
|
|
arg: searchArgs ? JSON.stringify(searchArgs) : ''
|
|
},
|
|
perPage: 5,
|
|
jobKinds: getJobKinds(runnableType),
|
|
syncQueuedRunsCount: false,
|
|
refreshRate: 10000,
|
|
currentWorkspace: $workspaceStore ?? '',
|
|
skip: !runnableId
|
|
}) satisfies UseJobLoaderArgs
|
|
)
|
|
let jobs = $derived(jobsLoader?.jobs ?? [])
|
|
</script>
|
|
|
|
<svelte:window onkeydown={handleKeydown} />
|
|
|
|
<div class="h-full max-h-full min-h-0 w-full flex flex-col gap-2 relative">
|
|
<div class="grow-0" data-schema-picker>
|
|
<DataTable size="xs" bind:currentPage={page} hasMore={hasMoreCurrentRuns} tableFixed={true}>
|
|
{#if jobsLoader?.loading}
|
|
<div class="text-primary absolute top-2 right-2">
|
|
<Loader2 class="animate-spin" size={14} />
|
|
</div>
|
|
{/if}
|
|
{#if jobs.length > 0}
|
|
<colgroup>
|
|
<col class="w-8" />
|
|
<col class="w-16" />
|
|
<col />
|
|
</colgroup>
|
|
|
|
<tbody class="w-full overflow-y-auto">
|
|
{#each jobs as job (job.id)}
|
|
<RunningJobSchemaPicker
|
|
{job}
|
|
selected={selected === job.id}
|
|
hovering={jobHovered === job.id}
|
|
on:select={(e) => handleSelected(e.detail)}
|
|
/>
|
|
{/each}
|
|
{#if jobs.length == 5}
|
|
<tr class="text-left text-primary text-xs w-full">
|
|
<td class="w-full px-2" colspan="3">limited to 5 runs</td>
|
|
</tr>
|
|
{/if}
|
|
</tbody>
|
|
{:else}
|
|
<div class="text-center text-primary text-xs py-2">No job currently running</div>
|
|
{/if}
|
|
</DataTable>
|
|
</div>
|
|
|
|
<div class="min-h-0 grow" data-schema-picker>
|
|
<HistoricList
|
|
bind:this={historicList}
|
|
on:error={(e) => handleError(e.detail)}
|
|
on:select={(e) => handleSelected(e.detail)}
|
|
{runnableId}
|
|
{runnableType}
|
|
{selected}
|
|
{showAuthor}
|
|
{placement}
|
|
{limitPayloadSize}
|
|
{searchArgs}
|
|
/>
|
|
</div>
|
|
</div>
|