feat(grid): configure cell detail button visibility

Closes #5593
This commit is contained in:
t8y2 committed 2026-08-24 19:54:35 +00:00
1 parent 3232195e1f
commit 68b0ab0476
17 files changed
+146 -9

No files matched your search

@@ -1,7 +1,7 @@
// @vitest-environment happy-dom
import { beforeEach, describe, expect, it, vi } from "vitest";
import { drawCanvasDataGrid, resolveCanvasBackingStoreMetrics, type DrawCanvasDataGridOptions } from "@/lib/dataGrid/canvasDataGridRenderer";
import { canvasDataGridActionOverlayWidth, canvasDataGridActionReservedWidth, drawCanvasDataGrid, resolveCanvasBackingStoreMetrics, type DrawCanvasDataGridOptions } from "@/lib/dataGrid/canvasDataGridRenderer";
function createMockCanvas(width = 800, height = 400) {
const canvas = document.createElement("canvas");
@@ -80,6 +80,18 @@ describe("drawCanvasDataGrid with frozen columns", () => {
} as CSSStyleDeclaration);
});
it.each([
[false, false, true, 22, 28],
[false, false, false, 0, 0],
[true, false, false, 22, 28],
[false, true, false, 22, 28],
[true, true, false, 44, 50],
[true, true, true, 66, 72],
])("reserves only enabled Canvas actions (download=%s, foreign key=%s, detail=%s)", (canQuickDownload, canNavigateForeignKey, showCellDetail, overlayWidth, reservedWidth) => {
expect(canvasDataGridActionOverlayWidth(canQuickDownload, canNavigateForeignKey, showCellDetail)).toBe(overlayWidth);
expect(canvasDataGridActionReservedWidth(canQuickDownload, canNavigateForeignKey, showCellDetail)).toBe(reservedWidth);
});
it("uses the exact observed device-pixel size instead of a nominal DPR", () => {
expect(
resolveCanvasBackingStoreMetrics({
@@ -195,13 +195,14 @@ export function fitCanvasText(ctx: CanvasRenderingContext2D, text: string, maxWi
return result;
}
export function canvasDataGridActionReservedWidth(canQuickDownload: boolean, canNavigateForeignKey = false): number {
return canvasDataGridActionOverlayWidth(canQuickDownload, canNavigateForeignKey) + 6;
export function canvasDataGridActionReservedWidth(canQuickDownload: boolean, canNavigateForeignKey = false, showCellDetail = true): number {
const overlayWidth = canvasDataGridActionOverlayWidth(canQuickDownload, canNavigateForeignKey, showCellDetail);
return overlayWidth > 0 ? overlayWidth + 6 : 0;
}
/** 悬浮按钮组宽度:每个按钮 20px + 2px 间距(detail 按钮始终存在) */
export function canvasDataGridActionOverlayWidth(canQuickDownload: boolean, canNavigateForeignKey = false): number {
return 22 + (canQuickDownload ? 22 : 0) + (canNavigateForeignKey ? 22 : 0);
/** 悬浮按钮组宽度:每个已启用按钮 20px + 2px 间距。 */
export function canvasDataGridActionOverlayWidth(canQuickDownload: boolean, canNavigateForeignKey = false, showCellDetail = true): number {
return (showCellDetail ? 22 : 0) + (canQuickDownload ? 22 : 0) + (canNavigateForeignKey ? 22 : 0);
}
export function resolveCanvasCellTextLayout(options: { drawX: number; colWidth: number; dpr: number; isRightAlign: boolean; reservedWidth?: number }): { textAnchorX: number; maxWidth: number } {
@@ -1,7 +1,10 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
import { EDITOR_SETTINGS_DRAFT_KEYS, editorSettingsDraftFromSettings, editorSettingsDraftChanged, editorSettingsPatchFromDraft, normalizeQueryResultMaxRowsDraft, normalizeTableOpenPageSizeDraft, shouldConfirmEditorSettingsDialogClose } from "../editorSettingsDraft";
import type { EditorSettings } from "@/stores/settingsStore";
const settingsDialogSource = readFileSync(new URL("../../../components/editor/EditorSettingsDialog.vue", import.meta.url), "utf8");
function makeSettings(overrides: Partial<EditorSettings> = {}): EditorSettings {
return {
autoCalculateTotalRows: false,
@@ -97,6 +100,10 @@ describe("EDITOR_SETTINGS_DRAFT_KEYS", () => {
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("dataGridTextFilterPanelHeight");
});
it("includes the cell detail button visibility", () => {
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("dataGridCellDetailButtonVisible");
});
it("includes completionTriggerMode", () => {
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("completionTriggerMode");
});
@@ -106,6 +113,16 @@ describe("EDITOR_SETTINGS_DRAFT_KEYS", () => {
});
});
describe("cell detail button settings control", () => {
it("binds the switch through apply and both reset paths", () => {
expect(settingsDialogSource).toContain("const editDataGridCellDetailButtonVisible = ref(settingsStore.editorSettings.dataGridCellDetailButtonVisible)");
expect(settingsDialogSource).toContain("dataGridCellDetailButtonVisible: editDataGridCellDetailButtonVisible.value");
expect(settingsDialogSource).toContain("editDataGridCellDetailButtonVisible.value = settingsStore.editorSettings.dataGridCellDetailButtonVisible");
expect(settingsDialogSource.match(/editDataGridCellDetailButtonVisible\.value = DEFAULT_EDITOR_SETTINGS\.dataGridCellDetailButtonVisible/g)).toHaveLength(2);
expect(settingsDialogSource).toContain('id="data-grid-cell-detail-button-visible" v-model="editDataGridCellDetailButtonVisible"');
});
});
describe("editorSettingsDraftFromSettings", () => {
it("round-trips a hidden line-number preference through the draft patch", () => {
const settings = makeSettings({ showLineNumbers: true });
@@ -281,6 +298,15 @@ describe("editorSettingsDraftChanged", () => {
});
describe("editorSettingsPatchFromDraft", () => {
it("applies, cancels, and re-enables the cell detail button visibility", () => {
const visible = editorSettingsDraftFromSettings(makeSettings({ dataGridCellDetailButtonVisible: true }));
const hidden = editorSettingsDraftFromSettings(makeSettings({ dataGridCellDetailButtonVisible: false }));
expect(editorSettingsPatchFromDraft(hidden, visible)).toEqual({ dataGridCellDetailButtonVisible: false });
expect(editorSettingsPatchFromDraft(visible, visible)).toEqual({});
expect(editorSettingsPatchFromDraft(visible, hidden)).toEqual({ dataGridCellDetailButtonVisible: true });
});
it("includes continueOnErrorOnBatch in patch when changed", () => {
const settings = makeSettings({ continueOnErrorOnBatch: false });
const draft = editorSettingsDraftFromSettings(settings);
@@ -44,6 +44,7 @@ export const EDITOR_SETTINGS_DRAFT_KEYS = [
"dataGridFilterEditorView",
"dataGridTextFilterPanelHeight",
"dataGridAutoTransposeSingleRow",
"dataGridCellDetailButtonVisible",
"pageSize",
"tableOpenPageSize",
"queryResultMaxRowsEnabled",