mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-20 08:18:52 +00:00
fix(grid): keep cloned rows next to their source
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { computed, ref, type Ref } from "vue";
|
||||
import { computed, nextTick, ref, type Ref } from "vue";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { clearDataGridPendingSnapshot, DATA_GRID_QUICK_ENTRY_DRAFT_ROW_ID, useDataGridEditor } from "@/composables/useDataGridEditor";
|
||||
import type { CellValue } from "@/lib/dataGrid/cellValue";
|
||||
@@ -514,6 +514,69 @@ describe("useDataGridEditor appendPastedRowsToNewRow", () => {
|
||||
|
||||
expect(editor.newRows.value[1]).toEqual(["Ada", "full payload", "Lovelace"]);
|
||||
});
|
||||
|
||||
it("places a cloned source row below its source row", () => {
|
||||
const editor = createEditor(undefined, true, undefined, undefined, [
|
||||
["Ada", null, "Lovelace"],
|
||||
["Grace", null, "Hopper"],
|
||||
]);
|
||||
editor.newRows.value = [];
|
||||
editor.newRowMeta.value = [];
|
||||
|
||||
editor.cloneRow(1);
|
||||
|
||||
expect(editor.newRowMeta.value[0]?.placement).toEqual({ anchorId: 1, position: "below" });
|
||||
});
|
||||
|
||||
it("keeps the scroll position when the cloned row anchors below its source row", async () => {
|
||||
class ScrollerStub {
|
||||
scrollTop = 0;
|
||||
scrollHeight = 4_000;
|
||||
}
|
||||
vi.stubGlobal("HTMLElement", ScrollerStub);
|
||||
const editor = createEditor(undefined, true, undefined, undefined, [
|
||||
["Ada", null, "Lovelace"],
|
||||
["Grace", null, "Hopper"],
|
||||
]);
|
||||
editor.newRows.value = [];
|
||||
editor.newRowMeta.value = [];
|
||||
const scroller = new ScrollerStub();
|
||||
editor.scrollerRef.value = scroller as unknown as NonNullable<typeof editor.scrollerRef.value>;
|
||||
|
||||
editor.cloneRow(1);
|
||||
await nextTick();
|
||||
vi.unstubAllGlobals();
|
||||
|
||||
expect(editor.newRowMeta.value[0]?.placement).toEqual({ anchorId: 1, position: "below" });
|
||||
expect(scroller.scrollTop).toBe(0);
|
||||
});
|
||||
|
||||
it("places a cloned pending row below the pending source row", () => {
|
||||
const editor = createEditor();
|
||||
editor.newRows.value = [];
|
||||
editor.newRowMeta.value = [];
|
||||
editor.addRows(1);
|
||||
|
||||
editor.cloneRow(-1);
|
||||
|
||||
expect(editor.newRowMeta.value[1]?.placement).toEqual({ anchorId: -1, position: "below" });
|
||||
});
|
||||
|
||||
it("places each multi-row clone below its corresponding source row", () => {
|
||||
const editor = createEditor(undefined, true, undefined, undefined, [
|
||||
["Ada", null, "Lovelace"],
|
||||
["Grace", null, "Hopper"],
|
||||
]);
|
||||
editor.newRows.value = [];
|
||||
editor.newRowMeta.value = [];
|
||||
|
||||
editor.cloneRows([1, 0]);
|
||||
|
||||
expect(editor.newRowMeta.value.map((meta) => meta.placement)).toEqual([
|
||||
{ anchorId: 1, position: "below" },
|
||||
{ anchorId: 0, position: "below" },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("useDataGridEditor saveChanges reload", () => {
|
||||
|
||||
@@ -272,7 +272,8 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
|
||||
if (value !== baseline[column]) edited.add(column);
|
||||
});
|
||||
}
|
||||
return allocateNewRowMeta(null, sourceIndex, [...edited]);
|
||||
const placement = item.isNew && item.newIndex !== undefined ? (inherited ? { anchorId: -inherited.token, position: "below" as const } : null) : sourceIndex === undefined ? null : { anchorId: sourceIndex, position: "below" as const };
|
||||
return allocateNewRowMeta(placement, sourceIndex, [...edited]);
|
||||
}
|
||||
// Restore a metadata snapshot and resume token allocation past its maximum so
|
||||
// newly created rows never collide with tokens held by restored rows (a fresh
|
||||
@@ -1218,7 +1219,8 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
|
||||
pushUndoSnapshot();
|
||||
rowStatusFilter.value = rowStatusFilterAfterAddingRow(rowStatusFilter.value);
|
||||
newRows.value.push(clonedData);
|
||||
newRowMeta.value.push(clonedRowMeta(item, clonedData));
|
||||
const clonedMeta = clonedRowMeta(item, clonedData);
|
||||
newRowMeta.value.push(clonedMeta);
|
||||
newRows.value = [...newRows.value];
|
||||
newRowMeta.value = [...newRowMeta.value];
|
||||
touchPendingChanges();
|
||||
@@ -1228,7 +1230,7 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
|
||||
const newRowId = -newRows.value.length;
|
||||
nextTick(() => {
|
||||
const el = getScrollerElement();
|
||||
if (el) el.scrollTop = el.scrollHeight;
|
||||
if (clonedMeta.placement === null && el) el.scrollTop = el.scrollHeight;
|
||||
startEdit(newRowId, initialEditColumn?.value ?? 0);
|
||||
});
|
||||
}
|
||||
|
||||
+1
-1
@@ -431,7 +431,7 @@ test("cloning a row preserves its source and edited columns for custom saves", a
|
||||
assert.deepEqual(savedMeta, [
|
||||
{
|
||||
token: 1,
|
||||
placement: null,
|
||||
placement: { anchorId: 0, position: "below" },
|
||||
sourceIndex: 0,
|
||||
editedColumns: [1],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user