fix(grid): hint truncated values in grid search

Closes #7279
This commit is contained in:
t8y2 committed 2026-08-26 18:43:21 +08:00
1 parent 138e48d347
commit 71344c637c
11 files changed
+43

No files matched your search

@@ -12092,6 +12092,7 @@ function currentGridContextMenuItems(): ContextMenuItem[] {
:match-count="searchMatches.length"
:current-match-index="currentMatchIndex"
:has-deferred-search-text="!!deferredClientSearchText"
:values-truncated="(props.result.large_value_cells?.length ?? 0) > 0"
@keydown="onSearchKeydown"
@navigate="navigateMatch"
@close="closeSearch"
@@ -12,6 +12,8 @@ const props = defineProps<{
matchCount: number;
currentMatchIndex: number;
hasDeferredSearchText: boolean;
/** 结果里含被截断显示的长值(large_value_cells),搜索只覆盖显示文本。 */
valuesTruncated?: boolean;
}>();
const searchText = defineModel<string>("text", { default: "" });
@@ -72,6 +74,11 @@ defineExpose({
<span>{{ suggestion }}</span>
</div>
</div>
<!-- 截断标记:表格预览对长文本/JSON 值做服务端截断,客户端搜索只能覆盖
显示前缀,匹配数可能少于 SQL 查询(#7279)。 -->
<span v-if="props.valuesTruncated && (props.matchCount > 0 || props.hasDeferredSearchText)" data-grid-search-truncated-hint class="text-xs text-amber-600 dark:text-amber-400 shrink-0 cursor-help" :title="t('grid.searchTruncatedValuesHint')" :aria-label="t('grid.searchTruncatedValuesHint')"
>≈</span
>
<span v-if="props.matchCount > 0" class="text-xs text-muted-foreground shrink-0">{{ props.currentMatchIndex + 1 }}/{{ props.matchCount }}</span>
<span v-else-if="props.hasDeferredSearchText" class="text-xs text-muted-foreground shrink-0">0</span>
<button
@@ -321,6 +321,33 @@ describe("DataGrid context menu target lifecycle", () => {
expect(contextMenuLabels()).toContain("Filter");
});
async function openGridSearchAndType(host: HTMLElement, query: string) {
await settle();
const gridRoot = host.querySelector<HTMLElement>("[data-grid-root]");
if (!gridRoot) throw new Error("Grid root not found");
gridRoot.dispatchEvent(new KeyboardEvent("keydown", { key: "f", ctrlKey: true, bubbles: true, cancelable: true }));
await settle();
const input = host.querySelector<HTMLInputElement>("input[type=search]");
if (!input) throw new Error("Search input not found");
input.value = query;
input.dispatchEvent(new Event("input", { bubbles: true }));
await settle();
// useDataGridSearch 防抖 150ms,等待 deferredSearchText 生效
await new Promise((resolve) => setTimeout(resolve, 400));
}
it("marks the search overlay when truncated large values may hide matches (issue #7279)", async () => {
const { host } = mountGrid(largeValueResult(1, "preview"));
await openGridSearchAndType(host, "prev");
expect(host.querySelector("[data-grid-search-truncated-hint]")).toBeTruthy();
});
it("does not show the truncation hint for fully loaded values", async () => {
const { host } = mountGrid(hydratedResult(1, "preview"));
await openGridSearchAndType(host, "prev");
expect(host.querySelector("[data-grid-search-truncated-hint]")).toBeNull();
});
it("offers toolbar-equivalent refresh in the cell context menu (issue #7273)", async () => {
const onReload = vi.fn();
const { host } = mountGrid(hydratedResult(1, "value"), onReload);
+1
View File
@@ -1847,6 +1847,7 @@ export default {
batchAppendPasteEmpty: "The clipboard does not contain rows to add.",
batchAppendPasteReadonlyColumn: "The pasted data includes a column that cannot be edited.",
search: "Search...",
searchTruncatedValuesHint: "Some long text/JSON values are truncated for display; the search only covers loaded cell text and may miss matches.",
searchOrWhere: "Search, or enter a WHERE clause...",
applyWhere: "Apply WHERE",
filterRows: "Filter rows",
+1
View File
@@ -1714,6 +1714,7 @@ export default withEnglishFallback({
unfreezeColumns: "Desinmovilizar columnas",
pasted: "¡Pegado!",
search: "Buscar...",
searchTruncatedValuesHint: "Algunos valores largos de texto/JSON están truncados para su visualización; la búsqueda solo cubre el contenido cargado y puede encontrar menos coincidencias que la consulta SQL.",
searchOrWhere: "Buscar, o ingresar una cláusula WHERE...",
applyWhere: "Aplicar WHERE",
filterRows: "Filtrar filas",
+1
View File
@@ -1712,6 +1712,7 @@ export default withEnglishFallback({
unfreezeColumns: "Sblocca colonne",
pasted: "Incollato!",
search: "Cerca...",
searchTruncatedValuesHint: "Alcuni valori di testo/JSON lunghi sono troncati per la visualizzazione; la ricerca copre solo il contenuto caricato e può trovare meno corrispondenze della query SQL.",
searchOrWhere: "Cerca o inserisci una clausola WHERE...",
applyWhere: "Applica WHERE",
filterRows: "Filtra righe",
+1
View File
@@ -1730,6 +1730,7 @@ export default withEnglishFallback({
unfreezeColumns: "列の固定を解除",
pasted: "貼り付けました!",
search: "検索...",
searchTruncatedValuesHint: "一部の長いテキスト/JSON 値は表示用に切り詰められています。検索は読み込み済みの表示内容のみが対象で、SQL クエリより一致数が少なくなることがあります。",
searchOrWhere: "検索、またはWHERE句を入力...",
applyWhere: "WHEREを適用",
filterRows: "行をフィルター",
+1
View File
@@ -1695,6 +1695,7 @@ export default withEnglishFallback({
unfreezeColumns: "컬럼 고정 해제",
pasted: "붙여넣었습니다!",
search: "검색...",
searchTruncatedValuesHint: "일부 긴 텍스트/JSON 값은 표시를 위해 잘렸습니다. 검색은 로드된 표시 내용만 대상으로 하며 SQL 쿼리보다 일치 수가 적을 수 있습니다.",
searchOrWhere: "검색 또는 WHERE 절 입력...",
applyWhere: "WHERE 적용",
filterRows: "행 필터",
+1
View File
@@ -1714,6 +1714,7 @@ export default withEnglishFallback({
unfreezeColumns: "Descongelar colunas",
pasted: "Colado!",
search: "Pesquisar...",
searchTruncatedValuesHint: "Alguns valores longos de texto/JSON estão truncados para exibição; a busca cobre apenas o conteúdo carregado e pode encontrar menos correspondências que a consulta SQL.",
searchOrWhere: "Pesquise, ou insira uma cláusula WHERE...",
applyWhere: "Aplicar WHERE",
filterRows: "Filtrar linhas",
+1
View File
@@ -1772,6 +1772,7 @@ export default withEnglishFallback({
batchAppendPasteEmpty: "剪贴板中没有可新增的行。",
batchAppendPasteReadonlyColumn: "粘贴的数据包含不可编辑的列。",
search: "搜索...",
searchTruncatedValuesHint: "部分长文本/JSON 值已截断显示,搜索仅覆盖已加载的显示内容,匹配数可能少于 SQL 查询。",
searchOrWhere: "搜索,或输入 WHERE 条件...",
applyWhere: "应用 WHERE",
filterRows: "筛选行",
+1
View File
@@ -1713,6 +1713,7 @@ export default withEnglishFallback({
unfreezeColumns: "取消凍結",
pasted: "已貼上!",
search: "搜尋……",
searchTruncatedValuesHint: "部分長文字/JSON 值已截斷顯示,搜尋僅涵蓋已載入的顯示內容,符合數可能少於 SQL 查詢。",
searchOrWhere: "搜尋,或輸入 WHERE 條件……",
applyWhere: "套用 WHERE",
filterRows: "篩選列",