mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 08:01:35 +00:00
221 lines
6.6 KiB
Svelte
221 lines
6.6 KiB
Svelte
<script lang="ts">
|
|
import { CompletedJob, Job, JobService, Preview } from '$lib/gen'
|
|
import { workspaceStore } from '$lib/stores'
|
|
import { displayDate } from '$lib/utils'
|
|
import { faTimes } from '@fortawesome/free-solid-svg-icons'
|
|
import Icon from 'svelte-awesome'
|
|
import { check } from 'svelte-awesome/icons'
|
|
import Tabs from '../common/tabs/Tabs.svelte'
|
|
import Tab from '../common/tabs/Tab.svelte'
|
|
import TabContent from '../common/tabs/TabContent.svelte'
|
|
import DisplayResult from '../DisplayResult.svelte'
|
|
import TableCustom from '../TableCustom.svelte'
|
|
import Drawer from '../common/drawer/Drawer.svelte'
|
|
import DrawerContent from '../common/drawer/DrawerContent.svelte'
|
|
import HighlightCode from '../HighlightCode.svelte'
|
|
import LogViewer from '../LogViewer.svelte'
|
|
import { Pane, Splitpanes } from 'svelte-splitpanes'
|
|
import SplitPanesWrapper from '../splitPanes/SplitPanesWrapper.svelte'
|
|
import { Loader2 } from 'lucide-svelte'
|
|
import type Editor from '../Editor.svelte'
|
|
import type DiffEditor from '../DiffEditor.svelte'
|
|
import ScriptFix from '../copilot/ScriptFix.svelte'
|
|
|
|
export let lang: Preview.language | undefined
|
|
export let previewIsLoading = false
|
|
export let previewJob: Job | undefined
|
|
export let pastPreviews: CompletedJob[] = []
|
|
export let editor: Editor | undefined = undefined
|
|
export let diffEditor: DiffEditor | undefined = undefined
|
|
export let args: Record<string, any> | undefined = undefined
|
|
|
|
type DrawerContent = {
|
|
mode: 'json' | Preview.language | 'plain'
|
|
title: string
|
|
content: any
|
|
}
|
|
|
|
let selectedTab = 'logs'
|
|
let drawerOpen: boolean = false
|
|
let drawerContent: DrawerContent | undefined = undefined
|
|
|
|
export function setFocusToLogs() {
|
|
selectedTab = 'logs'
|
|
}
|
|
|
|
function openDrawer(newContent: DrawerContent) {
|
|
drawerContent = newContent
|
|
drawerOpen = true
|
|
}
|
|
|
|
function closeDrawer() {
|
|
drawerOpen = false
|
|
}
|
|
</script>
|
|
|
|
<Drawer bind:open={drawerOpen} size="800px">
|
|
<DrawerContent title={drawerContent?.title} on:close={() => closeDrawer()}>
|
|
{#if drawerContent?.content == undefined}
|
|
<div class="p-2"> <Loader2 class="animate-spin" /> </div>
|
|
{:else if drawerContent?.mode === 'json'}
|
|
<DisplayResult
|
|
workspaceId={previewJob?.workspace_id}
|
|
jobId={previewJob?.id}
|
|
result={drawerContent.content}
|
|
/>
|
|
{:else if drawerContent?.mode === 'plain'}
|
|
<pre
|
|
class="overflow-x-auto break-words relative h-full m-2 text-xs bg-surface shadow-inner p-2"
|
|
>{drawerContent?.content}
|
|
</pre>
|
|
{:else if drawerContent?.mode === 'deno' || drawerContent?.mode === 'python3' || drawerContent?.mode === 'go' || drawerContent?.mode === 'bash' || drawerContent?.mode === 'nativets'}
|
|
<HighlightCode language={drawerContent?.mode} code={drawerContent?.content} />
|
|
{/if}
|
|
</DrawerContent>
|
|
</Drawer>
|
|
|
|
<Tabs bind:selected={selectedTab} class="mt-1">
|
|
<Tab value="logs" size="xs">Logs & Result</Tab>
|
|
<Tab value="history" size="xs">History</Tab>
|
|
|
|
<svelte:fragment slot="content">
|
|
<!--
|
|
TabContent would wrap it in an extra div which is undesirable in this situation
|
|
because SplitPanesWrapper uses the parent element as a reference point.
|
|
-->
|
|
{#if selectedTab === 'logs'}
|
|
<SplitPanesWrapper>
|
|
<Splitpanes horizontal>
|
|
<Pane class="relative">
|
|
<LogViewer
|
|
jobId={previewJob?.id}
|
|
duration={previewJob?.['duration_ms']}
|
|
mem={previewJob?.['mem_peak']}
|
|
content={previewJob?.logs}
|
|
isLoading={previewIsLoading}
|
|
/>
|
|
</Pane>
|
|
<Pane>
|
|
{#if previewJob != undefined && 'result' in previewJob}
|
|
<div class="relative w-full h-full p-2">
|
|
<DisplayResult
|
|
workspaceId={previewJob?.workspace_id}
|
|
jobId={previewJob?.id}
|
|
result={previewJob.result}
|
|
>
|
|
<svelte:fragment slot="copilot-fix">
|
|
{#if lang && editor && diffEditor && args && previewJob?.result?.error}
|
|
<ScriptFix
|
|
error={JSON.stringify(previewJob.result.error)}
|
|
{lang}
|
|
{editor}
|
|
{diffEditor}
|
|
{args}
|
|
/>
|
|
{/if}
|
|
</svelte:fragment>
|
|
</DisplayResult>
|
|
</div>
|
|
{:else}
|
|
<div class="text-sm text-tertiary p-2">
|
|
{#if previewIsLoading}
|
|
<Loader2 class="animate-spin" />
|
|
{:else}
|
|
Test to see the result here
|
|
{/if}
|
|
</div>
|
|
{/if}
|
|
</Pane>
|
|
</Splitpanes>
|
|
</SplitPanesWrapper>
|
|
{/if}
|
|
<TabContent value="history" class="p-2">
|
|
<TableCustom>
|
|
<tr slot="header-row">
|
|
<th class="text-xs">Id</th>
|
|
<th class="text-xs">Created at</th>
|
|
<th class="text-xs">Success</th>
|
|
<th class="text-xs">Result</th>
|
|
<th class="text-xs">Code</th>
|
|
<th class="text-xs">Logs</th>
|
|
</tr>
|
|
<tbody slot="body">
|
|
{#each pastPreviews as { id, created_at, success }}
|
|
<tr class="">
|
|
<td class="text-xs">
|
|
<a class="pr-3" href="/run/{id}?workspace={$workspaceStore}" target="_blank"
|
|
>{id.substring(30)}</a
|
|
>
|
|
</td>
|
|
<td class="text-xs">{displayDate(created_at)}</td>
|
|
<td class="text-xs">
|
|
{#if success}
|
|
<Icon class="text-green-600" data={check} scale={0.6} />
|
|
{:else}
|
|
<Icon class="text-red-700" data={faTimes} scale={0.6} />
|
|
{/if}
|
|
</td>
|
|
<td class="text-xs">
|
|
<a
|
|
href="#result"
|
|
class="text-xs"
|
|
on:click={() => {
|
|
openDrawer({ mode: 'json', content: undefined, title: 'Result' })
|
|
JobService.getCompletedJobResult({
|
|
workspace: $workspaceStore ?? 'NO_W',
|
|
id
|
|
}).then((res) => {
|
|
drawerContent && (drawerContent.content = res)
|
|
})
|
|
}}
|
|
>
|
|
See Result
|
|
</a>
|
|
</td>
|
|
<td class="text-xs">
|
|
<a
|
|
href="#code"
|
|
class="text-xs"
|
|
on:click={async () => {
|
|
const code = (
|
|
await JobService.getCompletedJob({
|
|
workspace: $workspaceStore ?? 'NO_W',
|
|
id
|
|
})
|
|
).raw_code
|
|
|
|
openDrawer({
|
|
mode: lang ?? 'plain',
|
|
content: String(code),
|
|
title: `Code ${lang}`
|
|
})
|
|
}}
|
|
>
|
|
View code
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<a
|
|
href="#logs"
|
|
class="text-xs"
|
|
on:click={async () => {
|
|
const logs = (
|
|
await JobService.getCompletedJob({
|
|
workspace: $workspaceStore ?? 'NO_W',
|
|
id
|
|
})
|
|
).logs
|
|
openDrawer({ mode: 'plain', content: String(logs), title: `Logs for ${id}` })
|
|
}}
|
|
>
|
|
View logs
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{/each}
|
|
</tbody>
|
|
</TableCustom>
|
|
</TabContent>
|
|
</svelte:fragment>
|
|
</Tabs>
|