mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 08:02:26 +00:00
fix(frontend): fix large JSON viewer (#4273)
* fix(frontend): fix large JSON viewer * fix(frontend): fix large JSON viewer * fix(frontend): improve UX * fix(frontend): improve show more button * fix(frontend): add fading effect * fix(frontend): remove show more when we reach the end * fix(frontend): Add show more button to the raw tab * fix(frontend): Add show more button to the raw tab
This commit is contained in:
@@ -1,17 +1,12 @@
|
||||
<script lang="ts">
|
||||
import Highlight from 'svelte-highlight'
|
||||
import json from 'svelte-highlight/languages/json'
|
||||
import type { FlowValue } from '$lib/gen'
|
||||
import { Tab, Tabs, TabContent, Button } from './common'
|
||||
import { Tab, Tabs, TabContent } from './common'
|
||||
import SchemaViewer from './SchemaViewer.svelte'
|
||||
import FieldHeader from './FieldHeader.svelte'
|
||||
import { copyToClipboard } from '../utils'
|
||||
import FlowGraphViewer from './FlowGraphViewer.svelte'
|
||||
|
||||
import { Clipboard } from 'lucide-svelte'
|
||||
import YAML from 'yaml'
|
||||
import { yaml } from 'svelte-highlight/languages'
|
||||
import HighlightTheme from './HighlightTheme.svelte'
|
||||
import FlowViewerInner from './FlowViewerInner.svelte'
|
||||
|
||||
export let flow: {
|
||||
summary: string
|
||||
@@ -22,21 +17,12 @@
|
||||
export let initialOpen: number | undefined = undefined
|
||||
export let noSide = false
|
||||
|
||||
$: flowFiltered = {
|
||||
summary: flow.summary,
|
||||
description: flow.description,
|
||||
value: flow.value,
|
||||
schema: flow.schema
|
||||
}
|
||||
|
||||
export let noGraph: boolean = false
|
||||
|
||||
export let tab: 'ui' | 'raw' | 'schema' = noGraph ? 'schema' : 'ui'
|
||||
export let noSummary = false
|
||||
export let noGraphDownload = false
|
||||
|
||||
let rawType: 'json' | 'yaml' = 'yaml'
|
||||
|
||||
let open: { [id: number]: boolean } = {}
|
||||
if (initialOpen) {
|
||||
open[initialOpen] = true
|
||||
@@ -92,37 +78,8 @@
|
||||
<FlowGraphViewer download={!noGraphDownload} {noSide} {flow} overflowAuto />
|
||||
</div>
|
||||
</TabContent>
|
||||
<TabContent value="raw"
|
||||
><Tabs bind:selected={rawType} wrapperClass="mt-4">
|
||||
<Tab value="yaml">YAML</Tab>
|
||||
<Tab value="json">JSON</Tab>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="relative pt-2">
|
||||
<Button
|
||||
on:click={() =>
|
||||
copyToClipboard(
|
||||
rawType === 'yaml'
|
||||
? YAML.stringify(flowFiltered)
|
||||
: JSON.stringify(flowFiltered, null, 4)
|
||||
)}
|
||||
color="light"
|
||||
variant="border"
|
||||
size="xs"
|
||||
startIcon={{ icon: Clipboard }}
|
||||
btnClasses="absolute top-2 right-2 w-min"
|
||||
>
|
||||
Copy content
|
||||
</Button>
|
||||
<Highlight
|
||||
class="overflow-auto px-1"
|
||||
language={rawType === 'yaml' ? yaml : json}
|
||||
code={rawType === 'yaml'
|
||||
? YAML.stringify(flowFiltered)
|
||||
: JSON.stringify(flowFiltered, null, 4)}
|
||||
/>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</Tabs>
|
||||
<TabContent value="raw">
|
||||
<FlowViewerInner {flow} />
|
||||
</TabContent>
|
||||
<TabContent value="schema">
|
||||
<div class="my-4" />
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
<script lang="ts">
|
||||
import Highlight from 'svelte-highlight'
|
||||
import json from 'svelte-highlight/languages/json'
|
||||
import type { FlowValue } from '$lib/gen'
|
||||
import { Tab, Tabs, Button } from './common'
|
||||
import { copyToClipboard } from '../utils'
|
||||
|
||||
import { ArrowDown, Clipboard } from 'lucide-svelte'
|
||||
import YAML from 'yaml'
|
||||
import { yaml } from 'svelte-highlight/languages'
|
||||
import HighlightTheme from './HighlightTheme.svelte'
|
||||
|
||||
export let flow: {
|
||||
summary: string
|
||||
description?: string
|
||||
value: FlowValue
|
||||
schema?: any
|
||||
}
|
||||
|
||||
$: flowFiltered = {
|
||||
summary: flow.summary,
|
||||
description: flow.description,
|
||||
value: flow.value,
|
||||
schema: flow.schema
|
||||
}
|
||||
|
||||
let rawType: 'json' | 'yaml' = 'yaml'
|
||||
|
||||
function trimStringToLines(inputString: string, maxLines: number = 100): string {
|
||||
const lines = inputString?.split('\n') ?? []
|
||||
const linesToKeep = lines.slice(0, maxLines)
|
||||
|
||||
return linesToKeep.join('\n')
|
||||
}
|
||||
|
||||
let code: string = ''
|
||||
|
||||
function computeCode() {
|
||||
const str =
|
||||
rawType === 'json' ? JSON.stringify(flowFiltered, null, 4) : YAML.stringify(flowFiltered)
|
||||
|
||||
const numberOfLines = str.split('\n').length
|
||||
|
||||
if (numberOfLines > maxLines) {
|
||||
shouldDisplayLoadMore = true
|
||||
}
|
||||
|
||||
code = str
|
||||
}
|
||||
|
||||
let shouldDisplayLoadMore = false
|
||||
|
||||
$: flowFiltered && rawType && computeCode()
|
||||
|
||||
let maxLines = 100
|
||||
</script>
|
||||
|
||||
<HighlightTheme />
|
||||
|
||||
<div>
|
||||
<Tabs
|
||||
bind:selected={rawType}
|
||||
on:selected={() => {
|
||||
maxLines = 100
|
||||
}}
|
||||
>
|
||||
<Tab value="yaml">YAML</Tab>
|
||||
<Tab value="json">JSON</Tab>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="relative pt-2">
|
||||
<Button
|
||||
on:click={() =>
|
||||
copyToClipboard(
|
||||
rawType === 'yaml'
|
||||
? YAML.stringify(flowFiltered)
|
||||
: JSON.stringify(flowFiltered, null, 4)
|
||||
)}
|
||||
color="light"
|
||||
variant="border"
|
||||
size="xs"
|
||||
startIcon={{ icon: Clipboard }}
|
||||
btnClasses="absolute top-2 right-2 w-min"
|
||||
>
|
||||
Copy content
|
||||
</Button>
|
||||
|
||||
<div class={shouldDisplayLoadMore ? 'code-container' : ''}>
|
||||
<Highlight
|
||||
class="overflow-auto px-1"
|
||||
language={rawType === 'yaml' ? yaml : json}
|
||||
code={trimStringToLines(code, maxLines)}
|
||||
/>
|
||||
</div>
|
||||
{#if shouldDisplayLoadMore}
|
||||
<Button
|
||||
on:click={() => {
|
||||
maxLines += 500
|
||||
|
||||
// If the code is less than the max lines, we don't need to show the button
|
||||
if (maxLines >= code?.split('\n').length) {
|
||||
shouldDisplayLoadMore = false
|
||||
}
|
||||
}}
|
||||
color="light"
|
||||
size="xs"
|
||||
btnClasses="mb-2 mx-2"
|
||||
startIcon={{ icon: ArrowDown }}
|
||||
>
|
||||
Show more
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.code-container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.code-container::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100px;
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgb(var(--color-surface)));
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
@@ -1,13 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { Tabs, Tab, TabContent, Button } from '$lib/components/common'
|
||||
import { copyToClipboard } from '$lib/utils'
|
||||
import { CalendarCheck2, Clipboard, MailIcon, Terminal, Webhook } from 'lucide-svelte'
|
||||
import { Highlight } from 'svelte-highlight'
|
||||
import { yaml } from 'svelte-highlight/languages'
|
||||
import json from 'svelte-highlight/languages/json'
|
||||
import { Tabs, Tab, TabContent } from '$lib/components/common'
|
||||
import { CalendarCheck2, MailIcon, Terminal, Webhook } from 'lucide-svelte'
|
||||
|
||||
import { Pane, Splitpanes } from 'svelte-splitpanes'
|
||||
import YAML from 'yaml'
|
||||
import HighlightTheme from '../HighlightTheme.svelte'
|
||||
import FlowViewerInner from '../FlowViewerInner.svelte'
|
||||
|
||||
export let triggerSelected: 'webhooks' | 'email' | 'schedule' | 'cli' = 'webhooks'
|
||||
export let flow_json: any | undefined = undefined
|
||||
@@ -17,8 +14,6 @@
|
||||
|
||||
export let selected: string
|
||||
|
||||
let rawType: 'json' | 'yaml' = 'yaml'
|
||||
|
||||
$: if (hasStepDetails) {
|
||||
selected = 'flow_step'
|
||||
}
|
||||
@@ -97,36 +92,7 @@
|
||||
</Splitpanes>
|
||||
</TabContent>
|
||||
<TabContent value="raw" class="flex flex-col flex-1 h-full overflow-auto">
|
||||
<Tabs bind:selected={rawType} wrapperClass="mt-4">
|
||||
<Tab value="yaml">YAML</Tab>
|
||||
<Tab value="json">JSON</Tab>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="relative pt-2">
|
||||
<Button
|
||||
on:click={() =>
|
||||
copyToClipboard(
|
||||
rawType === 'yaml'
|
||||
? YAML.stringify(flow_json)
|
||||
: JSON.stringify(flow_json, null, 4)
|
||||
)}
|
||||
color="light"
|
||||
variant="border"
|
||||
size="xs"
|
||||
startIcon={{ icon: Clipboard }}
|
||||
btnClasses="absolute top-2 right-2 w-min"
|
||||
>
|
||||
Copy content
|
||||
</Button>
|
||||
<Highlight
|
||||
class="overflow-auto px-1"
|
||||
language={rawType === 'yaml' ? yaml : json}
|
||||
code={rawType === 'yaml'
|
||||
? YAML.stringify(flow_json)
|
||||
: JSON.stringify(flow_json, null, 4)}
|
||||
/>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</Tabs>
|
||||
<FlowViewerInner flow={flow_json} />
|
||||
</TabContent>
|
||||
<TabContent value="flow_step" class="flex flex-col flex-1 h-full">
|
||||
<slot name="flow_step" />
|
||||
|
||||
Reference in New Issue
Block a user