feat(grid): optimize transpose view toggle

This commit is contained in:
t8y2 committed 2026-05-21 23:15:44 +08:00
1 parent 2569d54f68
commit a159dcfc83
13 files changed
+237 -21

No files matched your search

@@ -647,7 +647,7 @@ watch(
</nav>
<div class="min-w-0 flex-1 overflow-hidden px-1 flex flex-col">
<div class="min-h-0 flex-1 overflow-y-auto overflow-x-hidden pr-1">
<div class="min-h-0 flex-1 overflow-y-auto overflow-x-hidden px-1 pr-2">
<section v-if="activeSettingsTab === 'editor'" class="flex flex-col gap-5 py-2">
<div class="grid gap-4 md:grid-cols-[minmax(0,1fr)_220px]">
<!-- Font Family -->
@@ -847,7 +847,7 @@ watch(
<textarea
id="sidebar-hidden-table-prefixes"
v-model="editSidebarHiddenTablePrefixes"
class="min-h-24 w-full rounded-md border border-input bg-background px-3 py-2 text-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
class="min-h-24 w-full rounded-md border border-input bg-background px-3 py-2 text-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring"
:placeholder="t('settings.sidebarHiddenTablePrefixesPlaceholder')"
/>
<p class="text-xs text-muted-foreground">
+52 -18
View File
@@ -90,8 +90,9 @@ import {
} from "@/lib/tableEditing";
import { formatGridSqlLiteral } from "@/lib/dataGridSql";
import {
buildTransposeRows,
buildVisibleTransposeRows,
nextContextTransposeState,
nextKeyboardTransposeState,
nextTransposeState,
transposeFieldWidth,
transposeScrollLeftForRecord,
@@ -118,7 +119,7 @@ import {
type DateTimeFormatterUnit,
} from "@/lib/columnFormatter";
import { temporalCellEditorKind, type TemporalCellEditorKind } from "@/lib/dataGridTemporalEditor";
import { isCancelSearchShortcut, isFocusSearchShortcut } from "@/lib/keyboardShortcuts";
import { isCancelSearchShortcut, isFocusSearchShortcut, isToggleTransposeShortcut } from "@/lib/keyboardShortcuts";
import { dataGridHeaderContentWidth, scrollbarGutterWidth } from "@/lib/dataGridScrollGutter";
import { dataGridSaveActionMode, dataGridSaveToolbarState } from "@/lib/dataGridSaveUi";
import { appendColumnValueFilterCondition, buildColumnValueFilterCondition } from "@/lib/dataGridColumnFilter";
@@ -2258,6 +2259,33 @@ function scrollCellIntoView(rowIndex: number, colIndex: number) {
});
}
function currentTransposeRequestedRowIndex(): number {
const position = currentSelectedCellPosition();
if (position) return position.rowIndex;
if (transposeRowIndex.value !== null) return transposeRowIndex.value;
return 0;
}
function toggleKeyboardTranspose(): boolean {
if (displayItems.value.length === 0) return false;
const next = nextKeyboardTransposeState({
showTranspose: showTranspose.value,
transposeRowIndex: transposeRowIndex.value,
requestedRowIndex: currentTransposeRequestedRowIndex(),
rowIds: displayItems.value.map((item) => item.id),
selectedRowIds: selectedRowIds.value,
selectedRange: selectedRange.value,
});
showTranspose.value = next.showTranspose;
transposeRowIndex.value = next.transposeRowIndex;
if (next.showTranspose) {
closeCellDetails();
nextTick(updateTransposeViewport);
if (next.transposeRowIndex !== null) scrollTransposeRecordIntoView(next.transposeRowIndex);
}
return true;
}
function moveSelectedCell(rowDelta: number, colDelta: number): boolean {
const position = currentSelectedCellPosition();
if (!position || editingCell.value || displayItems.value.length === 0 || visibleColumnIndexes.value.length === 0)
@@ -2293,6 +2321,10 @@ async function onGridKeydown(event: KeyboardEvent) {
return;
}
if (eventTargetAllowsNativeClipboard(event)) return;
if (isToggleTransposeShortcut(event, settingsStore.editorSettings.shortcuts) && toggleKeyboardTranspose()) {
event.preventDefault();
return;
}
if (event.key === "ArrowLeft" && moveTransposeRecordSelection(-1)) {
event.preventDefault();
return;
@@ -2375,15 +2407,6 @@ const transposePinnedWidth = computed(
() => transposePinnedWidthOverride.value ?? transposeFieldWidth(visibleColumns.value),
);
const transposeRows = computed(() => {
return buildTransposeRows({
columns: visibleColumns.value,
records: displayItems.value.map((item) => visibleColumnIndexes.value.map((columnIndex) => item.data[columnIndex])),
typeByColumn: columnTypeMap.value,
displayValue: (value, _column, index) => formatCell(value, visibleColumnIndexes.value[index]),
});
});
const isTransposeMode = computed(() => showTranspose.value && transposeRows.value.length > 0);
const transposeRecordWindow = computed(() =>
visibleTransposeRecordWindow({
totalRecords: displayItems.value.length,
@@ -2398,6 +2421,17 @@ const visibleTransposeRecordIndexes = computed(() => {
const window = transposeRecordWindow.value;
return Array.from({ length: window.end - window.start }, (_, offset) => window.start + offset);
});
const transposeRows = computed(() => {
return buildVisibleTransposeRows({
columns: visibleColumns.value,
records: displayItems.value.map((item) => item.data),
recordIndexes: visibleTransposeRecordIndexes.value,
valueIndexes: visibleColumnIndexes.value,
typeByColumn: columnTypeMap.value,
displayValue: (value, _column, index) => formatCell(value, visibleColumnIndexes.value[index]),
});
});
const isTransposeMode = computed(() => showTranspose.value && transposeRows.value.length > 0);
const transposeTotalWidth = computed(
() => transposePinnedWidth.value + displayItems.value.length * transposeRecordWidth.value,
);
@@ -3344,18 +3378,18 @@ defineExpose({
</div>
<div class="shrink-0" :style="{ width: `${transposeRecordWindow.beforeWidth}px` }" />
<div
v-for="recordIndex in visibleTransposeRecordIndexes"
:key="`${item.id}:${recordIndex}`"
v-for="cell in item.values"
:key="`${item.id}:${cell.recordIndex}`"
class="shrink-0 border-r border-border/70 px-2 py-1.5 font-mono truncate"
:class="{
'text-muted-foreground italic': item.values[recordIndex]?.isNull,
'bg-primary/10': recordIndex === transposeRowIndex,
'text-muted-foreground italic': cell.isNull,
'bg-primary/10': cell.recordIndex === transposeRowIndex,
}"
:style="{ width: `${transposeRecordWidth}px` }"
:title="item.values[recordIndex]?.display"
@click="selectTransposeRecord(recordIndex)"
:title="cell.display"
@click="selectTransposeRecord(cell.recordIndex)"
>
{{ item.values[recordIndex]?.display }}
{{ cell.display }}
</div>
<div class="shrink-0" :style="{ width: `${transposeRecordWindow.afterWidth}px` }" />
</div>