feat: add ability to copy job args

This commit is contained in:
Ruben Fiszel
2023-06-22 21:21:35 +02:00
parent f9341af2fe
commit 29a2eeb382
5 changed files with 177 additions and 72 deletions

View File

@@ -2,7 +2,7 @@
import { ResourceService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import { copyToClipboard, truncate } from '$lib/utils'
import { ClipboardCopy } from 'lucide-svelte'
import { ClipboardCopy, Expand } from 'lucide-svelte'
import { Button, DrawerContent } from './common'
import Drawer from './common/drawer/Drawer.svelte'
import ObjectViewer from './propertyPicker/ObjectViewer.svelte'
@@ -68,16 +68,18 @@
>
{/if}
{:else}
<div class="max-h-40 overflow-auto">
<ObjectViewer collapsed={false} topBrackets={true} pureViewer={true} json={value} />
<div class="relative">
{#if JSON.stringify(value).length > 120}
<button
class="text-xs absolute top-0 right-4 text-gray-500"
on:click={() => {
jsonViewerContent = value
jsonViewer.toggleDrawer()
}}><Expand size={18} /></button
>
{/if}
<div class="max-h-40 overflow-auto">
<ObjectViewer collapsed={false} topBrackets={true} pureViewer={true} json={value} />
</div>
</div>
{#if JSON.stringify(value).length > 120}
<button
class="text-xs text-blue-500"
on:click={() => {
jsonViewerContent = value
jsonViewer.toggleDrawer()
}}>See JSON</button
>
{/if}
{/if}

View File

@@ -4,7 +4,7 @@
import TableCustom from './TableCustom.svelte'
import { copyToClipboard, truncate } from '$lib/utils'
import { Button, Drawer, DrawerContent } from './common'
import { ClipboardCopy } from 'lucide-svelte'
import { ClipboardCopy, Download, Expand } from 'lucide-svelte'
import Portal from 'svelte-portal'
import ObjectViewer from './propertyPicker/ObjectViewer.svelte'
@@ -106,6 +106,7 @@
}
let jsonViewer: Drawer
$: jsonStr = JSON.stringify(result, null, 4)
</script>
<div class="inline-highlight">
@@ -117,8 +118,8 @@
class="mb-2 w-full text-sm relative"
>The result keys are: <b>{truncate(Object.keys(result).join(', '), 50)}</b>
{#if !disableExpand}
<div class="text-gray-500 text-xs absolute top-5 right-0">
<button on:click={jsonViewer.openDrawer}>Expand</button>
<div class="text-gray-500 text-xs absolute top-5.5 right-0">
<button on:click={jsonViewer.openDrawer}><Expand size={16} /></button>
</div>
{/if}
</div>{/if}{#if !forceJson && resultKind == 'table-col'}<div
@@ -237,7 +238,6 @@
>
</div>
{:else}
{@const jsonStr = JSON.stringify(result, null, 4).replace(/\\n/g, '\n')}
{#if jsonStr.length > 10000}
<div class="text-sm mb-2 text-gray-600">
<a
@@ -252,7 +252,7 @@
{/if}
{/if}
{:else}
<div class="text-gray-500 text-sm">No result: {JSON.stringify(result)}</div>
<div class="text-gray-500 text-sm">No result: {jsonStr}</div>
{/if}
</div>
@@ -261,25 +261,26 @@
<Drawer bind:this={jsonViewer} size="900px">
<DrawerContent title="Expanded Result" on:close={jsonViewer.closeDrawer}>
<svelte:fragment slot="actions">
<Button
on:click={() => copyToClipboard(JSON.stringify(result, null, 4))}
color="light"
size="xs"
<a
class="text-sm text-gray-600 mr-2 inline-flex gap-2 items-center py-2 px-2 hover:bg-gray-100 rounded-lg"
download="{filename ?? 'result'}.json"
href="data:text/json;charset=utf-8,{encodeURIComponent(jsonStr)}"
>Download <Download size={14} /></a
>
<Button on:click={() => copyToClipboard(jsonStr)} color="light" size="xs">
<div class="flex gap-2 items-center">Copy to clipboard <ClipboardCopy /> </div>
</Button>
</svelte:fragment>
{@const str = JSON.stringify(result, null, 4).replace(/\\n/g, '\n')}
{#if str.length > 100000}
{#if jsonStr.length > 100000}
<div class="text-sm mb-2 text-gray-600">
<a
download="{filename ?? 'result'}.json"
href="data:text/json;charset=utf-8,{encodeURIComponent(str)}">Download</a
href="data:text/json;charset=utf-8,{encodeURIComponent(jsonStr)}">Download</a
>
JSON is too large to be displayed in full.
</div>
{:else}
<Highlight language={json} code={JSON.stringify(result, null, 4).replace(/\\n/g, '\n')} />
<Highlight language={json} code={jsonStr.replace(/\\n/g, '\n')} />
{/if}
</DrawerContent>
</Drawer>

View File

@@ -1,36 +1,132 @@
<script lang="ts">
import { ChevronRightSquare, ClipboardCopy, Download, Expand } from 'lucide-svelte'
import ArgInfo from './ArgInfo.svelte'
import { Skeleton } from './common'
import { Button, Drawer, DrawerContent, Skeleton } from './common'
import TableCustom from './TableCustom.svelte'
import Portal from 'svelte-portal'
import { Highlight } from 'svelte-highlight'
import { copyToClipboard } from '$lib/utils'
import { json, r } from 'svelte-highlight/languages'
export let args: any
export let tableClass = ''
let jsonViewer: Drawer
let runLocally: Drawer
let jsonStr = ''
function pythonCode() {
return `
if __name__ == 'main':
${Object.entries(args)
.map(([arg, value]) => {
return ` ${arg} = ${JSON.stringify(value)}`
})
.join('\n')}
main(${Object.keys(args)
.map((x) => `${x} = ${x}`)
.join(', ')})
`
}
function typescriptCode() {
return `
if (import.meta.main) {
${Object.entries(args)
.map(([arg, value]) => {
return ` let ${arg} = ${JSON.stringify(value)}`
})
.join('\n')}
await main(...)
}
`
}
</script>
<TableCustom class="py-2 {tableClass}">
<tr slot="header-row">
<th>Argument</th>
<th>Value</th>
</tr>
<tbody slot="body">
{#if args && Object.keys(args).length > 0}
{#each Object.entries(args) as [arg, value]}
<div class="relative">
<div class="text-gray-500 text-xs absolute top-8 right-0">
<button
on:click={() => {
jsonStr = JSON.stringify(args, null, 4)
jsonViewer.openDrawer()
}}><Expand size={18} /></button
>
</div>
<TableCustom class="py-2 {tableClass}">
<tr slot="header-row">
<th>Argument</th>
<th>Value</th>
</tr>
<tbody slot="body">
{#if args && Object.keys(args).length > 0}
{#each Object.entries(args) as [arg, value]}
<tr>
<td class="font-semibold">{arg}</td>
<td><ArgInfo {value} /></td>
</tr>
{/each}
{:else if args}
<tr><div class="text-gray-600 pt-2 pl-1 text-sm">No arguments</div></tr>
{:else}
<tr>
<td class="font-semibold">{arg}</td>
<td><ArgInfo {value} /></td>
<td>
<Skeleton layout={[[3], 0.5, [3]]} />
</td>
<td>
<Skeleton layout={[[3], 0.5, [3]]} />
</td>
</tr>
{/each}
{:else if args}
<tr><div class="text-gray-600 pt-2 pl-1 text-sm">No arguments</div></tr>
{:else}
<tr>
<td>
<Skeleton layout={[[3], 0.5, [3]]} />
</td>
<td>
<Skeleton layout={[[3], 0.5, [3]]} />
</td>
</tr>
{/if}
</tbody>
</TableCustom>
{/if}
</tbody>
</TableCustom>
</div>
<Portal>
<Drawer bind:this={jsonViewer} size="900px">
<DrawerContent title="Expanded Args" on:close={jsonViewer.closeDrawer}>
<svelte:fragment slot="actions">
<a
class="text-sm text-gray-600 mr-2 inline-flex gap-2 items-center py-2 px-2 hover:bg-gray-100 rounded-lg"
download="windmill-args.json"
href="data:text/json;charset=utf-8,{encodeURIComponent(jsonStr)}"
>Download <Download size={14} /></a
>
<Button on:click={runLocally.openDrawer} color="light" size="xs">
<div class="flex gap-2 items-center">Use in a local script<ChevronRightSquare /> </div>
</Button>
<Button on:click={() => copyToClipboard(jsonStr)} color="light" size="xs">
<div class="flex gap-2 items-center">Copy to clipboard <ClipboardCopy /> </div>
</Button>
</svelte:fragment>
{#if jsonStr.length > 100000}
<div class="text-sm mb-2 text-gray-600">
<a
download="windmill-args.json"
href="data:text/json;charset=utf-8,{encodeURIComponent(jsonStr)}">Download</a
>
JSON is too large to be displayed in full.
</div>
{:else}
<Highlight language={json} code={jsonStr.replace(/\\n/g, '\n')} />
{/if}
</DrawerContent>
</Drawer>
<Drawer bind:this={runLocally} size="900px">
<DrawerContent title="Run locally" on:close={runLocally.closeDrawer}>
<h3 class="mb-2">Envs</h3>
If using the wmill client in your code, set the following env variables:
<pre
><code
>BASE_URL="{window.location.origin}"
WM_TOKEN="{'<TOKEN>'}"</code
></pre
>
<h3 class="mt-8">TypeScript</h3>
<pre><code>{typescriptCode()}</code></pre>
<h3 class="mt-8">Python</h3>
<pre><code>{pythonCode()}</code></pre>
</DrawerContent>
</Drawer>
</Portal>

View File

@@ -9,7 +9,6 @@
async function loadVersion() {
try {
const res = await SettingsService.backendUptodate()
console.log(res)
if (res != 'yes') {
uptodate = res
}

View File

@@ -233,8 +233,8 @@
</svelte:fragment>
</ActionRow>
<CenteredPage>
<h1 class="flex flex-row flex-wrap justify-between items-center gap-4 py-6">
<div>
<h1 class="flex flex-row flex-wrap justify-between items-center gap-x-4 py-6">
<div class="flex flex-row flex-wrap gap-6 items-center">
{#if job}
{#if 'success' in job && job.success}
{#if job.is_skipped}
@@ -282,22 +282,29 @@
/>
{/if}
{job.script_path ?? (job.job_kind == 'dependencies' ? 'lock dependencies' : 'No path')}
{#if job.script_hash}
<a href="/scripts/get/{job.script_hash}?$workspaceStore={$workspaceStore}}"
><Badge color="gray">{truncateHash(job.script_hash)}</Badge></a
>
{/if}
{#if job && 'job_kind' in job}<Badge baseClass="ml-2" color="blue">{job.job_kind}</Badge>
{/if}
{#if job.tag && !['deno', 'python3', 'flow', 'other', 'go', 'bash', 'other', 'dependency'].includes(job.tag)}
<Badge color="indigo">Worker group: {job.tag}</Badge>
{/if}
{#if !job.visible_to_owner}<Badge color="red"
>only visible to you <Tooltip
>The option to hide this run from the owner of this script or flow was activated</Tooltip
></Badge
>
{/if}
<div class="flex flex-row gap-2 items-center">
{#if job.script_hash}
<a href="/scripts/get/{job.script_hash}?workspace={$workspaceStore}"
><Badge color="gray">{truncateHash(job.script_hash)}</Badge></a
>
{/if}
{#if job && 'job_kind' in job}
<div>
<Badge color="blue">{job.job_kind}</Badge>
</div>
{/if}
{#if job.tag && !['deno', 'python3', 'flow', 'other', 'go', 'bash', 'other', 'dependency'].includes(job.tag)}
<div>
<Badge color="indigo">Worker group: {job.tag}</Badge>
</div>
{/if}
{#if !job.visible_to_owner}<Badge color="red"
>only visible to you <Tooltip
>The option to hide this run from the owner of this script or flow was activated</Tooltip
></Badge
>
{/if}
</div>
{/if}
</div>
</h1>
@@ -308,11 +315,11 @@
{/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="flex flex-col mr-2 sm:mr-0 sm:grid sm:grid-cols-3 sm:gap-10">
<div class="col-span-2">
<JobArgs args={job?.args} />
</div>
<div>
<div class="mt-6">
<Skeleton loading={!job} layout={[[9.5]]} />
{#if job}<FlowMetadata {job} />{/if}
</div>