chore(react/collections/table): reintroduce item context menu partially

This commit is contained in:
Elian Doran 2025-09-11 19:35:46 +03:00
parent 803164791f
commit 3d2a4d8c38
No known key found for this signature in database
4 changed files with 55 additions and 71 deletions

View File

@ -9,6 +9,7 @@ export default class BoardApi {
constructor( constructor(
private byColumn: ColumnMap | undefined, private byColumn: ColumnMap | undefined,
public columns: string[],
private parentNote: FNote, private parentNote: FNote,
private statusAttribute: string, private statusAttribute: string,
private viewConfig: BoardViewData, private viewConfig: BoardViewData,

View File

@ -1,4 +1,6 @@
import contextMenu, { ContextMenuEvent } from "../../../menus/context_menu"; import contextMenu, { ContextMenuEvent } from "../../../menus/context_menu";
import link_context_menu from "../../../menus/link_context_menu";
import branches from "../../../services/branches";
import dialog from "../../../services/dialog"; import dialog from "../../../services/dialog";
import { t } from "../../../services/i18n"; import { t } from "../../../services/i18n";
import Api from "./api"; import Api from "./api";
@ -27,3 +29,44 @@ export function openColumnContextMenu(api: Api, event: ContextMenuEvent, column:
selectMenuItemHandler() {} selectMenuItemHandler() {}
}); });
} }
export function openNoteContextMenu(api: Api, event: ContextMenuEvent, noteId: string, branchId: string, column: string) {
event.preventDefault();
event.stopPropagation();
contextMenu.show({
x: event.pageX,
y: event.pageY,
items: [
...link_context_menu.getItems(),
{ title: "----" },
{
title: t("board_view.move-to"),
uiIcon: "bx bx-transfer",
items: api.columns.map(columnToMoveTo => ({
title: columnToMoveTo,
enabled: columnToMoveTo !== column,
handler: () => api.changeColumn(noteId, columnToMoveTo)
}))
},
{ title: "----" },
{
title: t("board_view.insert-above"),
uiIcon: "bx bx-list-plus",
// handler: () => boardView.insertItemAtPosition(column, branchId, "before")
},
{
title: t("board_view.insert-below"),
uiIcon: "bx bx-empty",
// handler: () => boardView.insertItemAtPosition(column, branchId, "after")
},
{ title: "----" },
{
title: t("board_view.delete-note"),
uiIcon: "bx bx-trash",
handler: () => branches.deleteNotes([ branchId ], false, false)
}
],
selectMenuItemHandler: ({ command }) => link_context_menu.handleLinkContextMenuItem(command, noteId),
});
}

View File

