chore(react/collections/table): reintroduce column context menu

This commit is contained in:
Elian Doran
2025-09-11 19:25:17 +03:00
parent 2b452a18df
commit 803164791f
5 changed files with 58 additions and 39 deletions

View File

@@ -1,12 +1,18 @@
import { BoardViewData } from ".";
import FNote from "../../../entities/fnote";
import attributes from "../../../services/attributes";
import { executeBulkActions } from "../../../services/bulk_action";
import note_create from "../../../services/note_create";
import { ColumnMap } from "./data";
export default class BoardApi {
constructor(
private byColumn: ColumnMap | undefined,
private parentNote: FNote,
private statusAttribute: string
private statusAttribute: string,
private viewConfig: BoardViewData,
private saveConfig: (newConfig: BoardViewData) => void
) {};
async createNewItem(column: string) {
@@ -36,5 +42,19 @@ export default class BoardApi {
await attributes.setLabel(noteId, this.statusAttribute, newColumn);
}
async removeColumn(column: string) {
// Remove the value from the notes.
const noteIds = this.byColumn?.get(column)?.map(item => item.note.noteId) || [];
await executeBulkActions(noteIds, [
{
name: "deleteLabel",
labelName: this.statusAttribute
}
]);
this.viewConfig.columns = (this.viewConfig.columns ?? []).filter(col => col.value !== column);
this.saveConfig(this.viewConfig);
}
}

View File

@@ -0,0 +1,29 @@
import contextMenu, { ContextMenuEvent } from "../../../menus/context_menu";
import dialog from "../../../services/dialog";
import { t } from "../../../services/i18n";
import Api from "./api";
export function openColumnContextMenu(api: Api, event: ContextMenuEvent, column: string) {
event.preventDefault();
event.stopPropagation();
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() {}
});
}

View File

@@ -10,6 +10,8 @@ import { t } from "../../../services/i18n";
import Api from "./api";
import FormTextBox from "../../react/FormTextBox";
import branchService from "../../../services/branches";
import { openColumnContextMenu } from "./context_menu";
import { ContextMenuEvent } from "../../../menus/context_menu";
export interface BoardViewData {
columns?: BoardColumnData[];
@@ -29,7 +31,7 @@ export default function BoardView({ note: parentNote, noteIds, viewConfig, saveC
const [ draggedColumn, setDraggedColumn ] = useState<{ column: string, index: number } | null>(null);
const [ columnDropPosition, setColumnDropPosition ] = useState<number | null>(null);
const api = useMemo(() => {
return new Api(parentNote, statusAttribute);
return new Api(byColumn, parentNote, statusAttribute, viewConfig ?? {}, saveConfig);
}, [ parentNote, statusAttribute ]);
function refresh() {
@@ -283,12 +285,17 @@ function Column({
setDraggedCard(null);
}, [draggedCard, draggedColumn, dropPosition, columnItems, column, statusAttribute, setDraggedCard, setDropTarget, setDropPosition, onCardDrop]);
const handleContextMenu = useCallback((e: ContextMenuEvent) => {
openColumnContextMenu(api, e, column);
}, [ api, column ]);
return (
<div
className={`board-column ${dropTarget === column && draggedCard?.fromColumn !== column ? 'drag-over' : ''} ${isDraggingColumn ? 'column-dragging' : ''}`}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
onContextMenu={handleContextMenu}
>
<h3
draggable="true"

View File

@@ -77,19 +77,7 @@ export default class BoardApi {
await this.viewStorage.store(this.persistedData);
}
async removeColumn(column: string) {
// Remove the value from the notes.
const noteIds = this.byColumn.get(column)?.map(item => item.note.noteId) || [];
await executeBulkActions(noteIds, [
{
name: "deleteLabel",
labelName: this._statusAttribute
}
]);
this.persistedData.columns = (this.persistedData.columns ?? []).filter(col => col.value !== column);
this.viewStorage.store(this.persistedData);
}
async reorderColumns(newColumnOrder: string[]) {
// Update the column order in persisted data

View File

@@ -16,32 +16,7 @@ export function setupContextMenu({ $container, api, boardView }: ShowNoteContext
$container.on("contextmenu", ".board-note", showNoteContextMenu);
$container.on("contextmenu", ".board-column h3", 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) {