mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-26 00:01:37 +00:00
feat: rich rendering of flows
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { faHourglassHalf, faSpinner, faTimes } from '@fortawesome/free-solid-svg-icons'
|
||||
import { truncateRev } from '$lib/utils'
|
||||
import { scriptPathToHref, truncateRev } from '$lib/utils'
|
||||
|
||||
import Icon from 'svelte-awesome'
|
||||
import { check } from 'svelte-awesome/icons'
|
||||
@@ -124,7 +124,8 @@
|
||||
<p class="text-sm text-gray-500">
|
||||
{#if mod.value.type == FlowModuleValue.type.SCRIPT}
|
||||
Script at path <a
|
||||
href="/scripts/get/{mod.value.path}"
|
||||
target="_blank"
|
||||
href={scriptPathToHref(mod.value.path ?? '')}
|
||||
class="font-medium text-gray-900">{mod.value.path}</a
|
||||
>
|
||||
{/if}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
<script lang="ts">
|
||||
import { scriptPathToHref } from '$lib/utils'
|
||||
|
||||
import Highlight from 'svelte-highlight'
|
||||
import json from 'svelte-highlight/languages/json'
|
||||
import python from 'svelte-highlight/languages/python'
|
||||
import typescript from 'svelte-highlight/languages/typescript'
|
||||
|
||||
import { FlowModuleValue, type Flow } from '$lib/gen'
|
||||
import github from 'svelte-highlight/styles/github'
|
||||
import { slide } from 'svelte/transition'
|
||||
import Tabs from './Tabs.svelte'
|
||||
|
||||
export let flow: Flow
|
||||
|
||||
export let embedded = false
|
||||
|
||||
export let tab: 'ui' | 'json' = 'ui'
|
||||
let open: { [id: number]: boolean } = {}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
{@html github}
|
||||
</svelte:head>
|
||||
|
||||
{#if !embedded}
|
||||
<Tabs
|
||||
tabs={[
|
||||
['ui', 'Flow rendered'],
|
||||
['json', 'JSON']
|
||||
]}
|
||||
bind:tab
|
||||
/>
|
||||
{/if}
|
||||
{#if tab == 'ui'}
|
||||
<div class="flow-root w-full p-4">
|
||||
<p class="font-black text-lg mb-6 w-full ml-2">
|
||||
<span>{flow.value.modules.length} Steps </span>
|
||||
<span class="mt-4" />
|
||||
</p>
|
||||
<ul class="-mb-8 w-full">
|
||||
{#each flow.value.modules ?? [] as mod, i}
|
||||
<li class="w-full">
|
||||
<div class="relative pb-8 w-full">
|
||||
{#if i < (flow.value.modules ?? []).length - 1}
|
||||
<span
|
||||
class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{/if}
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-blue-600 flex items-center justify-center ring-8 ring-white text-white"
|
||||
>{i + 1}
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4 w-full">
|
||||
<div class="w-full">
|
||||
<p class="text-sm text-gray-500">
|
||||
{#if mod.value.type == FlowModuleValue.type.SCRIPT}
|
||||
Script at path <a
|
||||
target="_blank"
|
||||
href={scriptPathToHref(mod.value.path ?? '')}
|
||||
class="font-medium text-gray-900">{mod.value.path}</a
|
||||
>
|
||||
{:else if mod.value.type == FlowModuleValue.type.RAWSCRIPT}
|
||||
<button
|
||||
on:click={() => (open[i] = !open[i])}
|
||||
class="mb-2 underline text-black"
|
||||
>
|
||||
Raw {mod.value.language} script {open[i] ? '(-)' : '(+)'}</button
|
||||
>
|
||||
|
||||
{#if open[i]}
|
||||
<div transition:slide class="border border-black p-2 bg-gray-50 w-full">
|
||||
<Highlight
|
||||
language={mod.value.language == 'deno' ? typescript : python}
|
||||
code={mod.value.content}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{:else if mod.value.type == FlowModuleValue.type.FLOW}
|
||||
Flow at path {mod.value.path}
|
||||
{:else if mod.value.type == FlowModuleValue.type.FORLOOPFLOW}
|
||||
For loop over step {i}'s result':
|
||||
<svelte:self flow={mod.value} embedded={true} />
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
{:else}
|
||||
<Highlight language={json} code={JSON.stringify(flow.value, null, 4)} />
|
||||
{/if}
|
||||
@@ -402,3 +402,11 @@ export function setInputCat(type: string | undefined, format: string | undefined
|
||||
return 'string'
|
||||
}
|
||||
}
|
||||
|
||||
export function scriptPathToHref(path: string): string {
|
||||
if (path.startsWith('hub/')) {
|
||||
return 'https://hub.windmill.dev/scripts/get/' + path.substring(4)
|
||||
} else {
|
||||
return `/scripts/get/${path}`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,7 @@
|
||||
faCalendar,
|
||||
faShare
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import Highlight from 'svelte-highlight'
|
||||
import json from 'svelte-highlight/languages/json'
|
||||
|
||||
import github from 'svelte-highlight/styles/github'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import ShareModal from '$lib/components/ShareModal.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
@@ -23,6 +20,7 @@
|
||||
import SchemaViewer from '$lib/components/SchemaViewer.svelte'
|
||||
import Dropdown from '$lib/components/Dropdown.svelte'
|
||||
import CenteredPage from '$lib/components/CenteredPage.svelte'
|
||||
import FlowViewer from '$lib/components/FlowViewer.svelte'
|
||||
|
||||
let flow: Flow | undefined
|
||||
let can_write = false
|
||||
@@ -47,10 +45,6 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
{@html github}
|
||||
</svelte:head>
|
||||
|
||||
<CenteredPage>
|
||||
<div class="flex flex-row justify-between">
|
||||
<h1>
|
||||
@@ -190,7 +184,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-gray-700 pb-1 mb-3 border-b">Flow</h3>
|
||||
<Highlight language={json} code={JSON.stringify(flow.value, null, 4)} />
|
||||
<FlowViewer {flow} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user