@ -10,7 +10,7 @@ import { t } from "../../../services/i18n";
import Api from "./api"; import Api from "./api";
import FormTextBox from "../../react/FormTextBox"; import FormTextBox from "../../react/FormTextBox";
import branchService from "../../../services/branches"; import branchService from "../../../services/branches";
import { openColumnContextMenu } from "./context_menu"; import { openColumnContextMenu, openNoteContextMenu } from "./context_menu";
import { ContextMenuEvent } from "../../../menus/context_menu"; import { ContextMenuEvent } from "../../../menus/context_menu";
export interface BoardViewData { export interface BoardViewData {
@ -31,8 +31,8 @@ export default function BoardView({ note: parentNote, noteIds, viewConfig, saveC
const [ draggedColumn, setDraggedColumn ] = useState<{ column: string, index: number } | null>(null); const [ draggedColumn, setDraggedColumn ] = useState<{ column: string, index: number } | null>(null);
const [ columnDropPosition, setColumnDropPosition ] = useState<number | null>(null); const [ columnDropPosition, setColumnDropPosition ] = useState<number | null>(null);
const api = useMemo(() => { const api = useMemo(() => {
return new Api(byColumn, parentNote, statusAttribute, viewConfig ?? {}, saveConfig); return new Api(byColumn, columns ?? [], parentNote, statusAttribute, viewConfig ?? {}, saveConfig);
}, [ parentNote, statusAttribute ]); }, [ byColumn, columns, parentNote, statusAttribute, viewConfig, saveConfig ]);
function refresh() { function refresh() {
getBoardData(parentNote, statusAttribute, viewConfig ?? {}).then(({ byColumn, newPersistedData }) => { getBoardData(parentNote, statusAttribute, viewConfig ?? {}).then(({ byColumn, newPersistedData }) => {
@ -319,6 +319,7 @@ function Column({
<div className="board-drop-placeholder show" /> <div className="board-drop-placeholder show" />
)} )}
<Card <Card
api={api}
note={note} note={note}
branch={branch} branch={branch}
column={column} column={column}
@ -342,6 +343,7 @@ function Column({
} }
function Card({ function Card({
api,
note, note,
branch, branch,
column, column,
@ -349,6 +351,7 @@ function Card({
setDraggedCard, setDraggedCard,
isDragging isDragging
}: { }: {
api: Api,
note: FNote, note: FNote,
branch: FBranch, branch: FBranch,
column: string, column: string,
@ -368,12 +371,17 @@ function Card({
setDraggedCard(null); setDraggedCard(null);
}, [setDraggedCard]); }, [setDraggedCard]);
const handleContextMenu = useCallback((e: ContextMenuEvent) => {
openNoteContextMenu(api, e, note.noteId, branch.branchId, column);
}, [ api, note, branch, column ]);
return ( return (
<div <div
className={`board-note ${colorClass} ${isDragging ? 'dragging' : ''}`} className={`board-note ${colorClass} ${isDragging ? 'dragging' : ''}`}
draggable="true" draggable="true"
onDragStart={handleDragStart} onDragStart={handleDragStart}
onDragEnd={handleDragEnd} onDragEnd={handleDragEnd}
onContextMenu={handleContextMenu}
> >
<span class={`icon ${note.getIcon()}`} /> <span class={`icon ${note.getIcon()}`} />
{note.title} {note.title}

View File

@ -1,68 +0,0 @@
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";
import type BoardView from "./index.js";
interface ShowNoteContextMenuArgs {
$container: JQuery<HTMLElement>;
api: BoardApi;
boardView: BoardView;
}
export function setupContextMenu({ $container, api, boardView }: ShowNoteContextMenuArgs) {
$container.on("contextmenu", ".board-note", showNoteContextMenu);
$container.on("contextmenu", ".board-column h3", showColumnContextMenu);
}
function showNoteContextMenu(event: ContextMenuEvent) {
event.preventDefault();
event.stopPropagation();
const $el = $(event.currentTarget);
const noteId = $el.data("note-id");
const branchId = $el.data("branch-id");
const column = $el.closest(".board-column").data("column");
if (!noteId) return;
contextMenu.show({
x: event.pageX,
y: event.pageY,
items: [
...link_context_menu.getItems(),
{ title: "----" },
{
title: t("board_view.move-to"),
uiIcon: "bx bx-transfer",
items: api.columns.map(columnToMoveTo => ({
title: columnToMoveTo,
enabled: columnToMoveTo !== column,
handler: () => api.changeColumn(noteId, columnToMoveTo)
}))
},
{ title: "----" },
{
title: t("board_view.insert-above"),
uiIcon: "bx bx-list-plus",
handler: () => boardView.insertItemAtPosition(column, branchId, "before")
},
{
title: t("board_view.insert-below"),
uiIcon: "bx bx-empty",
handler: () => boardView.insertItemAtPosition(column, branchId, "after")
},
{ title: "----" },
{
title: t("board_view.delete-note"),
uiIcon: "bx bx-trash",
handler: () => branches.deleteNotes([ branchId ], false, false)
}
],
selectMenuItemHandler: ({ command }) => link_context_menu.handleLinkContextMenuItem(command, noteId),
});
}
}