mirror of
https://github.com/t8y2/dbx.git
synced 2026-11-02 00:29:30 +00:00
fix(grid): enable editing in transpose view
This commit is contained in:
@@ -91,9 +91,11 @@ import {
|
||||
import { formatGridSqlLiteral } from "@/lib/dataGridSql";
|
||||
import {
|
||||
buildVisibleTransposeRows,
|
||||
nextAppendedTransposeState,
|
||||
nextContextTransposeState,
|
||||
nextKeyboardTransposeState,
|
||||
nextTransposeState,
|
||||
nextTransposeStateForRecordCount,
|
||||
transposeFieldWidth,
|
||||
transposeScrollLeftForRecord,
|
||||
visibleTransposeRecordWindow,
|
||||
@@ -293,6 +295,7 @@ const imagePreviewSrc = ref("");
|
||||
const imagePreviewTitle = ref("");
|
||||
const transposeRowIndex = ref<number | null>(null);
|
||||
const showTranspose = ref(false);
|
||||
const preserveTransposeOnNextResult = ref(false);
|
||||
const transposeScrollRef = ref<HTMLElement | { $el?: HTMLElement }>();
|
||||
const transposeScrollLeft = ref(0);
|
||||
const transposeViewportWidth = ref(0);
|
||||
@@ -1432,7 +1435,7 @@ const {
|
||||
applyCellValue,
|
||||
cancelEdit,
|
||||
onEditKeydown,
|
||||
addRow,
|
||||
addRow: addEditorRow,
|
||||
cloneRow,
|
||||
showDeleteRowConfirm,
|
||||
requestDeleteRow,
|
||||
@@ -1515,6 +1518,7 @@ async function onToolbarCommit() {
|
||||
}
|
||||
|
||||
function onToolbarRollback() {
|
||||
preserveTransposeOnNextResult.value = showTranspose.value;
|
||||
discardChanges();
|
||||
emit(
|
||||
"reload",
|
||||
@@ -1527,6 +1531,11 @@ function onToolbarRollback() {
|
||||
);
|
||||
}
|
||||
|
||||
function addRow() {
|
||||
addEditorRow();
|
||||
focusAppendedTransposeRecord();
|
||||
}
|
||||
|
||||
const sortedRows = computed(() => {
|
||||
let indices = localFilteredRows.value;
|
||||
const q = deferredClientSearchText.value;
|
||||
@@ -2481,6 +2490,22 @@ function scrollTransposeRecordIntoView(rowIndex: number) {
|
||||
});
|
||||
}
|
||||
|
||||
function applyTransposeState(next: { showTranspose: boolean; transposeRowIndex: number | null }) {
|
||||
showTranspose.value = next.showTranspose;
|
||||
transposeRowIndex.value = next.transposeRowIndex;
|
||||
if (next.showTranspose) {
|
||||
nextTick(updateTransposeViewport);
|
||||
if (next.transposeRowIndex !== null) scrollTransposeRecordIntoView(next.transposeRowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
function focusAppendedTransposeRecord() {
|
||||
if (!showTranspose.value) return;
|
||||
nextTick(() => {
|
||||
applyTransposeState(nextAppendedTransposeState(true, displayItems.value.length));
|
||||
});
|
||||
}
|
||||
|
||||
function onTransposePinnedResizeStart(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
const startX = event.clientX;
|
||||
@@ -2578,6 +2603,8 @@ watch(isTransposeMode, (active) => {
|
||||
watch(
|
||||
() => props.result,
|
||||
() => {
|
||||
const shouldPreserveTranspose = preserveTransposeOnNextResult.value;
|
||||
preserveTransposeOnNextResult.value = false;
|
||||
if (getResetScrollAfterResult()) {
|
||||
clearResetScrollAfterResult();
|
||||
resetGridVerticalScroll();
|
||||
@@ -2585,7 +2612,13 @@ watch(
|
||||
clearCellSelection();
|
||||
clearRowSelection();
|
||||
closeCellDetails();
|
||||
closeTranspose();
|
||||
if (shouldPreserveTranspose) {
|
||||
applyTransposeState(
|
||||
nextTransposeStateForRecordCount(showTranspose.value, transposeRowIndex.value, displayItems.value.length),
|
||||
);
|
||||
} else {
|
||||
closeTranspose();
|
||||
}
|
||||
exitTransaction();
|
||||
},
|
||||
);
|
||||
@@ -3393,16 +3426,52 @@ defineExpose({
|
||||
<div
|
||||
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="relative shrink-0 border-r border-border/70 px-2 py-1.5 font-mono truncate"
|
||||
:class="{
|
||||
'text-muted-foreground italic': cell.isNull,
|
||||
'bg-primary/10': cell.recordIndex === transposeRowIndex,
|
||||
'bg-yellow-500/10 cell-dirty': displayItems[cell.recordIndex]?.isDirtyCol[cell.valueIndex],
|
||||
'cursor-text hover:bg-accent/50': canEditCellItem(
|
||||
displayItems[cell.recordIndex],
|
||||
cell.valueIndex,
|
||||
),
|
||||
}"
|
||||
:style="{ width: `${transposeRecordWidth}px` }"
|
||||
:title="cell.display"
|
||||
@click="selectTransposeRecord(cell.recordIndex)"
|
||||
@dblclick.stop="
|
||||
canEditCellItem(displayItems[cell.recordIndex], cell.valueIndex) &&
|
||||
startEdit(displayItems[cell.recordIndex].id, cell.valueIndex)
|
||||
"
|
||||
>
|
||||
{{ cell.display }}
|
||||
<template
|
||||
v-if="
|
||||
editingCell?.rowId === displayItems[cell.recordIndex]?.id &&
|
||||
editingCell?.col === cell.valueIndex
|
||||
"
|
||||
>
|
||||
<TemporalCellEditor
|
||||
v-if="temporalEditorKindForColumn(cell.valueIndex)"
|
||||
v-model="editValue"
|
||||
:kind="temporalEditorKindForColumn(cell.valueIndex)!"
|
||||
@cancel="cancelEdit"
|
||||
@commit="commitGridEdit"
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
v-model="editValue"
|
||||
autocapitalize="off"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
class="cell-edit-input absolute inset-0 bg-background border-2 border-primary px-2 py-0.5 text-xs outline-none z-10"
|
||||
@blur="commitEdit"
|
||||
@click.stop
|
||||
@keydown.stop="onEditKeydown"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ cell.display }}
|
||||
</template>
|
||||
</div>
|
||||
<div class="shrink-0" :style="{ width: `${transposeRecordWindow.afterWidth}px` }" />
|
||||
</div>
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface DataGridTransposeCell<T> {
|
||||
|
||||
export interface DataGridVisibleTransposeCell<T> extends DataGridTransposeCell<T> {
|
||||
recordIndex: number;
|
||||
valueIndex: number;
|
||||
}
|
||||
|
||||
export interface DataGridTransposeRow<T> {
|
||||
@@ -115,6 +116,24 @@ export function nextKeyboardTransposeState(options: KeyboardTransposeStateOption
|
||||
return { showTranspose: true, transposeRowIndex: anchorRowIndex };
|
||||
}
|
||||
|
||||
export function nextAppendedTransposeState(showTranspose: boolean, totalRecords: number): DataGridTransposeState {
|
||||
if (!showTranspose || totalRecords <= 0) return { showTranspose: false, transposeRowIndex: null };
|
||||
return { showTranspose: true, transposeRowIndex: totalRecords - 1 };
|
||||
}
|
||||
|
||||
export function nextTransposeStateForRecordCount(
|
||||
showTranspose: boolean,
|
||||
transposeRowIndex: number | null,
|
||||
totalRecords: number,
|
||||
): DataGridTransposeState {
|
||||
if (!showTranspose || totalRecords <= 0) return { showTranspose: false, transposeRowIndex: null };
|
||||
const requestedRowIndex = transposeRowIndex ?? 0;
|
||||
return {
|
||||
showTranspose: true,
|
||||
transposeRowIndex: Math.max(0, Math.min(totalRecords - 1, requestedRowIndex)),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildTransposeRows<T>(options: BuildTransposeRowsOptions<T>): Array<DataGridTransposeRow<T>> {
|
||||
return options.columns.map((column, columnIndex) => {
|
||||
return {
|
||||
@@ -149,6 +168,7 @@ export function buildVisibleTransposeRows<T>(
|
||||
return [
|
||||
{
|
||||
recordIndex,
|
||||
valueIndex,
|
||||
value,
|
||||
display: options.displayValue(value, column, columnIndex, recordIndex),
|
||||
isNull: value === null,
|
||||
|
||||
Reference in New Issue
Block a user