From 2f01107b09404ef29815d902104a036c630ea0b6 Mon Sep 17 00:00:00 2001 From: yyh Date: Thu, 22 Jan 2026 23:49:06 +0800 Subject: [PATCH] feat(sqlite-preview): add truncation notice when row limit is reached Display a notice at the bottom of SQLite table preview when data is truncated due to PREVIEW_ROW_LIMIT (1000 rows), informing users that additional rows are not displayed. --- .../viewer/sqlite-file-preview/data-table.tsx | 19 +++++++++++++++++-- .../viewer/sqlite-file-preview/index.tsx | 3 +++ .../sqlite-file-preview/table-panel.tsx | 3 +++ web/i18n/en-US/workflow.json | 1 + web/i18n/zh-Hans/workflow.json | 1 + 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/web/app/components/workflow/skill/viewer/sqlite-file-preview/data-table.tsx b/web/app/components/workflow/skill/viewer/sqlite-file-preview/data-table.tsx index 09b273d88b..cc23c70c78 100644 --- a/web/app/components/workflow/skill/viewer/sqlite-file-preview/data-table.tsx +++ b/web/app/components/workflow/skill/viewer/sqlite-file-preview/data-table.tsx @@ -11,6 +11,7 @@ type DataTableProps = { columns: string[] values: SQLiteValue[][] scrollRef: RefObject + isTruncated?: boolean } const MAX_CELL_LENGTH = 120 @@ -28,10 +29,10 @@ const formatValue = (value: SQLiteValue, t: TFunction<'workflow'>): string => { const truncateValue = (value: string): string => { if (value.length <= MAX_CELL_LENGTH) return value - return `${value.slice(0, MAX_CELL_LENGTH)}...` + return `${value.slice(0, MAX_CELL_LENGTH)}…` } -const DataTable: FC = ({ columns, values, scrollRef }) => { +const DataTable: FC = ({ columns, values, scrollRef, isTruncated = false }) => { const { t } = useTranslation('workflow') const keyColumnIndex = useMemo(() => { const candidates = new Set(['id', 'rowid', 'uuid']) @@ -106,6 +107,20 @@ const DataTable: FC = ({ columns, values, scrollRef }) => { )} + {isTruncated && ( + + + + + {t('skillSidebar.sqlitePreview.rowsTruncated', { limit: values.length })} + + + + + )} ) } diff --git a/web/app/components/workflow/skill/viewer/sqlite-file-preview/index.tsx b/web/app/components/workflow/skill/viewer/sqlite-file-preview/index.tsx index a87acc3860..59f37160d1 100644 --- a/web/app/components/workflow/skill/viewer/sqlite-file-preview/index.tsx +++ b/web/app/components/workflow/skill/viewer/sqlite-file-preview/index.tsx @@ -4,6 +4,7 @@ import { useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import Loading from '@/app/components/base/loading' import { useSQLiteDatabase } from '../../hooks/use-sqlite-database' +import { PREVIEW_ROW_LIMIT } from './constants' import TablePanel from './table-panel' import TableSelector from './table-selector' import { useSQLiteTable } from './use-sqlite-table' @@ -28,6 +29,7 @@ const SQLiteFilePreview: FC = ({ return tables[0] }, [selectedTableId, tables]) const tableState = useSQLiteTable({ selectedTable, queryTable }) + const isTruncated = tableState.data !== null && tableState.data.values.length >= PREVIEW_ROW_LIMIT if (!downloadUrl) { return ( @@ -82,6 +84,7 @@ const SQLiteFilePreview: FC = ({ isLoading={tableState.isLoading} error={tableState.error} scrollRef={tableScrollRef} + isTruncated={isTruncated} /> ) diff --git a/web/app/components/workflow/skill/viewer/sqlite-file-preview/table-panel.tsx b/web/app/components/workflow/skill/viewer/sqlite-file-preview/table-panel.tsx index 1a2c57267d..11e818ce17 100644 --- a/web/app/components/workflow/skill/viewer/sqlite-file-preview/table-panel.tsx +++ b/web/app/components/workflow/skill/viewer/sqlite-file-preview/table-panel.tsx @@ -10,6 +10,7 @@ type TablePanelProps = { isLoading: boolean error: Error | null scrollRef: RefObject + isTruncated?: boolean } const TablePanel: FC = ({ @@ -17,6 +18,7 @@ const TablePanel: FC = ({ isLoading, error, scrollRef, + isTruncated = false, }) => { const { t } = useTranslation('workflow') @@ -45,6 +47,7 @@ const TablePanel: FC = ({ columns={data.columns} values={data.values} scrollRef={scrollRef} + isTruncated={isTruncated} /> ) : ( diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 4195f2ccb2..4d44217e1e 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -1095,6 +1095,7 @@ "skillSidebar.sqlitePreview.emptyTables": "No tables available", "skillSidebar.sqlitePreview.loadError": "Failed to load SQLite preview", "skillSidebar.sqlitePreview.nullValue": "NULL", + "skillSidebar.sqlitePreview.rowsTruncated": "Showing first {{limit}} rows. Additional rows are not displayed.", "skillSidebar.sqlitePreview.selectTable": "Select a table", "skillSidebar.toggleFolder": "Toggle folder", "skillSidebar.unsavedChanges.confirmClose": "Discard", diff --git a/web/i18n/zh-Hans/workflow.json b/web/i18n/zh-Hans/workflow.json index 0b67d3378f..9641db0621 100644 --- a/web/i18n/zh-Hans/workflow.json +++ b/web/i18n/zh-Hans/workflow.json @@ -1086,6 +1086,7 @@ "skillSidebar.sqlitePreview.emptyTables": "没有可用的表", "skillSidebar.sqlitePreview.loadError": "加载 SQLite 预览失败", "skillSidebar.sqlitePreview.nullValue": "NULL", + "skillSidebar.sqlitePreview.rowsTruncated": "仅显示前 {{limit}} 行,更多行已省略。", "skillSidebar.sqlitePreview.selectTable": "选择表", "skillSidebar.unsavedChanges.confirmClose": "放弃", "skillSidebar.unsavedChanges.content": "您有未保存的更改,是否放弃?",