From 458d66cb21628730ac66b774bafec4ce7db3882a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 13 Jul 2025 00:36:34 +0300 Subject: [PATCH] feat(views/table): delete row from context menu (closes #6288) --- apps/client/src/services/branches.ts | 20 ++++++++++---- .../src/translations/en/translation.json | 3 +++ .../view_widgets/table_view/context_menu.ts | 27 +++++++++++++++++++ .../widgets/view_widgets/table_view/index.ts | 2 ++ 4 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 apps/client/src/widgets/view_widgets/table_view/context_menu.ts diff --git a/apps/client/src/services/branches.ts b/apps/client/src/services/branches.ts index d551ba06c..86ec8e9a8 100644 --- a/apps/client/src/services/branches.ts +++ b/apps/client/src/services/branches.ts @@ -95,7 +95,15 @@ async function moveToParentNote(branchIdsToMove: string[], newParentBranchId: st } } -async function deleteNotes(branchIdsToDelete: string[], forceDeleteAllClones = false) { +/** + * Shows the delete confirmation screen + * + * @param branchIdsToDelete the list of branch IDs to delete. + * @param forceDeleteAllClones whether to check by default the "Delete also all clones" checkbox. + * @param moveToParent whether to automatically go to the parent note path after a succesful delete. Usually makes sense if deleting the active note(s). + * @returns promise that returns false if the operation was cancelled or there was nothing to delete, true if the operation succeeded. + */ +async function deleteNotes(branchIdsToDelete: string[], forceDeleteAllClones = false, moveToParent = true) { branchIdsToDelete = filterRootNote(branchIdsToDelete); if (branchIdsToDelete.length === 0) { @@ -110,10 +118,12 @@ async function deleteNotes(branchIdsToDelete: string[], forceDeleteAllClones = f return false; } - try { - await activateParentNotePath(); - } catch (e) { - console.error(e); + if (moveToParent) { + try { + await activateParentNotePath(); + } catch (e) { + console.error(e); + } } const taskId = utils.randomString(10); diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index b7795a225..32ecdcc9f 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -1949,5 +1949,8 @@ "book_properties_config": { "hide-weekends": "Hide weekends", "display-week-numbers": "Display week numbers" + }, + "table_context_menu": { + "delete_row": "Delete row" } } 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 new file mode 100644 index 000000000..88282ca5b --- /dev/null +++ b/apps/client/src/widgets/view_widgets/table_view/context_menu.ts @@ -0,0 +1,27 @@ +import { RowComponent, Tabulator } from "tabulator-tables"; +import contextMenu from "../../../menus/context_menu.js"; +import { TableData } from "./rows.js"; +import branches from "../../../services/branches.js"; +import { t } from "../../../services/i18n.js"; + +export function setupContextMenu(tabulator: Tabulator) { + tabulator.on("rowContext", showRowContextMenu); +} + +export function showRowContextMenu(_e: UIEvent, row: RowComponent) { + const e = _e as MouseEvent; + const rowData = row.getData() as TableData; + contextMenu.show({ + items: [ + { + title: t("table_context_menu.delete_row"), + uiIcon: "bx bx-trash", + handler: () => branches.deleteNotes([ rowData.branchId ], false, false) + } + ], + selectMenuItemHandler: () => {}, + x: e.pageX, + y: e.pageY + }); + e.preventDefault(); +} 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 2ba41c6cc..7e2e8f5cf 100644 --- a/apps/client/src/widgets/view_widgets/table_view/index.ts +++ b/apps/client/src/widgets/view_widgets/table_view/index.ts @@ -13,6 +13,7 @@ import { canReorderRows, configureReorderingRows } from "./dragging.js"; import buildFooter from "./footer.js"; import getPromotedAttributeInformation, { buildRowDefinitions } from "./rows.js"; import { buildColumnDefinitions } from "./columns.js"; +import { setupContextMenu } from "./context_menu.js"; const TPL = /*html*/`
@@ -144,6 +145,7 @@ export default class TableView extends ViewMode { persistenceReaderFunc: (_id, type: string) => this.persistentData?.[type], }); configureReorderingRows(this.api); + setupContextMenu(this.api); this.setupEditing(); }