mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-12 00:06:14 +00:00
feat(frontend): rich renderer improvements
This commit is contained in:
@@ -3,5 +3,6 @@
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100,
|
||||
"htmlWhitespaceSensitivity": "strict",
|
||||
"semi": false
|
||||
}
|
||||
|
||||
+11
-11
@@ -21,7 +21,7 @@ html {
|
||||
a {
|
||||
@apply text-blue-500;
|
||||
}
|
||||
|
||||
|
||||
.flex pre code.hljs {
|
||||
@apply text-sm;
|
||||
}
|
||||
@@ -127,19 +127,19 @@ html {
|
||||
@apply rounded-lg;
|
||||
@apply text-sm;
|
||||
@apply px-5;
|
||||
@apply py-2.5;
|
||||
@apply text-center;
|
||||
@apply py-2.5;
|
||||
@apply text-center;
|
||||
@apply inline-flex;
|
||||
@apply items-center;
|
||||
}
|
||||
|
||||
.default-primary-button-v2:focus {
|
||||
@apply ring-4;
|
||||
@apply ring-4;
|
||||
@apply outline-none;
|
||||
@apply bg-blue-800;
|
||||
}
|
||||
.default-primary-button-v2:hover {
|
||||
@apply bg-blue-800
|
||||
@apply bg-blue-800;
|
||||
}
|
||||
|
||||
.default-secondary-button-v2 {
|
||||
@@ -151,19 +151,19 @@ html {
|
||||
@apply rounded-lg;
|
||||
@apply text-sm;
|
||||
@apply px-5;
|
||||
@apply py-2.5;
|
||||
@apply text-center;
|
||||
@apply py-2.5;
|
||||
@apply text-center;
|
||||
@apply inline-flex;
|
||||
@apply items-center;
|
||||
}
|
||||
|
||||
.default-secondary-button-v2:focus {
|
||||
@apply ring-4;
|
||||
@apply ring-4;
|
||||
@apply outline-none;
|
||||
@apply ring-gray-100;
|
||||
}
|
||||
.default-secondary-button-v2:hover {
|
||||
@apply bg-gray-100
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
|
||||
.input-error {
|
||||
@@ -224,10 +224,10 @@ html {
|
||||
|
||||
.inline-highlight pre code.hljs {
|
||||
padding: 0;
|
||||
@apply text-xs;
|
||||
@apply text-xs whitespace-pre-wrap;
|
||||
}
|
||||
|
||||
/* svelte-split-pane separator class override */
|
||||
.separator {
|
||||
background-color: #ddd !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,18 @@
|
||||
|
||||
export let result: any
|
||||
|
||||
let resultKind: 'json' | 'table-col' | 'table-row' | 'png' | 'file' | 'jpeg' | 'gif' | undefined =
|
||||
inferResultKind(result)
|
||||
let resultKind:
|
||||
| 'json'
|
||||
| 'table-col'
|
||||
| 'table-row'
|
||||
| 'png'
|
||||
| 'file'
|
||||
| 'jpeg'
|
||||
| 'gif'
|
||||
| 'error'
|
||||
| undefined = inferResultKind(result)
|
||||
|
||||
let forceJson = false
|
||||
|
||||
function isRectangularArray(obj: any) {
|
||||
if (!Array.isArray(obj) || obj.length == 0) {
|
||||
@@ -45,6 +55,8 @@
|
||||
return 'jpeg'
|
||||
} else if (keys.length == 1 && keys[0] == 'file') {
|
||||
return 'file'
|
||||
} else if (keys.length == 1 && keys[0] == 'error') {
|
||||
return 'error'
|
||||
}
|
||||
} catch (err) {}
|
||||
}
|
||||
@@ -52,13 +64,17 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="inline-highlight">
|
||||
{#if result}
|
||||
{#if typeof result == 'object' && Object.keys(result).length > 0}
|
||||
<div>
|
||||
The result keys are: <b>{truncate(Object.keys(result).join(', '), 50)}</b>
|
||||
</div>{/if}{#if resultKind == 'table-col'}
|
||||
<div class="grid grid-flow-col-dense border border-gray-200 rounded-md ">
|
||||
{#if resultKind && resultKind != 'json'}
|
||||
<div class="mb-2 text-gray-500 text-sm bg-gray-50/20">
|
||||
as JSON <input type="checkbox" bind:checked={forceJson} /></div
|
||||
>{/if}{#if typeof result == 'object' && Object.keys(result).length > 0}<div
|
||||
class="mb-2 text-gray-700"
|
||||
>The result keys are: <b>{truncate(Object.keys(result).join(', '), 50)}</b></div
|
||||
>{/if}{#if !forceJson && 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 max-h-40 min-w-full overflow-auto">
|
||||
<div
|
||||
@@ -76,7 +92,7 @@
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else if resultKind == 'table-row'}<div
|
||||
{:else if !forceJson && resultKind == 'table-row'}<div
|
||||
class="grid grid-flow-col-dense border border-gray-200 rounded-md "
|
||||
>
|
||||
<TableCustom>
|
||||
@@ -91,37 +107,31 @@
|
||||
</tbody>
|
||||
</TableCustom>
|
||||
</div>
|
||||
{:else if resultKind == 'png'}
|
||||
<div class="h-full">
|
||||
Result is an image: <img
|
||||
alt="png rendered"
|
||||
class="w-auto h-full"
|
||||
src="data:image/png;base64,{result.png}"
|
||||
/>
|
||||
{:else if !forceJson && resultKind == 'png'}
|
||||
<div class="h-full"
|
||||
><img alt="png rendered" class="w-auto h-full" src="data:image/png;base64,{result.png}" />
|
||||
</div>
|
||||
{:else if resultKind == 'jpeg'}
|
||||
<div class="h-full">
|
||||
Result is an image: <img
|
||||
{:else if !forceJson && resultKind == 'jpeg'}
|
||||
<div class="h-full"
|
||||
><img
|
||||
alt="jpeg rendered"
|
||||
class="w-auto h-full"
|
||||
src="data:image/jpeg;base64,{result.jpeg}"
|
||||
/>
|
||||
</div>
|
||||
{:else if resultKind == 'gif'}
|
||||
<div class="h-full">
|
||||
Result is an image: <img
|
||||
alt="gif rendered"
|
||||
class="w-auto h-full"
|
||||
src="data:image/gif;base64,{result.gif}"
|
||||
/>
|
||||
{:else if !forceJson && resultKind == 'gif'}
|
||||
<div class="h-full"
|
||||
><img alt="gif rendered" class="w-auto h-full" src="data:image/gif;base64,{result.gif}" />
|
||||
</div>
|
||||
{:else if resultKind == 'file'}
|
||||
<div>
|
||||
Result is a file: <a
|
||||
download="windmill.file"
|
||||
href="data:application/octet-stream;base64,{result.file}">Download</a
|
||||
{:else if !forceJson && resultKind == 'file'}
|
||||
<div
|
||||
><a download="windmill.file" href="data:application/octet-stream;base64,{result.file}"
|
||||
>Download</a
|
||||
>
|
||||
</div>
|
||||
{:else if !forceJson && resultKind == 'error'}<div
|
||||
><p class="text-sm text-red-500">{result.error}</p>
|
||||
</div>
|
||||
{:else}<Highlight
|
||||
language={json}
|
||||
code={JSON.stringify(result, null, 4).replace(/\\n/g, '\n')}
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
<ResourceEditor bind:this={resourceEditor} on:refresh={resourcePicker.openModal} />
|
||||
<VariableEditor bind:this={variableEditor} on:create={variablePicker.openModal} />
|
||||
|
||||
<div class="flex divide-x items-center">
|
||||
<div class="flex divide-x items-center overflow-hidden w-full">
|
||||
<div>
|
||||
<Button
|
||||
color="light"
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
/>
|
||||
|
||||
<CenteredPage>
|
||||
<div class="flex flex-row justify-between">
|
||||
<div class="flex flex-row flex-wrap justify-between">
|
||||
<h1>
|
||||
<div>
|
||||
{#if job}
|
||||
@@ -369,8 +369,11 @@
|
||||
on:click={() => (viewTab = 'result')}
|
||||
>
|
||||
Result <Tooltip
|
||||
>What is returned by the <span class="font-mono">main</span> function of the script. Dictionary
|
||||
of columns are rendered as a table</Tooltip
|
||||
>What is returned by the <span class="font-mono">main</span> function of the script,
|
||||
stringified to JSON. Then for some specific cases, like having "png", "jpeg" or "file"
|
||||
as sole key, they are displayed more richly. See
|
||||
<a href="https://docs.windmill.dev/docs/reference#rich-display-rendering">here</a> for more
|
||||
details.</Tooltip
|
||||
>
|
||||
</button>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user