fix(frontend): add warning when integer number if too big for frontend (#5340)

This commit is contained in:
HugoCasa
2025-02-20 14:19:27 +01:00
committed by GitHub
parent 8b6df77ce1
commit d7cbdf0e70
2 changed files with 77 additions and 36 deletions
@@ -76,6 +76,7 @@
| 'pdf'
| undefined
let hasBigInt = false
$: resultKind = inferResultKind(result)
export let forceJson = false
@@ -168,6 +169,13 @@
largeObject = size > DISPLAY_MAX_SIZE
}
if (!largeObject) {
hasBigInt = checkIfHasBigInt(result)
if (hasBigInt) {
return 'json'
}
}
if (Array.isArray(result)) {
if (result.length === 0) {
return 'json'
@@ -263,6 +271,21 @@
}
}
function checkIfHasBigInt(result: any) {
if (typeof result === 'number' && Number.isInteger(result) && !Number.isSafeInteger(result)) {
return true
}
if (Array.isArray(result)) {
return result.some(checkIfHasBigInt)
}
if (result && typeof result === 'object') {
return Object.values(result).some(checkIfHasBigInt)
}
return false
}
function contentOrRootString(obj: string | { filename: string; content: string } | undefined) {
if (obj == undefined || obj == null) {
return ''
@@ -401,14 +424,17 @@
/>
{/each}</div
>
{:else if resultKind === 'nondisplayable'}<div class="text-red-400">Non displayable object</div
>{:else}<div
{:else if resultKind === 'nondisplayable'}
<div class="text-red-400">Non displayable object</div>
{:else}
<div
class="inline-highlight relative grow {['plain', 'markdown'].includes(resultKind ?? '')
? ''
: 'min-h-[160px]'}"
>{#if result != undefined && length != undefined && largeObject != undefined}<div
class="flex justify-between items-center w-full"
><div class="text-tertiary text-sm">
>
{#if result != undefined && length != undefined && largeObject != undefined}
<div class="flex justify-between items-center w-full">
<div class="text-tertiary text-sm flex flex-row gap-2 items-center">
{#if !hideAsJson && !['json', 's3object'].includes(resultKind ?? '') && typeof result === 'object'}<ToggleButtonGroup
class="h-6"
selected={forceJson ? 'json' : resultKind?.startsWith('table-') ? 'table' : 'pretty'}
@@ -458,8 +484,9 @@
</button>
{/if}
</div>
</div><div class="grow"
>{#if !forceJson && resultKind === 'table-col'}
</div>
<div class="grow">
{#if !forceJson && resultKind === 'table-col'}
{@const data = 'table-col' in result ? result['table-col'] : result}
<AutoDataTable objects={objectOfArraysToObjects(data)} />
{:else if !forceJson && resultKind === 'table-row'}
@@ -779,7 +806,7 @@
<div class="prose-xs dark:prose-invert !list-disc !list-outside">
<Markdown md={result?.md ?? result?.markdown} />
</div>
{:else if largeObject}
{:else if largeObject || hasBigInt}
{#if result && typeof result === 'object' && 'file' in result}
<div
><a
@@ -789,34 +816,36 @@
>
</div>
{:else}
<div class="text-sm text-tertiary"
><a
download="{filename ?? 'result'}.json"
href={workspaceId && jobId
? nodeId
? `${base}/api/w/${workspaceId}/jobs/result_by_id/${jobId}/${nodeId}`
: `${base}/api/w/${workspaceId}/jobs_u/completed/get_result/${jobId}`
: `data:text/json;charset=utf-8,${encodeURIComponent(toJsonStr(result))}`}
>
Download {filename ? '' : 'as JSON'}
</a>
{#if download_as_csv}
<DownloadCsv
getContent={() => convertJsonToCsv(result)}
customText="Download as CSV"
/>
{/if}
</div>
{#if largeObject}
<div class="text-sm text-tertiary"
><a
download="{filename ?? 'result'}.json"
href={workspaceId && jobId
? nodeId
? `${base}/api/w/${workspaceId}/jobs/result_by_id/${jobId}/${nodeId}`
: `${base}/api/w/${workspaceId}/jobs_u/completed/get_result/${jobId}`
: `data:text/json;charset=utf-8,${encodeURIComponent(toJsonStr(result))}`}
>
Download {filename ? '' : 'as JSON'}
</a>
{#if download_as_csv}
<DownloadCsv
getContent={() => convertJsonToCsv(result)}
customText="Download as CSV"
/>
{/if}
</div>
<div class="mt-1 mb-2">
<Alert
size="xs"
title="Large result detected"
type="warning"
tooltip="We recommend using persistent object storage for large result. See docs for setting up an object storage service integration using s3 or any other s3 compatible services."
documentationLink="https://www.windmill.dev/docs/core_concepts/persistent_storage#object-storage-for-large-data-s3-r2-minio-azure-blob"
/>
</div>
<div class="mt-1 mb-2">
<Alert
size="xs"
title="Large result detected"
type="warning"
tooltip="We recommend using persistent object storage for large result. See docs for setting up an object storage service integration using s3 or any other s3 compatible services."
documentationLink="https://www.windmill.dev/docs/core_concepts/persistent_storage#object-storage-for-large-data-s3-r2-minio-azure-blob"
/>
</div>
{/if}
{#if result && result != 'WINDMILL_TOO_BIG'}
<ObjectViewer json={result} />
{/if}
@@ -6,10 +6,11 @@
import { NEVER_TESTED_THIS_FAR } from '../flows/models'
import Portal from '$lib/components/Portal.svelte'
import { Button } from '$lib/components/common'
import { Download, PanelRightOpen } from 'lucide-svelte'
import { Download, PanelRightOpen, TriangleAlertIcon } from 'lucide-svelte'
import S3FilePicker from '../S3FilePicker.svelte'
import { workspaceStore } from '$lib/stores'
import AnimatedButton from '$lib/components/common/button/AnimatedButton.svelte'
import Popover from '../Popover.svelte'
export let json: any
export let level = 0
@@ -166,6 +167,17 @@
<span class="text-2xs">null</span>
{:else if typeof json[key] == 'string'}
<span class="text-2xs">"{truncate(json[key], 200)}"</span>
{:else if typeof json[key] == 'number' && Number.isInteger(json[key]) && !Number.isSafeInteger(json[key])}
<span class="inline-flex flex-row gap-1 items-center text-2xs">
{truncate(JSON.stringify(json[key]), 200)}
<Popover>
<TriangleAlertIcon size={14} class="text-yellow-500 mb-0.5" />
<svelte:fragment slot="text">
This number is too large for the frontend to handle correctly and may be
rounded.
</svelte:fragment>
</Popover>
</span>
{:else}
<span class="text-2xs">
{truncate(JSON.stringify(json[key]), 200)}