fix(views/table): wrong specs when restoring columns

This commit is contained in:
Elian Doran 2025-07-15 18:39:20 +03:00
parent 86f90e6685
commit a04804d3fa
No known key found for this signature in database
2 changed files with 49 additions and 17 deletions

View file

@ -3,6 +3,20 @@ import { restoreExistingData } from "./columns";
import type { ColumnDefinition } from "tabulator-tables"; import type { ColumnDefinition } from "tabulator-tables";
describe("restoreExistingData", () => { describe("restoreExistingData", () => {
it("maintains important columns properties", () => {
const newDefs: ColumnDefinition[] = [
{ field: "title", title: "Title", editor: "input" },
{ field: "noteId", title: "Note ID", formatter: "color", visible: false }
];
const oldDefs: ColumnDefinition[] = [
{ field: "title", title: "Title", width: 300, visible: true },
{ field: "noteId", title: "Note ID", width: 200, visible: true }
];
const restored = restoreExistingData(newDefs, oldDefs);
expect(restored[0].editor).toBe("input");
expect(restored[1].formatter).toBe("color");
});
it("should restore existing column data", () => { it("should restore existing column data", () => {
const newDefs: ColumnDefinition[] = [ const newDefs: ColumnDefinition[] = [
{ field: "title", title: "Title", editor: "input" }, { field: "title", title: "Title", editor: "input" },
@ -42,8 +56,26 @@ describe("restoreExistingData", () => {
{ field: "noteId", title: "Note ID", width: 200, visible: true } { field: "noteId", title: "Note ID", width: 200, visible: true }
]; ];
const restored = restoreExistingData(newDefs, oldDefs, 0); const restored = restoreExistingData(newDefs, oldDefs, 0);
expect(restored.length).toBe(3);
expect(restored[0].field).toBe("newColumn"); expect(restored[0].field).toBe("newColumn");
expect(restored[1].field).toBe("title"); expect(restored[1].field).toBe("title");
expect(restored[2].field).toBe("noteId"); expect(restored[2].field).toBe("noteId");
}); });
it("inserts new columns at the end if no position is specified", () => {
const newDefs: ColumnDefinition[] = [
{ field: "title", title: "Title", editor: "input" },
{ field: "noteId", title: "Note ID", visible: false },
{ field: "newColumn", title: "New Column", editor: "input" }
];
const oldDefs: ColumnDefinition[] = [
{ field: "title", title: "Title", width: 300, visible: true },
{ field: "noteId", title: "Note ID", width: 200, visible: true }
];
const restored = restoreExistingData(newDefs, oldDefs);
expect(restored.length).toBe(3);
expect(restored[0].field).toBe("title");
expect(restored[1].field).toBe("noteId");
expect(restored[2].field).toBe("newColumn");
});
}); });

View file

@ -93,30 +93,30 @@ export function buildColumnDefinitions(info: AttributeDefinitionInformation[], m
} }
export function restoreExistingData(newDefs: ColumnDefinition[], oldDefs: ColumnDefinition[], position?: number) { export function restoreExistingData(newDefs: ColumnDefinition[], oldDefs: ColumnDefinition[], position?: number) {
const existingColumns: ColumnDefinition[] = [] // 1. Keep existing columns, but restore their properties like width, visibility and order.
const byField = new Map<string, ColumnDefinition>; const newItemsByField = new Map<string, ColumnDefinition>(
for (const def of oldDefs) { newDefs.map(def => [def.field!, def])
byField.set(def.field ?? "", def); );
existingColumns.push(def); const existingColumns = oldDefs
} .map(item => {
return {
...newItemsByField.get(item.field!),
width: item.width,
visible: item.visible,
};
}) as ColumnDefinition[];
const newColumns: ColumnDefinition[] = []; // 2. Determine new columns.
for (const newDef of newDefs) { const existingFields = new Set(existingColumns.map(item => item.field));
const oldDef = byField.get(newDef.field ?? ""); const newColumns = newDefs
if (!oldDef) { .filter(item => !existingFields.has(item.field!));
newColumns.push(newDef);
} else {
newDef.width = oldDef.width;
newDef.visible = oldDef.visible;
}
}
// Clamp position to a valid range // Clamp position to a valid range
const insertPos = position !== undefined const insertPos = position !== undefined
? Math.min(Math.max(position, 0), existingColumns.length) ? Math.min(Math.max(position, 0), existingColumns.length)
: existingColumns.length; : existingColumns.length;
// Insert new columns at the specified position // 3. Insert new columns at the specified position
return [ return [
...existingColumns.slice(0, insertPos), ...existingColumns.slice(0, insertPos),
...newColumns, ...newColumns,