feat(breadcrumb): add hoist option

This commit is contained in:
Elian Doran 2025-12-16 10:09:10 +02:00
parent cb8e35c4dc
commit 51fcda646d
No known key found for this signature in database
2 changed files with 39 additions and 10 deletions

View File

@ -1,10 +1,11 @@
import { t } from "../services/i18n.js"; import type { LeafletMouseEvent } from "leaflet";
import contextMenu, { type ContextMenuEvent, type MenuItem } from "./context_menu.js";
import appContext, { type CommandNames } from "../components/app_context.js"; import appContext, { type CommandNames } from "../components/app_context.js";
import { t } from "../services/i18n.js";
import type { ViewScope } from "../services/link.js"; import type { ViewScope } from "../services/link.js";
import utils, { isMobile } from "../services/utils.js"; import utils, { isMobile } from "../services/utils.js";
import { getClosestNtxId } from "../widgets/widget_utils.js"; import { getClosestNtxId } from "../widgets/widget_utils.js";
import type { LeafletMouseEvent } from "leaflet"; import contextMenu, { type ContextMenuEvent, type MenuItem } from "./context_menu.js";
function openContextMenu(notePath: string, e: ContextMenuEvent, viewScope: ViewScope = {}, hoistedNoteId: string | null = null) { function openContextMenu(notePath: string, e: ContextMenuEvent, viewScope: ViewScope = {}, hoistedNoteId: string | null = null) {
contextMenu.show({ contextMenu.show({
@ -34,15 +35,21 @@ function handleLinkContextMenuItem(command: string | undefined, e: ContextMenuEv
if (command === "openNoteInNewTab") { if (command === "openNoteInNewTab") {
appContext.tabManager.openContextWithNote(notePath, { hoistedNoteId, viewScope }); appContext.tabManager.openContextWithNote(notePath, { hoistedNoteId, viewScope });
return true;
} else if (command === "openNoteInNewSplit") { } else if (command === "openNoteInNewSplit") {
const ntxId = getNtxId(e); const ntxId = getNtxId(e);
if (!ntxId) return; if (!ntxId) return false;
appContext.triggerCommand("openNewNoteSplit", { ntxId, notePath, hoistedNoteId, viewScope }); appContext.triggerCommand("openNewNoteSplit", { ntxId, notePath, hoistedNoteId, viewScope });
return true;
} else if (command === "openNoteInNewWindow") { } else if (command === "openNoteInNewWindow") {
appContext.triggerCommand("openInWindow", { notePath, hoistedNoteId, viewScope }); appContext.triggerCommand("openInWindow", { notePath, hoistedNoteId, viewScope });
return true;
} else if (command === "openNoteInPopup") { } else if (command === "openNoteInPopup") {
appContext.triggerCommand("openInPopup", { noteIdOrPath: notePath }) appContext.triggerCommand("openInPopup", { noteIdOrPath: notePath });
return true;
} }
return false;
} }
function getNtxId(e: ContextMenuEvent | LeafletMouseEvent) { function getNtxId(e: ContextMenuEvent | LeafletMouseEvent) {
@ -52,9 +59,9 @@ function getNtxId(e: ContextMenuEvent | LeafletMouseEvent) {
return subContexts[subContexts.length - 1].ntxId; return subContexts[subContexts.length - 1].ntxId;
} else if (e.target instanceof HTMLElement) { } else if (e.target instanceof HTMLElement) {
return getClosestNtxId(e.target); return getClosestNtxId(e.target);
} else {
return null;
} }
return null;
} }
export default { export default {

View File

@ -1,6 +1,6 @@
import "./Breadcrumb.css"; import "./Breadcrumb.css";
import { useRef, useState } from "preact/hooks"; import { useContext, useRef, useState } from "preact/hooks";
import { Fragment } from "preact/jsx-runtime"; import { Fragment } from "preact/jsx-runtime";
import appContext from "../../components/app_context"; import appContext from "../../components/app_context";
@ -19,6 +19,7 @@ import { FormListItem } from "../react/FormList";
import { useChildNotes, useNote, useNoteIcon, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useStaticTooltip } from "../react/hooks"; import { useChildNotes, useNote, useNoteIcon, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useStaticTooltip } from "../react/hooks";
import Icon from "../react/Icon"; import Icon from "../react/Icon";
import NoteLink from "../react/NoteLink"; import NoteLink from "../react/NoteLink";
import { ParentComponent } from "../react/react_utils";
const COLLAPSE_THRESHOLD = 5; const COLLAPSE_THRESHOLD = 5;
const INITIAL_ITEMS = 2; const INITIAL_ITEMS = 2;
@ -141,6 +142,8 @@ function BreadcrumbLastItem({ notePath }: { notePath: string }) {
} }
function BreadcrumbItem({ index, notePath, noteContext, notePathLength }: { index: number, notePathLength: number, notePath: string, noteContext: NoteContext | undefined }) { function BreadcrumbItem({ index, notePath, noteContext, notePathLength }: { index: number, notePathLength: number, notePath: string, noteContext: NoteContext | undefined }) {
const parentComponent = useContext(ParentComponent);
if (index === 0) { if (index === 0) {
return <BreadcrumbRoot noteContext={noteContext} />; return <BreadcrumbRoot noteContext={noteContext} />;
} }
@ -162,13 +165,32 @@ function BreadcrumbItem({ index, notePath, noteContext, notePathLength }: { inde
const note = await froca.getNote(noteId); const note = await froca.getNote(noteId);
if (!note) return; if (!note) return;
const notSearch = note?.type !== "search";
contextMenu.show({ contextMenu.show({
items: [ items: [
...link_context_menu.getItems(e), ...link_context_menu.getItems(e),
{
title: `${t("tree-context-menu.hoist-note")}`,
command: "toggleNoteHoisting",
keyboardShortcut: "toggleNoteHoisting",
uiIcon: "bx bxs-chevrons-up",
enabled: notSearch
},
], ],
x: e.pageX, x: e.pageX,
y: e.pageY, y: e.pageY,
selectMenuItemHandler: ({ command }) => link_context_menu.handleLinkContextMenuItem(command, e, note.noteId), selectMenuItemHandler: ({ command }) => {
if (link_context_menu.handleLinkContextMenuItem(command, e, note.noteId)) {
return;
}
if (command) {
parentComponent?.triggerCommand(command, {
noteId
});
}
},
}); });
}} }}
/>; />;