From c7b16cd04390765f41975f8806b25bbd346e47c5 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 25 Jun 2025 13:52:53 +0300 Subject: [PATCH] feat(book/table): allow show/hide columns --- apps/client/src/menus/context_menu.ts | 14 ++++-- .../table_view/header-customization.ts | 49 +++++++++++++++++++ .../view_widgets/table_view/renderer.ts | 6 ++- 3 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 apps/client/src/widgets/view_widgets/table_view/header-customization.ts diff --git a/apps/client/src/menus/context_menu.ts b/apps/client/src/menus/context_menu.ts index 72519233a..a23421651 100644 --- a/apps/client/src/menus/context_menu.ts +++ b/apps/client/src/menus/context_menu.ts @@ -2,7 +2,7 @@ import keyboardActionService from "../services/keyboard_actions.js"; import note_tooltip from "../services/note_tooltip.js"; import utils from "../services/utils.js"; -interface ContextMenuOptions { +export interface ContextMenuOptions { x: number; y: number; orientation?: "left"; @@ -28,6 +28,7 @@ export interface MenuCommandItem { items?: MenuItem[] | null; shortcut?: string; spellingSuggestion?: string; + checked?: boolean; } export type MenuItem = MenuCommandItem | MenuSeparatorItem; @@ -146,10 +147,13 @@ class ContextMenu { } else { const $icon = $(""); - if ("uiIcon" in item && item.uiIcon) { - $icon.addClass(item.uiIcon); - } else { - $icon.append(" "); + if ("uiIcon" in item || "checked" in item) { + const icon = (item.checked ? "bx bx-check" : item.uiIcon); + if (icon) { + $icon.addClass(icon); + } else { + $icon.append(" "); + } } const $link = $("") diff --git a/apps/client/src/widgets/view_widgets/table_view/header-customization.ts b/apps/client/src/widgets/view_widgets/table_view/header-customization.ts new file mode 100644 index 000000000..6907a3664 --- /dev/null +++ b/apps/client/src/widgets/view_widgets/table_view/header-customization.ts @@ -0,0 +1,49 @@ +import { GridApi } from "ag-grid-community"; +import contextMenu, { MenuItem } from "../../../menus/context_menu.js"; +import { TableData } from "./data.js"; + +export default function applyHeaderCustomization(baseEl: HTMLElement, api: GridApi) { + const header = baseEl.querySelector(".ag-header"); + if (!header) { + return; + } + + header.addEventListener("contextmenu", (e) => { + e.preventDefault(); + + + contextMenu.show({ + items: [ + { + title: "Columns", + items: buildColumnChooser(api) + } + ], + x: e.pageX, + y: e.pageY, + selectMenuItemHandler: () => {} + }); + }); +} + +export function buildColumnChooser(api: GridApi) { + const items: MenuItem[] = []; + + for (const column of api.getColumns() ?? []) { + const colDef = column.getColDef(); + if (!colDef) { + continue; + } + + const visible = column.isVisible(); + items.push({ + title: colDef.headerName ?? api.getDisplayNameForColumn(column, "header") ?? "", + checked: visible, + handler() { + api.setColumnsVisible([ column ], !visible); + } + }); + } + + return items; +} diff --git a/apps/client/src/widgets/view_widgets/table_view/renderer.ts b/apps/client/src/widgets/view_widgets/table_view/renderer.ts index 8a9fc12cc..dbf27f13c 100644 --- a/apps/client/src/widgets/view_widgets/table_view/renderer.ts +++ b/apps/client/src/widgets/view_widgets/table_view/renderer.ts @@ -3,6 +3,7 @@ import { buildData, type TableData } from "./data.js"; import FNote from "../../../entities/fnote.js"; import getPromotedAttributeInformation, { PromotedAttributeInformation } from "./parser.js"; import { setLabel } from "../../../services/attributes.js"; +import applyHeaderCustomization from "./header-customization.js"; ModuleRegistry.registerModules([ AllCommunityModule ]); @@ -11,7 +12,10 @@ export default function renderTable(el: HTMLElement, parentNote: FNote, notes: F createGrid(el, { ...buildData(info, notes), - ...setupEditing(info) + ...setupEditing(info), + onGridReady(event) { + applyHeaderCustomization(el, event.api); + }, }); }