feat(views/table): automatic index col width

This commit is contained in:
Elian Doran
2025-07-17 20:44:31 +03:00
parent 9d7455d28a
commit 669a3d9dcf
4 changed files with 39 additions and 9 deletions

View File

@@ -119,4 +119,15 @@ describe("restoreExistingData", () => {
const restored = restoreExistingData(newDefs, oldDefs);
expect(restored[0].visible).toStrictEqual(false);
});
it("enforces size for non-resizable columns", () => {
const newDefs: ColumnDefinition[] = [
{ title: "#", resizable: false, width: "100px" },
]
const oldDefs: ColumnDefinition[] = [
{ title: "#", resizable: false, width: "120px" },
];
const restored = restoreExistingData(newDefs, oldDefs);
expect(restored[0].width).toStrictEqual("100px");
});
});

View File

@@ -41,7 +41,7 @@ const labelTypeMappings: Record<ColumnType, Partial<ColumnDefinition>> = {
}
};
export function buildColumnDefinitions(info: AttributeDefinitionInformation[], movableRows: boolean, existingColumnData: ColumnDefinition[] | undefined, position?: number) {
export function buildColumnDefinitions(info: AttributeDefinitionInformation[], movableRows: boolean, existingColumnData: ColumnDefinition[] | undefined, rowNumberHint: number, position?: number) {
let columnDefs: ColumnDefinition[] = [
{
title: "#",
@@ -50,6 +50,7 @@ export function buildColumnDefinitions(info: AttributeDefinitionInformation[], m
resizable: false,
frozen: true,
rowHandle: movableRows,
width: calculateIndexColumnWidth(rowNumberHint, movableRows),
formatter: RowNumberFormatter(movableRows)
},
{
@@ -66,6 +67,7 @@ export function buildColumnDefinitions(info: AttributeDefinitionInformation[], m
width: 400
}
];
console.log("Log ", rowNumberHint, columnDefs[0].width);
const seenFields = new Set<string>();
for (const { name, title, type } of info) {
@@ -102,7 +104,7 @@ export function restoreExistingData(newDefs: ColumnDefinition[], oldDefs: Column
.filter(item => (item.field && newItemsByField.has(item.field!)) || item.title === "#")
.map(oldItem => {
const data = newItemsByField.get(oldItem.field!)!;
if (oldItem.width !== undefined) {
if (oldItem.resizable && oldItem.width !== undefined) {
data.width = oldItem.width;
}
if (oldItem.visible !== undefined) {
@@ -128,3 +130,11 @@ export function restoreExistingData(newDefs: ColumnDefinition[], oldDefs: Column
...existingColumns.slice(insertPos)
];
}
function calculateIndexColumnWidth(rowNumberHint: number, movableRows: boolean): number {
let columnWidth = 16 * (rowNumberHint.toString().length || 1);
if (movableRows) {
columnWidth += 32;
}
return columnWidth;
}

View File

@@ -105,6 +105,7 @@ export default class TableView extends ViewMode<StateInfo> {
private colEditing?: TableColumnEditing;
private rowEditing?: TableRowEditing;
private maxDepth: number = -1;
private rowNumberHint: number = 1;
constructor(args: ViewModeArgs) {
super(args, "table");
@@ -137,9 +138,10 @@ export default class TableView extends ViewMode<StateInfo> {
this.persistentData = viewStorage?.tableData || {};
this.maxDepth = parseInt(this.parentNote.getLabelValue("maxNestingDepth") ?? "-1", 10);
const { definitions: rowData, hasSubtree: hasChildren } = await buildRowDefinitions(this.parentNote, info, this.maxDepth);
const { definitions: rowData, hasSubtree: hasChildren, rowNumber } = await buildRowDefinitions(this.parentNote, info, this.maxDepth);
this.rowNumberHint = rowNumber;
const movableRows = canReorderRows(this.parentNote) && !hasChildren;
const columnDefs = buildColumnDefinitions(info, movableRows, this.persistentData.columns);
const columnDefs = buildColumnDefinitions(info, movableRows, this.persistentData.columns, this.rowNumberHint);
let opts: Options = {
layout: "fitDataFill",
index: "branchId",
@@ -226,7 +228,7 @@ export default class TableView extends ViewMode<StateInfo> {
}
const info = getAttributeDefinitionInformation(this.parentNote);
const columnDefs = buildColumnDefinitions(info, !!this.api.options.movableRows, this.persistentData?.columns, this.colEditing?.getNewAttributePosition());
const columnDefs = buildColumnDefinitions(info, !!this.api.options.movableRows, this.persistentData?.columns, this.colEditing?.getNewAttributePosition(), this.rowNumberHint);
this.api.setColumns(columnDefs);
this.colEditing?.resetNewAttributePosition();
}
@@ -243,7 +245,8 @@ export default class TableView extends ViewMode<StateInfo> {
}
const info = getAttributeDefinitionInformation(this.parentNote);
const { definitions, hasSubtree } = await buildRowDefinitions(this.parentNote, info, this.maxDepth);
const { definitions, hasSubtree, rowNumber } = await buildRowDefinitions(this.parentNote, info, this.maxDepth);
this.rowNumberHint = rowNumber;
// Force a refresh if the data tree needs enabling/disabling.
if (this.api.options.dataTree !== hasSubtree) {

View File

@@ -14,8 +14,11 @@ export type TableData = {
export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDefinitionInformation[], maxDepth = -1, currentDepth = 0) {
const definitions: TableData[] = [];
const childBranches = parentNote.getChildBranches();
let hasSubtree = false;
for (const branch of parentNote.getChildBranches()) {
let rowNumber = childBranches.length;
for (const branch of childBranches) {
const note = await branch.getNote();
if (!note) {
continue; // Skip if the note is not found
@@ -41,8 +44,10 @@ export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDef
}
if (note.hasChildren() && (maxDepth < 0 || currentDepth < maxDepth)) {
def._children = (await buildRowDefinitions(note, infos, maxDepth, currentDepth + 1)).definitions;
const { definitions, rowNumber: subRowNumber } = (await buildRowDefinitions(note, infos, maxDepth, currentDepth + 1));
def._children = definitions;
hasSubtree = true;
rowNumber += subRowNumber;
}
definitions.push(def);
@@ -50,7 +55,8 @@ export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDef
return {
definitions,
hasSubtree
hasSubtree,
rowNumber
};
}