diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index 6a9f5a413..7bb080778 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -1973,6 +1973,8 @@ "delete-note": "Delete Note", "move-to": "Move to", "insert-above": "Insert above", - "insert-below": "Insert below" + "insert-below": "Insert below", + "delete-column": "Delete column", + "delete-column-confirmation": "Are you sure you want to delete this column? All notes in this column will be deleted as well." } } diff --git a/apps/client/src/widgets/view_widgets/board_view/api.ts b/apps/client/src/widgets/view_widgets/board_view/api.ts index 39c7bf246..aa2e50802 100644 --- a/apps/client/src/widgets/view_widgets/board_view/api.ts +++ b/apps/client/src/widgets/view_widgets/board_view/api.ts @@ -68,6 +68,11 @@ export default class BoardApi { } } + async removeColumn(column: string) { + this.persistedData.columns = (this.persistedData.columns ?? []).filter(col => col.value !== column); + this.viewStorage.store(this.persistedData); + } + static async build(parentNote: FNote, viewStorage: ViewModeStorage) { let persistedData = await viewStorage.restore() ?? {}; const { byColumn, newPersistedData } = await getBoardData(parentNote, "status", persistedData); diff --git a/apps/client/src/widgets/view_widgets/board_view/context_menu.ts b/apps/client/src/widgets/view_widgets/board_view/context_menu.ts index a6044c8c7..9ee9909e0 100644 --- a/apps/client/src/widgets/view_widgets/board_view/context_menu.ts +++ b/apps/client/src/widgets/view_widgets/board_view/context_menu.ts @@ -1,6 +1,7 @@ -import contextMenu from "../../../menus/context_menu.js"; +import contextMenu, { ContextMenuEvent } from "../../../menus/context_menu.js"; import link_context_menu from "../../../menus/link_context_menu.js"; import branches from "../../../services/branches.js"; +import dialog from "../../../services/dialog.js"; import { t } from "../../../services/i18n.js"; import BoardApi from "./api.js"; @@ -9,8 +10,39 @@ interface ShowNoteContextMenuArgs { api: BoardApi; } -export function showNoteContextMenu({ $container, api }: ShowNoteContextMenuArgs) { - $container.on("contextmenu", ".board-note", (event) => { +export function setupContextMenu({ $container, api }: ShowNoteContextMenuArgs) { + $container.on("contextmenu", ".board-note", showNoteContextMenu); + $container.on("contextmenu", ".board-column", showColumnContextMenu); + + function showColumnContextMenu(event: ContextMenuEvent) { + event.preventDefault(); + event.stopPropagation(); + + const $el = $(event.currentTarget); + const column = $el.closest(".board-column").data("column"); + + contextMenu.show({ + x: event.pageX, + y: event.pageY, + items: [ + { + title: t("board_view.delete-column"), + uiIcon: "bx bx-trash", + async handler() { + const confirmed = await dialog.confirm(t("board_view.delete-column-confirmation")); + if (!confirmed) { + return; + } + + await api.removeColumn(column); + } + } + ], + selectMenuItemHandler() {} + }); + } + + function showNoteContextMenu(event: ContextMenuEvent) { event.preventDefault(); event.stopPropagation(); @@ -55,5 +87,5 @@ export function showNoteContextMenu({ $container, api }: ShowNoteContextMenuArgs ], selectMenuItemHandler: ({ command }) => link_context_menu.handleLinkContextMenuItem(command, noteId), }); - }); + } } diff --git a/apps/client/src/widgets/view_widgets/board_view/index.ts b/apps/client/src/widgets/view_widgets/board_view/index.ts index 28ef1dc28..6505d11cf 100644 --- a/apps/client/src/widgets/view_widgets/board_view/index.ts +++ b/apps/client/src/widgets/view_widgets/board_view/index.ts @@ -1,13 +1,12 @@ import { setupHorizontalScrollViaWheel } from "../../widget_utils"; import ViewMode, { ViewModeArgs } from "../view_mode"; -import { getBoardData } from "./data"; import attributeService from "../../../services/attributes"; import branchService from "../../../services/branches"; import noteCreateService from "../../../services/note_create"; import appContext, { EventData } from "../../../components/app_context"; import { BoardData } from "./config"; import SpacedUpdate from "../../../services/spaced_update"; -import { showNoteContextMenu } from "./context_menu"; +import { setupContextMenu } from "./context_menu"; import BoardApi from "./api"; const TPL = /*html*/` @@ -201,7 +200,7 @@ export default class BoardView extends ViewMode { private async renderBoard(el: HTMLElement) { this.api = await BoardApi.build(this.parentNote, this.viewStorage); - showNoteContextMenu({ + setupContextMenu({ $container: this.$container, api: this.api }); @@ -571,6 +570,11 @@ export default class BoardView extends ViewMode { return true; } + // React to attachment change. + if (loadResults.getAttachmentRows().some(att => att.ownerId === this.parentNote.noteId && att.title === "board.json")) { + return true; + } + return false; }