autoscroll + status viewer auto update
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import github from 'svelte-highlight/styles/github'
|
||||
import { json } from 'svelte-highlight/languages'
|
||||
import TableCustom from './TableCustom.svelte'
|
||||
import { truncate } from '$lib/utils'
|
||||
|
||||
export let result: any
|
||||
|
||||
@@ -65,13 +66,13 @@
|
||||
{#if resultKind == 'table-col'}
|
||||
<div class="grid grid-flow-col-dense border border-gray-200 rounded-md ">
|
||||
{#each Object.keys(result) as col}
|
||||
<div class="flex flex-col min-w-full">
|
||||
<div class="flex flex-col max-h-40 min-w-full overflow-auto">
|
||||
<div class="px-12 text-left uppercase border-b bg-gray-50 overflow-hidden rounded-t-md ">
|
||||
{col}
|
||||
</div>
|
||||
{#if Array.isArray(result[col])}
|
||||
{#each result[col] as item}
|
||||
<div class="px-12 text-left">
|
||||
<div class="px-12 text-left whitespace-nowrap">
|
||||
{typeof item === 'string' ? item : JSON.stringify(item)}
|
||||
</div>
|
||||
{/each}
|
||||
@@ -87,7 +88,7 @@
|
||||
{#each asListOfList(Object.values(result)[0]) as row}
|
||||
<tr>
|
||||
{#each row as v}
|
||||
<td>{v ?? ''}</td>
|
||||
<td>{truncate(v, 200) ?? ''}</td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
})
|
||||
scheduleEnabled = schedule.enabled
|
||||
scheduleCron = schedule.schedule
|
||||
scheduleArgs = scheduleArgs
|
||||
console.log(schedule.enabled, schedule.schedule)
|
||||
scheduleArgs = schedule.args ?? {}
|
||||
console.log(scheduleArgs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<ChevronButton text="logs" viewOptions={true}>
|
||||
<div class="text-xs p-4 bg-gray-50 overflow-auto max-h-lg">
|
||||
<div class="text-xs p-4 bg-gray-50 overflow-auto max-h-80 border mt-1">
|
||||
<pre class="w-full">{job.logs}</pre>
|
||||
</div>
|
||||
</ChevronButton>
|
||||
|
||||
@@ -15,7 +15,27 @@
|
||||
|
||||
let forloop_selected = ''
|
||||
|
||||
function loadResults() {
|
||||
let logs: { [key: number]: string } = {}
|
||||
let pres: { [key: number]: HTMLElement } = {}
|
||||
|
||||
async function loadResults() {
|
||||
if (!('success' in job)) {
|
||||
const mods = job?.flow_status?.modules
|
||||
if (mods) {
|
||||
let i = mods?.findIndex((x) => x.type == FlowStatusModule.type.IN_PROGRESS)
|
||||
if (i != -1) {
|
||||
let last = mods[i]
|
||||
if (last?.type == FlowStatusModule.type.IN_PROGRESS) {
|
||||
logs[i] =
|
||||
(await JobService.getJob({ workspace: $workspaceStore ?? '', id: last.job ?? '' }))
|
||||
.logs ?? ''
|
||||
console.log(logs[i])
|
||||
logs = logs
|
||||
pres[i].scroll({ top: pres[i]?.scrollHeight, behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
job?.flow_status?.modules?.forEach(async (x, i) => {
|
||||
if (
|
||||
(i >= jobs.length && x.type == FlowStatusModule.type.SUCCESS) ||
|
||||
@@ -49,7 +69,7 @@
|
||||
$: $workspaceStore && job && loadResults()
|
||||
</script>
|
||||
|
||||
<div class="flow-root max-w-lg w-full p-4">
|
||||
<div class="flow-root w-full p-4">
|
||||
<div class="flex flex-row-reverse">
|
||||
{#if job}
|
||||
<div class="flex-col">
|
||||
@@ -133,28 +153,33 @@
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
{job.flow_status?.modules[i].type}
|
||||
{#if job.flow_status?.modules[i].forloop_jobs}
|
||||
{#each job.flow_status?.modules[i].forloop_jobs ?? [] as job}
|
||||
<div class="flex flex-col">
|
||||
<a href="/run/{job}" class="font-medium text-blue-600"
|
||||
>{truncateRev(job ?? '', 10)}</a
|
||||
>
|
||||
</div>
|
||||
{/each}
|
||||
{:else if job.flow_status?.modules[i].job}
|
||||
<a href="/run/{job.flow_status?.modules[i].job}" class="font-medium text-blue-600"
|
||||
>{truncateRev(job.flow_status?.modules[i].job ?? '', 10)}</a
|
||||
>
|
||||
{/if}
|
||||
<div class=" max-h-40 overflow-y-auto">
|
||||
{#if job.flow_status?.modules[i].forloop_jobs}
|
||||
{#each job.flow_status?.modules[i].forloop_jobs ?? [] as job}
|
||||
<div class="flex flex-col">
|
||||
<a href="/run/{job}" class="font-medium text-blue-600"
|
||||
>{truncateRev(job ?? '', 10)}</a
|
||||
>
|
||||
</div>
|
||||
{/each}
|
||||
{:else if job.flow_status?.modules[i].job}
|
||||
<a
|
||||
href="/run/{job.flow_status?.modules[i].job}"
|
||||
class="font-medium text-blue-600"
|
||||
>{truncateRev(job.flow_status?.modules[i].job ?? '', 10)}</a
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if jobs[i]}
|
||||
{#if Array.isArray(jobs[i])}
|
||||
<div class="flex flex-col space-y-2">
|
||||
<div class="flex flex-col mt-2 space-y-2 max-h-60 overflow-y-auto shadow-inner">
|
||||
{#each toCompletedJobs(jobs[i]) as job, i}
|
||||
<button
|
||||
class="underline text-blue-600 hover:text-blue-700"
|
||||
class:text-red-600={!job.success}
|
||||
on:click={() => {
|
||||
if (forloop_selected == job.id) {
|
||||
forloop_selected = ''
|
||||
@@ -172,6 +197,15 @@
|
||||
{:else}
|
||||
<FlowJobResult job={toCompletedJob(jobs[i])} />
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="mx-20">
|
||||
<pre
|
||||
bind:this={pres[i]}
|
||||
class="break-all p-4 relative h-full mx-2 bg-gray-50 text-xs max-h-40 overflow-y-auto border">{logs[
|
||||
i
|
||||
] ?? ''}
|
||||
</pre>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -9,22 +9,28 @@
|
||||
export let format: string
|
||||
export let value: any
|
||||
|
||||
console.log(value)
|
||||
function isString(value: any) {
|
||||
return typeof value === 'string' || value instanceof String
|
||||
}
|
||||
|
||||
let path: string =
|
||||
isString(value) && value.length >= '$res:'.length ? value.substr('$res:'.length) : undefined
|
||||
let path: string = ''
|
||||
let args: Record<string, any> = {}
|
||||
|
||||
if (!isString(value) && value) {
|
||||
args = value
|
||||
}
|
||||
|
||||
valueToPath()
|
||||
|
||||
let schema: any | undefined = undefined
|
||||
let isValid = true
|
||||
let resourceTypeName: string = ''
|
||||
|
||||
let option: 'resource' | 'raw' = isString(value) || value == undefined ? 'resource' : 'raw'
|
||||
|
||||
$: format.startsWith('resource-') && loadSchema(format)
|
||||
|
||||
async function loadSchema(format: string) {
|
||||
resourceTypeName = format.substring('resource-'.length)
|
||||
schema = (
|
||||
@@ -32,16 +38,19 @@
|
||||
).schema
|
||||
}
|
||||
|
||||
let option: 'resource' | 'raw' = isString(value) || value == undefined ? 'resource' : 'raw'
|
||||
|
||||
$: {
|
||||
function argToValue() {
|
||||
if (option == 'resource') {
|
||||
value = `$res:${path}`
|
||||
} else {
|
||||
value = args
|
||||
}
|
||||
}
|
||||
$: format.startsWith('resource-') && loadSchema(format)
|
||||
function valueToPath() {
|
||||
path =
|
||||
isString(value) && value.length >= '$res:'.length ? value.substr('$res:'.length) : undefined
|
||||
}
|
||||
|
||||
$: value && valueToPath()
|
||||
</script>
|
||||
|
||||
<div class="flex flex-row w-full gap-2">
|
||||
@@ -51,12 +60,18 @@
|
||||
[`Resource (${resourceTypeName})`, 'resource'],
|
||||
[`Raw object value`, 'raw']
|
||||
]}
|
||||
on:change={argToValue}
|
||||
bind:value={option}
|
||||
/>
|
||||
</div>
|
||||
<div class="grow">
|
||||
{#if option == 'resource'}
|
||||
<ResourcePicker
|
||||
on:refresh={() => loadSchema(format)}
|
||||
on:change={(e) => {
|
||||
path = e.detail
|
||||
argToValue()
|
||||
}}
|
||||
bind:value={path}
|
||||
resourceType={format.split('-').length > 1
|
||||
? format.substring('resource-'.length)
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { type Resource, ResourceService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import ResourceEditor from './ResourceEditor.svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let resources: Resource[] = []
|
||||
|
||||
export let value: string | undefined = undefined
|
||||
export let initialValue: string | undefined = undefined
|
||||
export let value: string | undefined = initialValue
|
||||
export let resourceType: string | undefined = undefined
|
||||
|
||||
let resourceEditor: ResourceEditor
|
||||
|
||||
async function loadResources(resourceType: string | undefined) {
|
||||
const v = value
|
||||
resources = await ResourceService.listResource({ workspace: $workspaceStore!, resourceType })
|
||||
value = v
|
||||
}
|
||||
|
||||
$: {
|
||||
if ($workspaceStore) {
|
||||
loadResources(resourceType)
|
||||
}
|
||||
}
|
||||
$: dispatch('change', value)
|
||||
</script>
|
||||
|
||||
<ResourceEditor bind:this={resourceEditor} on:refresh={() => loadResources(resourceType)} />
|
||||
|
||||
<select class="mt-1" bind:value placeholder="Pick a resource {resourceType}">
|
||||
<option value={undefined} />
|
||||
{#each resources as r}
|
||||
|
||||
@@ -75,6 +75,8 @@
|
||||
return editor
|
||||
}
|
||||
|
||||
let div: HTMLElement | null = null
|
||||
|
||||
export async function runPreview(): Promise<void> {
|
||||
try {
|
||||
if (previewIntervalId) {
|
||||
@@ -145,6 +147,7 @@
|
||||
previewIsLoading = false
|
||||
loadPastPreviews()
|
||||
}
|
||||
div?.scroll({ top: div?.scrollHeight, behavior: 'smooth' })
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
@@ -367,7 +370,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview flex-1 overflow-hidden p-3">
|
||||
<div bind:this={div} class="preview flex-1 overflow-hidden p-3">
|
||||
{#if previewTab === 'logs'}
|
||||
<pre
|
||||
class="break-all relative h-full mx-2">{#if previewJob && previewJob.logs}{previewJob.logs}
|
||||
|
||||
@@ -206,10 +206,12 @@
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class:bg-gray-300={!schedule.enabled}>
|
||||
<div>
|
||||
<div>
|
||||
<h3 class="text-gray-700 ">Schedule</h3>
|
||||
{schedule.schedule}
|
||||
<h3 class="text-gray-700">Schedule</h3>
|
||||
<span class="font-mono p-1 border" class:bg-gray-300={!schedule.enabled}
|
||||
>{schedule.schedule}</span
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-gray-700 ">Args</h3>
|
||||
|
||||
@@ -330,7 +330,9 @@
|
||||
|
||||
{#if job?.job_kind == 'flow' || job?.job_kind == 'flowpreview'}
|
||||
<div class="mt-10" />
|
||||
<FlowStatusViewer {job} bind:jobs />
|
||||
<div class="max-w-lg">
|
||||
<FlowStatusViewer {job} bind:jobs />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user