diff --git a/apps/client/src/widgets/view_widgets/table_view/columns.ts b/apps/client/src/widgets/view_widgets/table_view/columns.ts index db42425c5..ad1fa334f 100644 --- a/apps/client/src/widgets/view_widgets/table_view/columns.ts +++ b/apps/client/src/widgets/view_widgets/table_view/columns.ts @@ -41,8 +41,8 @@ const labelTypeMappings: Record> = { } }; -export function buildColumnDefinitions(info: AttributeDefinitionInformation[], movableRows: boolean, existingColumnData?: ColumnDefinition[]) { - const columnDefs: ColumnDefinition[] = [ +export function buildColumnDefinitions(info: AttributeDefinitionInformation[], movableRows: boolean, existingColumnData?: ColumnDefinition[], position?: number) { + let columnDefs: ColumnDefinition[] = [ { title: "#", headerSort: false, @@ -86,25 +86,40 @@ export function buildColumnDefinitions(info: AttributeDefinitionInformation[], m } if (existingColumnData) { - restoreExistingData(columnDefs, existingColumnData); + columnDefs = restoreExistingData(columnDefs, existingColumnData, position); } return columnDefs; } -function restoreExistingData(newDefs: ColumnDefinition[], oldDefs: ColumnDefinition[]) { +function restoreExistingData(newDefs: ColumnDefinition[], oldDefs: ColumnDefinition[], position?: number) { const byField = new Map; for (const def of oldDefs) { byField.set(def.field ?? "", def); } + const newColumns: ColumnDefinition[] = []; + const existingColumns: ColumnDefinition[] = [] for (const newDef of newDefs) { const oldDef = byField.get(newDef.field ?? ""); if (!oldDef) { - continue; + newColumns.push(newDef); + } else { + newDef.width = oldDef.width; + newDef.visible = oldDef.visible; + existingColumns.push(newDef); } - - newDef.width = oldDef.width; - newDef.visible = oldDef.visible; } + + // Clamp position to a valid range + const insertPos = position !== undefined + ? Math.min(Math.max(position, 0), existingColumns.length) + : existingColumns.length; + + // Insert new columns at the specified position + return [ + ...existingColumns.slice(0, insertPos), + ...newColumns, + ...existingColumns.slice(insertPos) + ]; } diff --git a/apps/client/src/widgets/view_widgets/table_view/context_menu.ts b/apps/client/src/widgets/view_widgets/table_view/context_menu.ts index dd229ae87..005d76fc4 100644 --- a/apps/client/src/widgets/view_widgets/table_view/context_menu.ts +++ b/apps/client/src/widgets/view_widgets/table_view/context_menu.ts @@ -78,6 +78,16 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, tabulator: uiIcon: "bx bx-empty", items: buildColumnItems() }, + { title: "----" }, + { + title: "Add column to the left", + handler: () => { + getParentComponent(e)?.triggerCommand("addNoteListItem", { + referenceColumn: column + }); + console.log("Add col"); + } + } ], selectMenuItemHandler() {}, x: e.pageX, diff --git a/apps/client/src/widgets/view_widgets/table_view/index.ts b/apps/client/src/widgets/view_widgets/table_view/index.ts index a56039cbe..ed4e03485 100644 --- a/apps/client/src/widgets/view_widgets/table_view/index.ts +++ b/apps/client/src/widgets/view_widgets/table_view/index.ts @@ -6,7 +6,7 @@ import SpacedUpdate from "../../../services/spaced_update.js"; import type { CommandListenerData, EventData } from "../../../components/app_context.js"; import type { Attribute } from "../../../services/attribute_parser.js"; import note_create, { CreateNoteOpts } from "../../../services/note_create.js"; -import {Tabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule, Options, RowComponent} from 'tabulator-tables'; +import {Tabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule, Options, RowComponent, ColumnComponent} from 'tabulator-tables'; import "tabulator-tables/dist/css/tabulator.css"; import "../../../../src/stylesheets/table.css"; import { canReorderRows, configureReorderingRows } from "./dragging.js"; @@ -105,10 +105,10 @@ export default class TableView extends ViewMode { private spacedUpdate: SpacedUpdate; private api?: Tabulator; private newAttribute?: Attribute; + private newAttributePosition?: number; private persistentData: StateInfo["tableData"]; private attributeDetailWidget: AttributeDetailWidget; - constructor(args: ViewModeArgs) { super(args, "table"); @@ -234,13 +234,20 @@ export default class TableView extends ViewMode { console.log("Save attributes", this.newAttribute); } - addNoteListItemEvent() { + addNoteListItemEvent({ referenceColumn }: { referenceColumn?: ColumnComponent }) { + console.log("Add note list item ", referenceColumn); const attr: Attribute = { type: "label", name: "label:myLabel", value: "promoted,single,text" }; + if (referenceColumn && this.api) { + this.newAttributePosition = this.api.getColumns().indexOf(referenceColumn) - 1; + } else { + this.newAttributePosition = undefined; + } + this.attributeDetailWidget!.showAttributeDetail({ attribute: attr, allAttributes: [ attr ], @@ -274,7 +281,7 @@ export default class TableView extends ViewMode { } // Force a refresh if sorted is changed since we need to disable reordering. - if (loadResults.getAttributeRows().find(a => attributes.isAffecting(a, this.parentNote))) { + if (loadResults.getAttributeRows().find(a => a.name === "sorted" && attributes.isAffecting(a, this.parentNote))) { return true; } @@ -283,6 +290,7 @@ export default class TableView extends ViewMode { attr.type === "label" && (attr.name?.startsWith("label:") || attr.name?.startsWith("relation:")) && attributes.isAffecting(attr, this.parentNote))) { + console.log("Col update"); this.#manageColumnUpdate(); } @@ -301,8 +309,9 @@ export default class TableView extends ViewMode { } const info = getAttributeDefinitionInformation(this.parentNote); - const columnDefs = buildColumnDefinitions(info, !!this.api.options.movableRows, this.persistentData?.columns); + const columnDefs = buildColumnDefinitions(info, !!this.api.options.movableRows, this.persistentData?.columns, this.newAttributePosition); this.api.setColumns(columnDefs); + this.newAttributePosition = undefined; } async #manageRowsUpdate() {