From ef13dc024f55e2da00d409f771976083efebb4c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E4=B8=AB=E8=AE=B2=E6=A2=B5?= Date: Thu, 3 Sep 2026 11:56:58 +0800 Subject: [PATCH] feat(grid): open cell http urls from hover overlay --- apps/desktop/src/components/grid/DataGrid.vue | 61 +++++++++++++++++-- .../DataGridCellDetailSelection.spec.ts | 8 +-- apps/desktop/src/i18n/locales/en.ts | 1 + apps/desktop/src/i18n/locales/es.ts | 1 + apps/desktop/src/i18n/locales/it.ts | 1 + apps/desktop/src/i18n/locales/ja.ts | 1 + apps/desktop/src/i18n/locales/ko.ts | 1 + apps/desktop/src/i18n/locales/pt-BR.ts | 1 + apps/desktop/src/i18n/locales/zh-CN.ts | 1 + apps/desktop/src/i18n/locales/zh-TW.ts | 1 + .../lib/dataGrid/canvasDataGridRenderer.ts | 8 +-- .../src/lib/dataGrid/cellExternalUrl.ts | 18 ++++++ .../app-tests/canvasDataGridRenderer.test.ts | 2 +- 13 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 apps/desktop/src/lib/dataGrid/cellExternalUrl.ts diff --git a/apps/desktop/src/components/grid/DataGrid.vue b/apps/desktop/src/components/grid/DataGrid.vue index 9688a9d899..a73bbf36c4 100644 --- a/apps/desktop/src/components/grid/DataGrid.vue +++ b/apps/desktop/src/components/grid/DataGrid.vue @@ -6,6 +6,7 @@ import { ArrowDown, ArrowUpDown, ArrowUpRight, + ExternalLink, Download, FileUp, Trash2, @@ -135,6 +136,7 @@ import { } from "@/lib/dataGrid/dataGridTranspose"; import { canApplyGridSelectionValue, canDeleteGridRowItem, canEditGridCellDetail, matchesRowStatusFilter, shouldShowQuickEntryDraftRow, type RowStatus, type RowStatusFilter } from "@/lib/dataGrid/gridRowStatus"; import { displayCellValue, firstLineCellDisplayValue, limitDataGridCellDisplay, SQLSERVER_DATA_GRID_CELL_DISPLAY_MAX_LENGTH, type CellValue } from "@/lib/dataGrid/cellValue"; +import { cellExternalUrl } from "@/lib/dataGrid/cellExternalUrl"; import { getApplicablePreviewActions, type PreviewAction } from "@/lib/dataGrid/resultPreviewRegistry"; import "@/lib/dataGrid/geometryMapPreview"; import { @@ -7889,8 +7891,9 @@ const canvasDetailButtonCell = computed(() => { const visibleRight = viewportWidth > 0 ? Math.min(viewportWidth, rect.left + rect.width) : rect.left + rect.width; const canQuickDownload = canQuickDownloadCellValue(target.rowIndex, target.col); const foreignKey = canvasCellForeignKey(target.rowIndex, target.col); - if (!cellDetailButtonEnabled.value && !canQuickDownload && !foreignKey) return null; - const minWidth = canvasDataGridActionOverlayWidth(canQuickDownload, !!foreignKey, cellDetailButtonEnabled.value) + 2; + const externalUrl = cellExternalUrl(displayItemAt(target.rowIndex)?.data[target.col]); + if (!cellDetailButtonEnabled.value && !canQuickDownload && !foreignKey && !externalUrl) return null; + const minWidth = canvasDataGridActionOverlayWidth(canQuickDownload, !!foreignKey, cellDetailButtonEnabled.value, !!externalUrl) + 2; if (rect.top < 0 || rect.top > viewportHeight - 1 || visibleRight - visibleLeft < minWidth) return null; return { rowIndex: target.rowIndex, @@ -7899,13 +7902,14 @@ const canvasDetailButtonCell = computed(() => { rect, canQuickDownload, foreignKey, + externalUrl, }; }); const canvasDetailButtonStyle = computed(() => { const cell = canvasDetailButtonCell.value; if (!cell) return {}; - const actionWidth = canvasDataGridActionOverlayWidth(cell.canQuickDownload, !!cell.foreignKey, cellDetailButtonEnabled.value); + const actionWidth = canvasDataGridActionOverlayWidth(cell.canQuickDownload, !!cell.foreignKey, cellDetailButtonEnabled.value, !!cell.externalUrl); const edgeGap = 6; return { left: `${Math.max(rowNumberWidth.value, cell.rect.left + cell.rect.width - actionWidth - edgeGap)}px`, @@ -7919,7 +7923,7 @@ const canvasRightAlignedActionCell = computed(() => { return { rowIndex: cell.rowIndex, visibleColIdx: cell.visibleColIdx, - reservedWidth: canvasDataGridActionReservedWidth(cell.canQuickDownload, !!cell.foreignKey, cellDetailButtonEnabled.value), + reservedWidth: canvasDataGridActionReservedWidth(cell.canQuickDownload, !!cell.foreignKey, cellDetailButtonEnabled.value, !!cell.externalUrl), }; }); @@ -9854,6 +9858,25 @@ function canQuickDownloadCellValue(rowIndex: number, columnIndex: number): boole return canDownloadDetailBinaryValue(cellDetailFor(rowIndex, columnIndex)); } +function cellExternalUrlFor(rowIndex: number, columnIndex: number): string | null { + return cellExternalUrl(displayItemAt(rowIndex)?.data[columnIndex]); +} + +function canOpenCellExternalUrl(rowIndex: number, columnIndex: number): boolean { + return cellExternalUrlFor(rowIndex, columnIndex) !== null; +} + +async function openCellExternalUrl(rowIndex: number, columnIndex: number) { + const url = cellExternalUrlFor(rowIndex, columnIndex); + if (!url) return; + try { + const { open } = await import("@tauri-apps/plugin-shell"); + await open(url); + } catch { + window.open(url, "_blank", "noopener,noreferrer"); + } +} + function downloadCellBinaryValue(rowIndex: number, columnIndex: number, mode: BinaryCellDownloadMode) { void downloadDetailBinaryValue(cellDetailFor(rowIndex, columnIndex), mode); } @@ -13033,6 +13056,16 @@ function openGridSnapshot() { +