mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
refactoring of tree context menu into reusable component
This commit is contained in:
parent
bc2e230425
commit
d978c64e1a
65
src/public/javascripts/services/context_menu.js
Normal file
65
src/public/javascripts/services/context_menu.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
const $contextMenuContainer = $("#context-menu-container");
|
||||||
|
|
||||||
|
function initContextMenu(event, contextMenuItems, selectContextMenuItem) {
|
||||||
|
$contextMenuContainer.empty();
|
||||||
|
|
||||||
|
for (const item of contextMenuItems) {
|
||||||
|
if (item.title === '----') {
|
||||||
|
$contextMenuContainer.append($("<div>").addClass("dropdown-divider"));
|
||||||
|
} else {
|
||||||
|
const $icon = $("<span>");
|
||||||
|
|
||||||
|
if (item.uiIcon) {
|
||||||
|
$icon.addClass("jam jam-" + item.uiIcon);
|
||||||
|
} else {
|
||||||
|
$icon.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
const $item = $("<a>")
|
||||||
|
.append($icon)
|
||||||
|
.append(" ") // some space between icon and text
|
||||||
|
.addClass("dropdown-item")
|
||||||
|
.prop("data-cmd", item.cmd)
|
||||||
|
.append(item.title);
|
||||||
|
|
||||||
|
|
||||||
|
if (item.enabled !== undefined && !item.enabled) {
|
||||||
|
$item.addClass("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
$item.click(async function (e) {
|
||||||
|
const cmd = $(e.target).prop("data-cmd");
|
||||||
|
|
||||||
|
await selectContextMenuItem(e, cmd);
|
||||||
|
});
|
||||||
|
|
||||||
|
$contextMenuContainer.append($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// code below tries to detect when dropdown would overflow from page
|
||||||
|
// in such case we'll position it above click coordinates so it will fit into client
|
||||||
|
const clickPosition = event.pageY;
|
||||||
|
const clientHeight = document.documentElement.clientHeight;
|
||||||
|
const contextMenuHeight = $contextMenuContainer.height();
|
||||||
|
|
||||||
|
let top;
|
||||||
|
|
||||||
|
if (clickPosition + contextMenuHeight > clientHeight) {
|
||||||
|
top = clientHeight - contextMenuHeight - 10;
|
||||||
|
} else {
|
||||||
|
top = event.pageY - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
$contextMenuContainer.css({
|
||||||
|
display: "block",
|
||||||
|
top: top,
|
||||||
|
left: event.pageX - 20
|
||||||
|
}).addClass("show");
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).click(() => $contextMenuContainer.hide());
|
||||||
|
|
||||||
|
export default {
|
||||||
|
initContextMenu
|
||||||
|
}
|
@ -224,19 +224,17 @@ function initJsPlumbInstance () {
|
|||||||
$relationMapCanvas.contextmenu({
|
$relationMapCanvas.contextmenu({
|
||||||
delegate: ".note-box",
|
delegate: ".note-box",
|
||||||
menu: [
|
menu: [
|
||||||
{title: "Remove note", cmd: "remove", uiIcon: "ui-icon-trash"},
|
{title: "Remove note", cmd: "remove", uiIcon: "trash"},
|
||||||
{title: "Edit title", cmd: "edit-title", uiIcon: "ui-icon-pencil"},
|
{title: "Edit title", cmd: "edit-title", uiIcon: "pencil"},
|
||||||
],
|
],
|
||||||
select: noteContextMenuHandler
|
select: noteContextMenuHandler
|
||||||
});
|
});
|
||||||
|
|
||||||
$.widget("moogle.contextmenuRelation", $.moogle.contextmenu, {});
|
|
||||||
|
|
||||||
$relationMapCanvas.contextmenuRelation({
|
$relationMapCanvas.contextmenuRelation({
|
||||||
delegate: ".connection-label,.jtk-connector",
|
delegate: ".connection-label,.jtk-connector",
|
||||||
autoTrigger: false, // it doesn't open automatically, needs to be triggered explicitly by .open() call
|
autoTrigger: false, // it doesn't open automatically, needs to be triggered explicitly by .open() call
|
||||||
menu: [
|
menu: [
|
||||||
{title: "Remove relation", cmd: "remove", uiIcon: "ui-icon-trash"}
|
{title: "Remove relation", cmd: "remove", uiIcon: "trash"}
|
||||||
],
|
],
|
||||||
select: relationContextMenuHandler
|
select: relationContextMenuHandler
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import contextMenuWidget from './context_menu.js';
|
||||||
import treeContextMenuService from './tree_context_menu.js';
|
import treeContextMenuService from './tree_context_menu.js';
|
||||||
import dragAndDropSetup from './drag_and_drop.js';
|
import dragAndDropSetup from './drag_and_drop.js';
|
||||||
import linkService from './link.js';
|
import linkService from './link.js';
|
||||||
@ -15,7 +16,6 @@ import Branch from '../entities/branch.js';
|
|||||||
import NoteShort from '../entities/note_short.js';
|
import NoteShort from '../entities/note_short.js';
|
||||||
|
|
||||||
const $tree = $("#tree");
|
const $tree = $("#tree");
|
||||||
const $treeContextMenu = $("#tree-context-menu");
|
|
||||||
const $createTopLevelNoteButton = $("#create-top-level-note-button");
|
const $createTopLevelNoteButton = $("#create-top-level-note-button");
|
||||||
const $collapseTreeButton = $("#collapse-tree-button");
|
const $collapseTreeButton = $("#collapse-tree-button");
|
||||||
const $scrollToCurrentNoteButton = $("#scroll-to-current-note-button");
|
const $scrollToCurrentNoteButton = $("#scroll-to-current-note-button");
|
||||||
@ -378,73 +378,10 @@ function initFancyTree(tree) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$treeContextMenu.on('click', '.dropdown-item', function(e) {
|
|
||||||
const cmd = $(e.target).prop("data-cmd");
|
|
||||||
|
|
||||||
treeContextMenuService.selectContextMenuItem(e, cmd);
|
|
||||||
});
|
|
||||||
|
|
||||||
async function openContextMenu(e) {
|
|
||||||
$treeContextMenu.empty();
|
|
||||||
|
|
||||||
const contextMenuItems = await treeContextMenuService.getContextMenuItems(e);
|
|
||||||
|
|
||||||
for (const item of contextMenuItems) {
|
|
||||||
if (item.title === '----') {
|
|
||||||
$treeContextMenu.append($("<div>").addClass("dropdown-divider"));
|
|
||||||
} else {
|
|
||||||
const $icon = $("<span>");
|
|
||||||
|
|
||||||
if (item.uiIcon) {
|
|
||||||
$icon.addClass("jam jam-" + item.uiIcon);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$icon.append(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
const $item = $("<a>")
|
|
||||||
.append($icon)
|
|
||||||
.append(" ") // some space between icon and text
|
|
||||||
.addClass("dropdown-item")
|
|
||||||
.prop("data-cmd", item.cmd)
|
|
||||||
.append(item.title);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (item.enabled !== undefined && !item.enabled) {
|
|
||||||
$item.addClass("disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
$treeContextMenu.append($item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// code below tries to detect when dropdown would overflow from page
|
|
||||||
// in such case we'll position it above click coordinates so it will fit into client
|
|
||||||
const clickPosition = e.pageY;
|
|
||||||
const clientHeight = document.documentElement.clientHeight;
|
|
||||||
const contextMenuHeight = $treeContextMenu.height();
|
|
||||||
|
|
||||||
let top;
|
|
||||||
|
|
||||||
if (clickPosition + contextMenuHeight > clientHeight) {
|
|
||||||
top = clientHeight - contextMenuHeight - 10;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
top = e.pageY - 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
$treeContextMenu.css({
|
|
||||||
display: "block",
|
|
||||||
top: top,
|
|
||||||
left: e.pageX - 20
|
|
||||||
}).addClass("show");
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).click(() => $(".context-menu").hide());
|
|
||||||
|
|
||||||
$tree.on('contextmenu', '.fancytree-node', function(e) {
|
$tree.on('contextmenu', '.fancytree-node', function(e) {
|
||||||
openContextMenu(e);
|
treeContextMenuService.getContextMenuItems(e).then(contextMenuItems => {
|
||||||
|
contextMenuWidget.initContextMenu(e, contextMenuItems, treeContextMenuService.selectContextMenuItem);
|
||||||
|
});
|
||||||
|
|
||||||
return false; // blocks default browser right click menu
|
return false; // blocks default browser right click menu
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,7 @@ import exportSubtreeDialog from '../dialogs/export_subtree.js';
|
|||||||
import infoService from "./info.js";
|
import infoService from "./info.js";
|
||||||
import treeCache from "./tree_cache.js";
|
import treeCache from "./tree_cache.js";
|
||||||
import syncService from "./sync.js";
|
import syncService from "./sync.js";
|
||||||
|
import contextMenuService from "./context_menu.js";
|
||||||
|
|
||||||
const $tree = $("#tree");
|
const $tree = $("#tree");
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div id="branch-prefix-dialog" class="modal fade mx-auto" tabindex="-1" role="dialog">
|
<div id="branch-prefix-dialog" class="modal fade mx-auto" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title mr-auto">Edit branch prefix</h5>
|
<h5 class="modal-title mr-auto">Edit branch prefix</h5>
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
|
|
||||||
<div id="tree"></div>
|
<div id="tree"></div>
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-sm context-menu" id="tree-context-menu"></div>
|
<div class="dropdown-menu dropdown-menu-sm" id="context-menu-container"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="title-container">
|
<div id="title-container">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user