feat(data-grid): 优化查询结果展示宽度
This commit is contained in:
parent
ab186c30a5
commit
2cbce44628
|
|
@ -0,0 +1,52 @@
|
|||
import { computed, ref } from "vue";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { DATA_GRID_COL_AUTO_FIT_MAX_WIDTH, DATA_GRID_COL_MAX_WIDTH, DATA_GRID_COL_MIN_WIDTH } from "@/lib/dataGrid/dataGridColumnWidth";
|
||||
import { DATA_GRID_ROW_NUM_WIDTH, resizeDataGridColumnWidth, useDataGridColumnResize } from "@/composables/useDataGridColumnResize";
|
||||
|
||||
function createResizeState(options: { columns: string[]; rows: Array<Array<string | number | boolean | null>>; columnIndexes?: number[] }) {
|
||||
return useDataGridColumnResize({
|
||||
columns: computed(() => options.columns),
|
||||
sourceRows: computed(() => options.rows),
|
||||
columnIndexes: computed(() => options.columnIndexes ?? options.columns.map((_, index) => index)),
|
||||
gridRef: ref<HTMLDivElement>(),
|
||||
scrollbarGutter: ref(0),
|
||||
});
|
||||
}
|
||||
|
||||
describe("useDataGridColumnResize", () => {
|
||||
it("keeps compact query result columns at content width instead of filling the viewport", () => {
|
||||
const state = createResizeState({
|
||||
columns: ["id", "user_id"],
|
||||
rows: [
|
||||
[1, 10],
|
||||
[2, 20],
|
||||
],
|
||||
});
|
||||
|
||||
state.initColumnWidths();
|
||||
|
||||
expect(state.renderedColumnWidths.value).toEqual(state.columnWidths.value);
|
||||
expect(state.totalWidth.value).toBe(DATA_GRID_ROW_NUM_WIDTH + state.columnWidths.value.reduce((total, width) => total + width, 0));
|
||||
expect(Math.max(...state.renderedColumnWidths.value)).toBeLessThan(200);
|
||||
});
|
||||
|
||||
it("keeps default widths bounded but lets auto-fit use the wider cap", () => {
|
||||
const state = createResizeState({
|
||||
columns: ["description"],
|
||||
rows: [["x".repeat(120)]],
|
||||
});
|
||||
|
||||
state.initColumnWidths();
|
||||
expect(state.columnWidths.value[0]).toBe(DATA_GRID_COL_MAX_WIDTH);
|
||||
|
||||
state.autoFitColumn(0);
|
||||
|
||||
expect(state.columnWidths.value[0]).toBeGreaterThan(DATA_GRID_COL_MAX_WIDTH);
|
||||
expect(state.columnWidths.value[0]).toBeLessThanOrEqual(DATA_GRID_COL_AUTO_FIT_MAX_WIDTH);
|
||||
});
|
||||
|
||||
it("clamps manual column resizing to the minimum width", () => {
|
||||
expect(resizeDataGridColumnWidth(120, -200)).toBe(DATA_GRID_COL_MIN_WIDTH);
|
||||
expect(resizeDataGridColumnWidth(120, 30)).toBe(150);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
import { ref, computed, watch, type ComputedRef, type Ref } from "vue";
|
||||
import { useElementSize } from "@vueuse/core";
|
||||
import { calculateDataGridColumnWidth, DATA_GRID_AUTO_FIT_VALUE_TEXT_LIMIT, DATA_GRID_COL_AUTO_FIT_MAX_WIDTH, DATA_GRID_COL_MIN_WIDTH, DATA_GRID_SAMPLE_ROWS } from "@/lib/dataGrid/dataGridColumnWidth";
|
||||
|
||||
type CellValue = string | number | boolean | null;
|
||||
|
||||
export const DATA_GRID_ROW_NUM_WIDTH = 48;
|
||||
|
||||
export function resizeDataGridColumnWidth(startWidth: number, deltaX: number): number {
|
||||
return Math.max(DATA_GRID_COL_MIN_WIDTH, startWidth + deltaX);
|
||||
}
|
||||
|
||||
export interface UseDataGridColumnResizeOptions {
|
||||
columns: ComputedRef<string[]>;
|
||||
sourceRows: ComputedRef<CellValue[][]>;
|
||||
|
|
@ -15,10 +18,9 @@ export interface UseDataGridColumnResizeOptions {
|
|||
}
|
||||
|
||||
export function useDataGridColumnResize(options: UseDataGridColumnResizeOptions) {
|
||||
const { columns, sourceRows, columnIndexes, gridRef, scrollbarGutter } = options;
|
||||
const { columns, sourceRows, columnIndexes } = options;
|
||||
|
||||
const columnWidths = ref<number[]>([]);
|
||||
const { width: gridWidth } = useElementSize(gridRef);
|
||||
let isResizing = false;
|
||||
let previousColumnIndexes: number[] = [];
|
||||
|
||||
|
|
@ -59,7 +61,7 @@ export function useDataGridColumnResize(options: UseDataGridColumnResizeOptions)
|
|||
const startX = event.clientX;
|
||||
const startWidth = columnWidths.value[colIdx];
|
||||
const onMove = (e: MouseEvent) => {
|
||||
columnWidths.value[colIdx] = Math.max(DATA_GRID_COL_MIN_WIDTH, startWidth + e.clientX - startX);
|
||||
columnWidths.value[colIdx] = resizeDataGridColumnWidth(startWidth, e.clientX - startX);
|
||||
};
|
||||
const onUp = () => {
|
||||
document.removeEventListener("mousemove", onMove);
|
||||
|
|
@ -83,19 +85,7 @@ export function useDataGridColumnResize(options: UseDataGridColumnResizeOptions)
|
|||
});
|
||||
}
|
||||
|
||||
const baseTotalWidth = computed(() => columnWidths.value.reduce((a, b) => a + b, 0));
|
||||
|
||||
const renderedColumnWidths = computed(() => {
|
||||
const widths = columnWidths.value;
|
||||
if (widths.length === 0) return widths;
|
||||
|
||||
const availableWidth = Math.max(0, gridWidth.value - (scrollbarGutter?.value ?? 0));
|
||||
const extraWidth = Math.max(0, availableWidth - DATA_GRID_ROW_NUM_WIDTH - baseTotalWidth.value);
|
||||
if (extraWidth === 0) return widths;
|
||||
|
||||
const extraPerColumn = extraWidth / widths.length;
|
||||
return widths.map((width) => width + extraPerColumn);
|
||||
});
|
||||
const renderedColumnWidths = computed(() => columnWidths.value);
|
||||
|
||||
const totalWidth = computed(() => renderedColumnWidths.value.reduce((a, b) => a + b, 0) + DATA_GRID_ROW_NUM_WIDTH);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue