mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 08:01:35 +00:00
pass workspace as query arg of every runs link
This commit is contained in:
@@ -710,7 +710,10 @@ async fn slack_command(
|
||||
.await?;
|
||||
tx.commit().await?;
|
||||
let url = base_url.0.to_owned();
|
||||
return Ok(format!("Job launched. See details at {url}/run/{uuid}"));
|
||||
return Ok(format!(
|
||||
"Job launched. See details at {url}/run/{uuid}?workspace={}",
|
||||
&settings.workspace_id
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-gray-700 text-2xs pt-2">
|
||||
run id: <a href={`/run/${job.id}`}>{job.id}</a>
|
||||
run id: <a href={`/run/${job.id}?workspace=${job.workspace_id}`}>{job.id}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
} from 'chart.js'
|
||||
import type { CompletedJob } from '$lib/gen'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { json } from 'svelte-highlight/languages'
|
||||
|
||||
export let jobs: CompletedJob[] | undefined = []
|
||||
|
||||
@@ -43,13 +44,16 @@
|
||||
// borderColor: 'rgba(99,0,125, .2)',
|
||||
backgroundColor: '#f87171',
|
||||
label: 'Failed',
|
||||
data: failed?.map((job) => ({ x: job.created_at as any, y: job.duration_ms })) ?? []
|
||||
data:
|
||||
failed?.map((job) => ({ x: job.created_at as any, y: job.duration_ms, id: job.id })) ?? []
|
||||
},
|
||||
{
|
||||
// borderColor: 'rgba(99,0,125, .2)',
|
||||
backgroundColor: '#4ade80',
|
||||
label: 'Successful',
|
||||
data: success?.map((job) => ({ x: job.created_at as any, y: job.duration_ms })) ?? []
|
||||
data:
|
||||
success?.map((job) => ({ x: job.created_at as any, y: job.duration_ms, id: job.id })) ??
|
||||
[]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -83,8 +87,24 @@
|
||||
zoom: zoomOptions,
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function (context) {
|
||||
let label = context.dataset.label || 'X'
|
||||
|
||||
if (label) {
|
||||
label += ': '
|
||||
}
|
||||
if (context.parsed.y !== null) {
|
||||
label += JSON.stringify(context.parsed)
|
||||
}
|
||||
return label
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
scales: {
|
||||
x: {
|
||||
grid: {
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
|
||||
export let isLoading = false
|
||||
export let job: Job | undefined = undefined
|
||||
export let workspaceOverride: string | undefined = undefined
|
||||
export let notfound = false
|
||||
|
||||
$: workspace = workspaceOverride ?? $workspaceStore
|
||||
let intervalId: NodeJS.Timer
|
||||
|
||||
let syncIteration: number = 0
|
||||
@@ -27,7 +30,7 @@
|
||||
intervalId && clearInterval(intervalId)
|
||||
if (isLoading && job) {
|
||||
JobService.cancelQueuedJob({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: workspace!,
|
||||
id: job.id,
|
||||
requestBody: {}
|
||||
})
|
||||
@@ -35,7 +38,7 @@
|
||||
isLoading = true
|
||||
|
||||
const testId = await JobService.runScriptPreview({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: workspace!,
|
||||
requestBody: {
|
||||
path,
|
||||
content: code,
|
||||
@@ -78,7 +81,7 @@
|
||||
try {
|
||||
if (job && `running` in job) {
|
||||
let previewJobUpdates = await JobService.getJobUpdates({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: workspace!,
|
||||
id,
|
||||
running: job.running,
|
||||
logOffset: job.logs?.length ?? 0
|
||||
@@ -88,21 +91,29 @@
|
||||
job.logs = (job.logs ?? '').concat(previewJobUpdates.new_logs)
|
||||
}
|
||||
if ((previewJobUpdates.running ?? false) || (previewJobUpdates.completed ?? false)) {
|
||||
job = await JobService.getJob({ workspace: $workspaceStore!, id })
|
||||
job = await JobService.getJob({ workspace: workspace!, id })
|
||||
}
|
||||
} else {
|
||||
job = await JobService.getJob({ workspace: $workspaceStore!, id })
|
||||
console.log(workspaceOverride)
|
||||
console.log(workspace)
|
||||
|
||||
job = await JobService.getJob({ workspace: workspace!, id })
|
||||
}
|
||||
if (job?.type === 'CompletedJob') {
|
||||
//only CompletedJob has success property
|
||||
isCompleted = true
|
||||
clearInterval(intervalId)
|
||||
intervalId && clearInterval(intervalId)
|
||||
if (isLoading) {
|
||||
dispatch('done', job)
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
notfound = false
|
||||
} catch (err) {
|
||||
intervalId && clearInterval(intervalId)
|
||||
if (err.status === 404) {
|
||||
notfound = true
|
||||
}
|
||||
console.error(err)
|
||||
}
|
||||
return isCompleted
|
||||
|
||||
@@ -89,13 +89,15 @@
|
||||
<div class="flex flex-row space-x-2">
|
||||
<div class="whitespace-nowrap">
|
||||
{#if job.script_path}
|
||||
<a href="/run/{job.id}">{job.script_path} </a>
|
||||
<a href="/run/{job.id}?workspace={job.workspace_id}">{job.script_path} </a>
|
||||
{:else if 'job_kind' in job && job.job_kind == 'preview'}
|
||||
<a href="/run/{job.id}">Preview without path </a>
|
||||
<a href="/run/{job.id}?workspace={job.workspace_id}">Preview without path </a>
|
||||
{:else if 'job_kind' in job && job.job_kind == 'dependencies'}
|
||||
<a href="/run/{job.id}">lock deps of {truncateHash(job.script_hash ?? '')}</a>
|
||||
<a href="/run/{job.id}?workspace={job.workspace_id}"
|
||||
>lock deps of {truncateHash(job.script_hash ?? '')}</a
|
||||
>
|
||||
{:else if 'job_kind' in job && job.job_kind == 'identity'}
|
||||
<a href="/run/{job.id}">no op</a>
|
||||
<a href="/run/{job.id}?workspace={job.workspace_id}">no op</a>
|
||||
{/if}
|
||||
<button
|
||||
class="ml-1"
|
||||
@@ -109,8 +111,10 @@
|
||||
><Badge color="blue">{job.job_kind}</Badge></a
|
||||
>
|
||||
{/if}
|
||||
{#if (job.is_flow_step && job.job_kind == 'script') || job.job_kind == 'preview'}
|
||||
<a href="/run/{job.parent_job}"><Badge color="gray">flow step</Badge></a>
|
||||
{#if job.is_flow_step && (job.job_kind == 'script' || job.job_kind == 'preview')}
|
||||
<a href="/run/{job.parent_job}?workspace={job.workspace_id}"
|
||||
><Badge color="gray">flow step</Badge></a
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
Job Id
|
||||
</th>
|
||||
<td class="py-2">
|
||||
<a rel="noreferrer" target="_blank" href="/run/{job?.id}">
|
||||
<a rel="noreferrer" target="_blank" href="/run/{job?.id}?workspace={job?.workspace_id}">
|
||||
{job?.id}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@@ -161,7 +161,9 @@
|
||||
|
||||
<div class="mt-4 flex flex-row flex-wrap justify-between"
|
||||
><a href="https://windmill.dev">Learn more about Windmill</a>
|
||||
<a target="_blank" href="/run/{job?.id}">Flow run details (require auth)</a>
|
||||
<a target="_blank" rel="noreferrer" href="/run/{job?.id}?workspace={job?.workspace_id}"
|
||||
>Flow run details (require auth)</a
|
||||
>
|
||||
</div>
|
||||
{#if job && job.raw_flow}
|
||||
<h2 class="mt-10">Flow details</h2>
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
requestBody: args,
|
||||
scheduledFor
|
||||
})
|
||||
sendUserToast(`Job <a href='/run/${run}'>${run}</a> started`)
|
||||
goto('/run/' + run)
|
||||
sendUserToast(`Job <a href='/run/${run}?workspace=${$workspaceStore}'>${run}</a> started`)
|
||||
goto('/run/' + run + '?workspace=' + $workspaceStore)
|
||||
}
|
||||
|
||||
$: {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
faFastForward
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import DisplayResult from '$lib/components/DisplayResult.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { userStore, usersWorkspaceStore, workspaceStore } from '$lib/stores'
|
||||
import CenteredPage from '$lib/components/CenteredPage.svelte'
|
||||
import FlowStatusViewer from '$lib/components/FlowStatusViewer.svelte'
|
||||
import HighlightCode from '$lib/components/HighlightCode.svelte'
|
||||
@@ -39,8 +39,7 @@
|
||||
import Tabs from '$lib/components/common/tabs/Tabs.svelte'
|
||||
import Badge from '$lib/components/common/badge/Badge.svelte'
|
||||
|
||||
let workspace_id_query: string | undefined = $page.url.searchParams.get('workspace') ?? undefined
|
||||
let workspace_id: string | undefined
|
||||
$: workspace_id = $page.url.searchParams.get('workspace') ?? $workspaceStore
|
||||
|
||||
let job: Job | undefined
|
||||
const iconScale = 1
|
||||
@@ -83,11 +82,11 @@
|
||||
}
|
||||
|
||||
$: {
|
||||
if ($workspaceStore && $page.params.run && testJobLoader) {
|
||||
workspace_id = workspace_id_query ?? $workspaceStore
|
||||
if (workspace_id && $page.params.run && testJobLoader) {
|
||||
getLogs()
|
||||
}
|
||||
}
|
||||
let notfound = false
|
||||
</script>
|
||||
|
||||
<TestJobLoader
|
||||
@@ -95,205 +94,232 @@
|
||||
bind:this={testJobLoader}
|
||||
bind:isLoading={testIsLoading}
|
||||
bind:job
|
||||
workspaceOverride={workspace_id}
|
||||
bind:notfound
|
||||
/>
|
||||
|
||||
<Skeleton
|
||||
class="!max-w-6xl !px-4 sm:!px-6 md:!px-8"
|
||||
loading={!job}
|
||||
layout={[0.75, [2, 0, 2], 2.25, [{ h: 1.5, w: 40 }]]}
|
||||
/>
|
||||
{#if job?.job_kind === 'script' || job?.job_kind === 'flow'}
|
||||
<ActionRow applyPageWidth stickToTop>
|
||||
<svelte:fragment slot="left">
|
||||
{@const isScript = job?.job_kind === 'script'}
|
||||
{@const runsHref = `/runs/${job?.script_path}${!isScript ? '?jobKind=flow' : ''}`}
|
||||
{#if job && 'deleted' in job && !job?.deleted && ($userStore?.is_admin ?? false)}
|
||||
{#if notfound}
|
||||
<CenteredPage>
|
||||
<div class="flex flex-col gap-6">
|
||||
<h1 class="text-red-400 mt-6">Job {$page.params.run} not found in {workspace_id}</h1>
|
||||
<h2>Are you in the right workspace?</h2>
|
||||
<div class="flex flex-col gap-2">
|
||||
{#each $usersWorkspaceStore?.workspaces ?? [] as workspace}
|
||||
<div
|
||||
><Button variant="border" href="/run/{$page.params.run}?workspace={workspace.id}"
|
||||
>See in {workspace.name}</Button
|
||||
></div
|
||||
>
|
||||
{/each}
|
||||
<div>
|
||||
<Button href="/runs">Go to runs page</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CenteredPage>
|
||||
{:else}
|
||||
<Skeleton
|
||||
class="!max-w-6xl !px-4 sm:!px-6 md:!px-8"
|
||||
loading={!job}
|
||||
layout={[0.75, [2, 0, 2], 2.25, [{ h: 1.5, w: 40 }]]}
|
||||
/>
|
||||
{#if job?.job_kind === 'script' || job?.job_kind === 'flow'}
|
||||
<ActionRow applyPageWidth stickToTop>
|
||||
<svelte:fragment slot="left">
|
||||
{@const isScript = job?.job_kind === 'script'}
|
||||
{@const runsHref = `/runs/${job?.script_path}${!isScript ? '?jobKind=flow' : ''}`}
|
||||
{#if job && 'deleted' in job && !job?.deleted && ($userStore?.is_admin ?? false)}
|
||||
<Button
|
||||
variant="border"
|
||||
color="red"
|
||||
size="xs"
|
||||
startIcon={{ icon: faTrash }}
|
||||
on:click={() => job?.id && deleteCompletedJob(job.id)}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
<Button
|
||||
href={runsHref}
|
||||
variant="border"
|
||||
color="blue"
|
||||
size="xs"
|
||||
startIcon={{ icon: faList }}
|
||||
>
|
||||
View runs
|
||||
</Button>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="right">
|
||||
{@const stem = `/${job?.job_kind}s`}
|
||||
{@const isScript = job?.job_kind === 'script'}
|
||||
{@const route = isScript ? job?.script_hash : job?.script_path}
|
||||
{@const runHref = `${stem}/run/${route}${
|
||||
job?.args ? '?args=' + encodeURIComponent(encodeState(job?.args)) : ''
|
||||
}`}
|
||||
{@const editHref = `${stem}/edit/${route}${
|
||||
isScript
|
||||
? `?step=2${job?.args ? `&args=${encodeURIComponent(encodeState(job?.args))}` : ''}`
|
||||
: `${job?.args ? `?args=${encodeURIComponent(encodeState(job?.args))}` : ''}`
|
||||
}`}
|
||||
{@const isRunning = job && 'running' in job && job.running}
|
||||
{@const viewHref = `${stem}/get/${isScript ? job?.script_hash : job?.script_path}`}
|
||||
{#if isRunning}
|
||||
<Button
|
||||
color="red"
|
||||
size="xs"
|
||||
startIcon={{ icon: faTimesCircle }}
|
||||
on:click|once={() => {
|
||||
if (job?.id) {
|
||||
cancelJob(job?.id)
|
||||
}
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
{/if}
|
||||
<Button
|
||||
variant="border"
|
||||
color="red"
|
||||
size="xs"
|
||||
startIcon={{ icon: faTrash }}
|
||||
on:click={() => job?.id && deleteCompletedJob(job.id)}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
<Button
|
||||
href={runsHref}
|
||||
variant="border"
|
||||
href={runHref}
|
||||
disabled={isRunning}
|
||||
color="blue"
|
||||
size="xs"
|
||||
startIcon={{ icon: faList }}
|
||||
startIcon={{ icon: faRefresh }}>Run again</Button
|
||||
>
|
||||
View runs
|
||||
{#if canWrite(job?.script_path ?? '', {}, $userStore)}
|
||||
<Button href={editHref} color="blue" size="xs" startIcon={{ icon: faEdit }}>Edit</Button>
|
||||
{/if}
|
||||
<Button href={viewHref} color="blue" size="xs" startIcon={{ icon: faScroll }}>
|
||||
View {job?.job_kind}
|
||||
</Button>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="right">
|
||||
{@const stem = `/${job?.job_kind}s`}
|
||||
{@const isScript = job?.job_kind === 'script'}
|
||||
{@const route = isScript ? job?.script_hash : job?.script_path}
|
||||
{@const runHref = `${stem}/run/${route}${
|
||||
job?.args ? '?args=' + encodeURIComponent(encodeState(job?.args)) : ''
|
||||
}`}
|
||||
{@const editHref = `${stem}/edit/${route}${
|
||||
isScript
|
||||
? `?step=2${job?.args ? `&args=${encodeURIComponent(encodeState(job?.args))}` : ''}`
|
||||
: `${job?.args ? `?args=${encodeURIComponent(encodeState(job?.args))}` : ''}`
|
||||
}`}
|
||||
{@const isRunning = job && 'running' in job && job.running}
|
||||
{@const runsHref = `/runs/${job?.script_path}${!isScript ? '?jobKind=flow' : ''}`}
|
||||
{@const viewHref = `${stem}/get/${isScript ? job?.script_hash : job?.script_path}`}
|
||||
{#if isRunning}
|
||||
<Button
|
||||
color="red"
|
||||
size="xs"
|
||||
startIcon={{ icon: faTimesCircle }}
|
||||
on:click|once={() => {
|
||||
if (job?.id) {
|
||||
cancelJob(job?.id)
|
||||
}
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
{/if}
|
||||
<Button
|
||||
href={runHref}
|
||||
disabled={isRunning}
|
||||
color="blue"
|
||||
size="xs"
|
||||
startIcon={{ icon: faRefresh }}>Run again</Button
|
||||
>
|
||||
{#if canWrite(job?.script_path ?? '', {}, $userStore)}
|
||||
<Button href={editHref} color="blue" size="xs" startIcon={{ icon: faEdit }}>Edit</Button>
|
||||
{/if}
|
||||
<Button href={viewHref} color="blue" size="xs" startIcon={{ icon: faScroll }}>
|
||||
View {job?.job_kind}
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
</ActionRow>
|
||||
{/if}
|
||||
<CenteredPage>
|
||||
<h1 class="flex flex-row flex-wrap justify-between items-center gap-4 py-6">
|
||||
<div>
|
||||
{#if job}
|
||||
{#if 'success' in job && job.success}
|
||||
{#if job.is_skipped}
|
||||
<Icon
|
||||
class="text-green-600"
|
||||
data={faFastForward}
|
||||
scale={SMALL_ICON_SCALE}
|
||||
label="Job completed successfully but was skipped"
|
||||
/>
|
||||
{:else}
|
||||
<Icon
|
||||
class="text-green-600"
|
||||
data={check}
|
||||
scale={SMALL_ICON_SCALE}
|
||||
label="Job completed successfully"
|
||||
/>
|
||||
{/if}
|
||||
{:else if job && 'success' in job}
|
||||
<Icon
|
||||
class="text-red-700"
|
||||
data={faTimes}
|
||||
scale={iconScale}
|
||||
label="Job completed with an error"
|
||||
/>
|
||||
{:else if job && 'running' in job && job.running}
|
||||
<Icon class="text-yellow-500" data={faCircle} scale={iconScale} label="Job is running" />
|
||||
{:else if job && 'running' in job && job.scheduled_for && forLater(job.scheduled_for)}
|
||||
<Icon
|
||||
class="text-gray-700"
|
||||
data={faCalendar}
|
||||
scale={iconScale}
|
||||
label="Job is scheduled for a later time"
|
||||
/>
|
||||
{:else if job && 'running' in job && job.scheduled_for}
|
||||
<Icon
|
||||
class="text-gray-500"
|
||||
data={faHourglassHalf}
|
||||
scale={iconScale}
|
||||
label="Job is waiting for an executor"
|
||||
/>
|
||||
{/if}
|
||||
{job.script_path ?? (job.job_kind == 'dependencies' ? 'lock dependencies' : 'No path')}
|
||||
{#if job.script_hash}
|
||||
<a href="/scripts/get/{job.script_hash}"
|
||||
><Badge color="gray">{truncateHash(job.script_hash)}</Badge></a
|
||||
>
|
||||
{/if}
|
||||
{#if job && 'job_kind' in job}<Badge color="blue">{job.job_kind}</Badge>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</h1>
|
||||
{#if job && 'deleted' in job && job?.deleted}
|
||||
<div class="bg-red-100 border-l-4 border-red-600 text-orange-700 p-4" role="alert">
|
||||
<p class="font-bold">Deleted</p>
|
||||
<p>The content of this run was deleted (by an admin, no less)</p>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</ActionRow>
|
||||
{/if}
|
||||
|
||||
<!-- Arguments and actions -->
|
||||
<div class="flex flex-col mr-2 sm:mr-0 sm:grid sm:grid-cols-3 sm:gap-5">
|
||||
<div class="col-span-2">
|
||||
<JobArgs args={job?.args} />
|
||||
|
||||
{#if job?.job_kind == 'flow' || job?.job_kind == 'flowpreview'}
|
||||
<div class="mt-10" />
|
||||
<FlowProgressBar {job} class="py-4" />
|
||||
<div class="max-w-lg">
|
||||
<FlowStatusViewer
|
||||
jobId={job.id}
|
||||
on:jobsLoaded={({ detail }) => {
|
||||
job = detail
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Skeleton loading={!job} layout={[[9.5]]} />
|
||||
{#if job}<FlowMetadata {job} />{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if job?.job_kind !== 'flow' && job?.job_kind !== 'flowpreview'}
|
||||
<!-- Logs and outputs-->
|
||||
<div class="mr-2 sm:mr-0 mt-12">
|
||||
<Tabs bind:selected={viewTab}>
|
||||
<Tab value="result">Result</Tab>
|
||||
<Tab value="logs">Logs</Tab>
|
||||
{#if job?.job_kind == 'dependencies'}
|
||||
<Tab value="code">Dependencies</Tab>
|
||||
{:else if job?.job_kind == 'preview'}
|
||||
<Tab value="code">Code</Tab>
|
||||
{/if}
|
||||
</Tabs>
|
||||
|
||||
<Skeleton loading={!job} layout={[[5]]} />
|
||||
{#if job}
|
||||
<div class="flex flex-row border rounded-md p-3 max-h-1/2 overflow-auto">
|
||||
{#if viewTab == 'logs'}
|
||||
<div class="w-full">
|
||||
<LogViewer isLoading={!(job && 'logs' in job && job.logs)} content={job?.logs} />
|
||||
</div>
|
||||
{:else if viewTab == 'code'}
|
||||
{#if job && 'raw_code' in job && job.raw_code}
|
||||
<HighlightCode language={job.language} code={job.raw_code} />
|
||||
{:else if job}
|
||||
No code is available
|
||||
<CenteredPage>
|
||||
<h1 class="flex flex-row flex-wrap justify-between items-center gap-4 py-6">
|
||||
<div>
|
||||
{#if job}
|
||||
{#if 'success' in job && job.success}
|
||||
{#if job.is_skipped}
|
||||
<Icon
|
||||
class="text-green-600"
|
||||
data={faFastForward}
|
||||
scale={SMALL_ICON_SCALE}
|
||||
label="Job completed successfully but was skipped"
|
||||
/>
|
||||
{:else}
|
||||
<Skeleton layout={[[5]]} />
|
||||
<Icon
|
||||
class="text-green-600"
|
||||
data={check}
|
||||
scale={SMALL_ICON_SCALE}
|
||||
label="Job completed successfully"
|
||||
/>
|
||||
{/if}
|
||||
{:else if job !== undefined && 'result' in job && job.result !== undefined}
|
||||
<DisplayResult result={job.result} />
|
||||
{:else if job}
|
||||
No output is available yet
|
||||
{:else if job && 'success' in job}
|
||||
<Icon
|
||||
class="text-red-700"
|
||||
data={faTimes}
|
||||
scale={iconScale}
|
||||
label="Job completed with an error"
|
||||
/>
|
||||
{:else if job && 'running' in job && job.running}
|
||||
<Icon
|
||||
class="text-yellow-500"
|
||||
data={faCircle}
|
||||
scale={iconScale}
|
||||
label="Job is running"
|
||||
/>
|
||||
{:else if job && 'running' in job && job.scheduled_for && forLater(job.scheduled_for)}
|
||||
<Icon
|
||||
class="text-gray-700"
|
||||
data={faCalendar}
|
||||
scale={iconScale}
|
||||
label="Job is scheduled for a later time"
|
||||
/>
|
||||
{:else if job && 'running' in job && job.scheduled_for}
|
||||
<Icon
|
||||
class="text-gray-500"
|
||||
data={faHourglassHalf}
|
||||
scale={iconScale}
|
||||
label="Job is waiting for an executor"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{job.script_path ?? (job.job_kind == 'dependencies' ? 'lock dependencies' : 'No path')}
|
||||
{#if job.script_hash}
|
||||
<a href="/scripts/get/{job.script_hash}"
|
||||
><Badge color="gray">{truncateHash(job.script_hash)}</Badge></a
|
||||
>
|
||||
{/if}
|
||||
{#if job && 'job_kind' in job}<Badge color="blue">{job.job_kind}</Badge>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</h1>
|
||||
{#if job && 'deleted' in job && job?.deleted}
|
||||
<div class="bg-red-100 border-l-4 border-red-600 text-orange-700 p-4" role="alert">
|
||||
<p class="font-bold">Deleted</p>
|
||||
<p>The content of this run was deleted (by an admin, no less)</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Arguments and actions -->
|
||||
<div class="flex flex-col mr-2 sm:mr-0 sm:grid sm:grid-cols-3 sm:gap-5">
|
||||
<div class="col-span-2">
|
||||
<JobArgs args={job?.args} />
|
||||
|
||||
{#if job?.job_kind == 'flow' || job?.job_kind == 'flowpreview'}
|
||||
<div class="mt-10" />
|
||||
<FlowProgressBar {job} class="py-4" />
|
||||
<div class="max-w-lg">
|
||||
<FlowStatusViewer
|
||||
jobId={job.id}
|
||||
on:jobsLoaded={({ detail }) => {
|
||||
job = detail
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Skeleton loading={!job} layout={[[9.5]]} />
|
||||
{#if job}<FlowMetadata {job} />{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</CenteredPage>
|
||||
|
||||
{#if job?.job_kind !== 'flow' && job?.job_kind !== 'flowpreview'}
|
||||
<!-- Logs and outputs-->
|
||||
<div class="mr-2 sm:mr-0 mt-12">
|
||||
<Tabs bind:selected={viewTab}>
|
||||
<Tab value="result">Result</Tab>
|
||||
<Tab value="logs">Logs</Tab>
|
||||
{#if job?.job_kind == 'dependencies'}
|
||||
<Tab value="code">Dependencies</Tab>
|
||||
{:else if job?.job_kind == 'preview'}
|
||||
<Tab value="code">Code</Tab>
|
||||
{/if}
|
||||
</Tabs>
|
||||
|
||||
<Skeleton loading={!job} layout={[[5]]} />
|
||||
{#if job}
|
||||
<div class="flex flex-row border rounded-md p-3 max-h-1/2 overflow-auto">
|
||||
{#if viewTab == 'logs'}
|
||||
<div class="w-full">
|
||||
<LogViewer isLoading={!(job && 'logs' in job && job.logs)} content={job?.logs} />
|
||||
</div>
|
||||
{:else if viewTab == 'code'}
|
||||
{#if job && 'raw_code' in job && job.raw_code}
|
||||
<HighlightCode language={job.language} code={job.raw_code} />
|
||||
{:else if job}
|
||||
No code is available
|
||||
{:else}
|
||||
<Skeleton layout={[[5]]} />
|
||||
{/if}
|
||||
{:else if job !== undefined && 'result' in job && job.result !== undefined}
|
||||
<DisplayResult result={job.result} />
|
||||
{:else if job}
|
||||
No output is available yet
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</CenteredPage>
|
||||
{/if}
|
||||
|
||||
@@ -59,8 +59,8 @@
|
||||
requestBody: args,
|
||||
scheduledFor
|
||||
})
|
||||
sendUserToast(`Job <a href='/run/${run}'>${run}</a> started`)
|
||||
goto('/run/' + run)
|
||||
sendUserToast(`Job <a href='/run/${run}?workspace=${$workspaceStore}'>${run}</a> started`)
|
||||
goto('/run/' + run + '?workspace=' + $workspaceStore)
|
||||
} catch (err) {
|
||||
sendUserToast(`Could not create job: ${err}`, true)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user