From aef824d262f0426eeabfa5c2858094e097c478e4 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 17 Jul 2025 15:36:33 +0300 Subject: [PATCH] feat(views/table): add a context menu for the header outside columns --- .../view_widgets/table_view/context_menu.ts | 60 ++++++++++++++----- 1 file changed, 45 insertions(+), 15 deletions(-) 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 dbac8e0a4..50f72092c 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 @@ -11,6 +11,10 @@ import type Component from "../../../components/component.js"; export function setupContextMenu(tabulator: Tabulator, parentNote: FNote) { tabulator.on("rowContext", (e, row) => showRowContextMenu(e, row, parentNote, tabulator)); tabulator.on("headerContext", (e, col) => showColumnContextMenu(e, col, parentNote, tabulator)); + tabulator.on("renderComplete", () => { + const headerRow = tabulator.element.querySelector(".tabulator-header-contents"); + headerRow?.addEventListener("contextmenu", (e) => showHeaderContextMenu(e, tabulator)); + }); // Pressing the expand button prevents bubbling and the context menu remains menu when it shouldn't. if (tabulator.options.dataTree) { @@ -75,7 +79,7 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote: { title: t("table_view.show-hide-columns"), uiIcon: "bx bx-empty", - items: buildColumnItems() + items: buildColumnItems(tabulator) }, { title: "----" }, { @@ -118,22 +122,32 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote: y: e.pageY }); e.preventDefault(); +} - function buildColumnItems() { - const items: MenuItem[] = []; - for (const column of tabulator.getColumns()) { - const { title, field } = column.getDefinition(); - - items.push({ - title, - checked: column.isVisible(), +/** + * Shows a context menu which has options dedicated to the header area (the part where the columns are, but in the empty space). + * Provides generic options such as toggling columns. + */ +function showHeaderContextMenu(_e: Event, tabulator: Tabulator) { + const e = _e as MouseEvent; + contextMenu.show({ + items: [ + { + title: t("table_view.show-hide-columns"), uiIcon: "bx bx-empty", - handler: () => column.toggle() - }); - } - - return items; - } + items: buildColumnItems(tabulator) + }, + { + title: t("table_view.new-column"), + uiIcon: "bx bx-columns", + handler: () => getParentComponent(e)?.triggerCommand("addNewTableColumn", {}) + }, + ], + selectMenuItemHandler() {}, + x: e.pageX, + y: e.pageY + }); + e.preventDefault(); } export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: FNote, tabulator: Tabulator) { @@ -213,3 +227,19 @@ function getParentComponent(e: MouseEvent) { .closest(".component") .prop("component") as Component; } + +function buildColumnItems(tabulator: Tabulator) { + const items: MenuItem[] = []; + for (const column of tabulator.getColumns()) { + const { title } = column.getDefinition(); + + items.push({ + title, + checked: column.isVisible(), + uiIcon: "bx bx-empty", + handler: () => column.toggle() + }); + } + + return items; +}