mirror of
https://github.com/zadam/trilium.git
synced 2025-12-05 15:04:24 +01:00
Compare commits
121 Commits
cf07e1df42
...
8ee59e9daa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ee59e9daa | ||
|
|
4e5c26371e | ||
|
|
436146d829 | ||
|
|
315fcecf57 | ||
|
|
0a57e6e154 | ||
|
|
bdcb84a394 | ||
|
|
213c36ba84 | ||
|
|
995e765276 | ||
|
|
8e81c38c14 | ||
|
|
7378fa4cbd | ||
|
|
af8a5ff0c9 | ||
|
|
eca5a4a072 | ||
|
|
71b3ad5027 | ||
|
|
7864168adc | ||
|
|
f8090d9217 | ||
|
|
09aa22c74b | ||
|
|
8fc8f97879 | ||
|
|
547cdff510 | ||
|
|
cdd08d6971 | ||
|
|
b3cf9c8f2d | ||
|
|
feefa389b4 | ||
|
|
f65be4f368 | ||
|
|
77a014109e | ||
|
|
d3db48c99b | ||
|
|
7e4833e893 | ||
|
|
470d7eee31 | ||
|
|
aada631c0f | ||
|
|
bc4186d216 | ||
|
|
c2a27eff2c | ||
|
|
ca24408a13 | ||
|
|
b9e19e524a | ||
|
|
09c8a778f5 | ||
|
|
3438f1103d | ||
|
|
82a3be06d1 | ||
|
|
f0dead5390 | ||
|
|
b0fdb9fef2 | ||
|
|
71009bddc7 | ||
|
|
66e499a2e1 | ||
|
|
a5ef5eee2f | ||
|
|
bcb29d22f5 | ||
|
|
6ad2b49ab3 | ||
|
|
656e7c069d | ||
|
|
00aa470bf2 | ||
|
|
c6ed0b43fc | ||
|
|
3d8a4d2553 | ||
|
|
42ab0eb804 | ||
|
|
d80d06a9b8 | ||
|
|
3c39026739 | ||
|
|
72c17b22df | ||
|
|
dd1aa23cb6 | ||
|
|
ecdf243e63 | ||
|
|
1e15585a24 | ||
|
|
9d40c0cb26 | ||
|
|
e41e24b044 | ||
|
|
a15d661fd7 | ||
|
|
cb5954e8c7 | ||
|
|
2b55db05e1 | ||
|
|
74bf93059c | ||
|
|
384d8c9c37 | ||
|
|
1bb6149dbe | ||
|
|
3cc64b5764 | ||
|
|
19cf07564f | ||
|
|
5847ce5c14 | ||
|
|
a7ad45635e | ||
|
|
781215394e | ||
|
|
0aafdca999 | ||
|
|
18d3cb6f0c | ||
|
|
263a96e8b7 | ||
|
|
27d5009486 | ||
|
|
2e431b1135 | ||
|
|
e2ec27250c | ||
|
|
1228eda5ea | ||
|
|
435794df73 | ||
|
|
7e3d0639f7 | ||
|
|
86b0005821 | ||
|
|
2fb78275f7 | ||
|
|
98f421c697 | ||
|
|
a5572b7d45 | ||
|
|
fdecbaaa6a | ||
|
|
c6afd7fa24 | ||
|
|
5cad522a60 | ||
|
|
82f64677cb | ||
|
|
3ee086a063 | ||
|
|
13da444a69 | ||
|
|
b51ceaaadc | ||
|
|
2024c72209 | ||
|
|
b5959c55e1 | ||
|
|
16f0ac97f4 | ||
|
|
073c02ee0c | ||
|
|
786f0db4bb | ||
|
|
6958e4b74f | ||
|
|
22c4fba665 | ||
|
|
f7c0e56cec | ||
|
|
5f423cd22e | ||
|
|
282b3a109c | ||
|
|
dddb051d8b | ||
|
|
63d3706003 | ||
|
|
22ca2494f5 | ||
|
|
a0f02b6877 | ||
|
|
487fcff61f | ||
|
|
bfb8897188 | ||
|
|
ce1ccf378a | ||
|
|
96d5ee3d46 | ||
|
|
6f3771e7cd | ||
|
|
e6b00b05a2 | ||
|
|
148d0afe81 | ||
|
|
c5d63dbdb9 | ||
|
|
1af072b059 | ||
|
|
a6a8fdd2f8 | ||
|
|
8836021ff9 | ||
|
|
915803c5be | ||
|
|
cd95d43457 | ||
|
|
35af5fd13c | ||
|
|
35e602f75f | ||
|
|
b4f0a1acc0 | ||
|
|
7b7e9f6868 | ||
|
|
de3892950c | ||
|
|
5c53826da3 | ||
|
|
d358073081 | ||
|
|
d2d7fd7c4c | ||
|
|
706da768e2 |
@ -9,7 +9,7 @@
|
||||
"keywords": [],
|
||||
"author": "Elian Doran <contact@eliandoran.me>",
|
||||
"license": "AGPL-3.0-only",
|
||||
"packageManager": "pnpm@10.23.0",
|
||||
"packageManager": "pnpm@10.24.0",
|
||||
"devDependencies": {
|
||||
"@redocly/cli": "2.12.0",
|
||||
"archiver": "7.0.1",
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
"@types/reveal.js": "5.2.1",
|
||||
"@types/tabulator-tables": "6.3.0",
|
||||
"copy-webpack-plugin": "13.0.1",
|
||||
"happy-dom": "20.0.10",
|
||||
"happy-dom": "20.0.11",
|
||||
"script-loader": "0.7.2",
|
||||
"vite-plugin-static-copy": "3.1.4"
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ import TouchBarComponent from "./touch_bar.js";
|
||||
import type { CKTextEditor } from "@triliumnext/ckeditor5";
|
||||
import type CodeMirror from "@triliumnext/codemirror";
|
||||
import { StartupChecks } from "./startup_checks.js";
|
||||
import type { CreateNoteOpts } from "../services/note_create.js";
|
||||
import type { CreateNoteOpts, CreateNoteWithLinkOpts } from "../services/note_create.js";
|
||||
import { ColumnComponent } from "tabulator-tables";
|
||||
import { ChooseNoteTypeCallback } from "../widgets/dialogs/note_type_chooser.jsx";
|
||||
import type RootContainer from "../widgets/containers/root_container.js";
|
||||
@ -359,8 +359,7 @@ export type CommandMappings = {
|
||||
|
||||
// Table view
|
||||
addNewRow: CommandData & {
|
||||
customOpts: CreateNoteOpts;
|
||||
parentNotePath?: string;
|
||||
customOpts?: CreateNoteWithLinkOpts;
|
||||
};
|
||||
addNewTableColumn: CommandData & {
|
||||
columnToEdit?: ColumnComponent;
|
||||
|
||||
@ -11,6 +11,7 @@ import froca from "../services/froca.js";
|
||||
import linkService from "../services/link.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import { CreateChildrenResponse, SqlExecuteResponse } from "@triliumnext/commons";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
|
||||
export default class Entrypoints extends Component {
|
||||
constructor() {
|
||||
@ -24,23 +25,9 @@ export default class Entrypoints extends Component {
|
||||
}
|
||||
|
||||
async createNoteIntoInboxCommand() {
|
||||
const inboxNote = await dateNoteService.getInboxNote();
|
||||
if (!inboxNote) {
|
||||
console.warn("Missing inbox note.");
|
||||
return;
|
||||
}
|
||||
|
||||
const { note } = await server.post<CreateChildrenResponse>(`notes/${inboxNote.noteId}/children?target=into`, {
|
||||
content: "",
|
||||
type: "text",
|
||||
isProtected: inboxNote.isProtected && protectedSessionHolder.isProtectedSessionAvailable()
|
||||
});
|
||||
|
||||
await ws.waitForMaxKnownEntityChangeId();
|
||||
|
||||
await appContext.tabManager.openTabWithNoteWithHoisting(note.noteId, { activate: true });
|
||||
|
||||
appContext.triggerEvent("focusAndSelectTitle", { isNewNote: true });
|
||||
await noteCreateService.createNote(
|
||||
{ target: "default" }
|
||||
);
|
||||
}
|
||||
|
||||
async toggleNoteHoistingCommand({ noteId = appContext.tabManager.getActiveContextNoteId() }) {
|
||||
|
||||
@ -48,10 +48,15 @@ export default class MainTreeExecutors extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
await noteCreateService.createNote(activeNoteContext.notePath, {
|
||||
isProtected: activeNoteContext.note.isProtected,
|
||||
saveSelection: false
|
||||
});
|
||||
await noteCreateService.createNote(
|
||||
{
|
||||
target: "into",
|
||||
parentNoteLink: activeNoteContext.notePath,
|
||||
isProtected: activeNoteContext.note.isProtected,
|
||||
saveSelection: false,
|
||||
promptForType: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async createNoteAfterCommand() {
|
||||
@ -72,11 +77,14 @@ export default class MainTreeExecutors extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
await noteCreateService.createNote(parentNotePath, {
|
||||
target: "after",
|
||||
targetBranchId: node.data.branchId,
|
||||
isProtected: isProtected,
|
||||
saveSelection: false
|
||||
});
|
||||
await noteCreateService.createNote(
|
||||
{
|
||||
target: "after",
|
||||
parentNoteLink: parentNotePath,
|
||||
targetBranchId: node.data.branchId,
|
||||
isProtected: isProtected,
|
||||
saveSelection: false
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ export default class RootCommandExecutor extends Component {
|
||||
}
|
||||
|
||||
async searchInSubtreeCommand({ notePath }: CommandListenerData<"searchInSubtree">) {
|
||||
const noteId = treeService.getNoteIdFromUrl(notePath);
|
||||
const noteId = treeService.getNoteIdFromLink(notePath);
|
||||
|
||||
this.searchNotesCommand({ ancestorNoteId: noteId });
|
||||
}
|
||||
@ -240,14 +240,18 @@ export default class RootCommandExecutor extends Component {
|
||||
// Create a new AI Chat note at the root level
|
||||
const rootNoteId = "root";
|
||||
|
||||
const result = await noteCreateService.createNote(rootNoteId, {
|
||||
title: "New AI Chat",
|
||||
type: "aiChat",
|
||||
content: JSON.stringify({
|
||||
messages: [],
|
||||
title: "New AI Chat"
|
||||
})
|
||||
});
|
||||
const result = await noteCreateService.createNote(
|
||||
{
|
||||
parentNoteLink: rootNoteId,
|
||||
target: "into",
|
||||
title: "New AI Chat",
|
||||
type: "aiChat",
|
||||
content: JSON.stringify({
|
||||
messages: [],
|
||||
title: "New AI Chat"
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
if (!result.note) {
|
||||
toastService.showError("Failed to create AI Chat note");
|
||||
|
||||
@ -74,10 +74,10 @@ export default class TabManager extends Component {
|
||||
|
||||
// preload all notes at once
|
||||
await froca.getNotes([...noteContextsToOpen.flatMap((tab: NoteContextState) =>
|
||||
[treeService.getNoteIdFromUrl(tab.notePath), tab.hoistedNoteId])], true);
|
||||
[treeService.getNoteIdFromLink(tab.notePath), tab.hoistedNoteId])], true);
|
||||
|
||||
const filteredNoteContexts = noteContextsToOpen.filter((openTab: NoteContextState) => {
|
||||
const noteId = treeService.getNoteIdFromUrl(openTab.notePath);
|
||||
const noteId = treeService.getNoteIdFromLink(openTab.notePath);
|
||||
if (!noteId || !(noteId in froca.notes)) {
|
||||
// note doesn't exist so don't try to open tab for it
|
||||
return false;
|
||||
|
||||
@ -58,6 +58,7 @@ function initOnElectron() {
|
||||
|
||||
initDarkOrLightMode(style);
|
||||
initTransparencyEffects(style, currentWindow);
|
||||
initFullScreenDetection(currentWindow);
|
||||
|
||||
if (options.get("nativeTitleBarVisible") !== "true") {
|
||||
initTitleBarButtons(style, currentWindow);
|
||||
@ -87,6 +88,11 @@ function initTitleBarButtons(style: CSSStyleDeclaration, currentWindow: Electron
|
||||
}
|
||||
}
|
||||
|
||||
function initFullScreenDetection(currentWindow: Electron.BrowserWindow) {
|
||||
currentWindow.on("enter-full-screen", () => document.body.classList.add("full-screen"));
|
||||
currentWindow.on("leave-full-screen", () => document.body.classList.remove("full-screen"));
|
||||
}
|
||||
|
||||
function initTransparencyEffects(style: CSSStyleDeclaration, currentWindow: Electron.BrowserWindow) {
|
||||
if (window.glob.platform === "win32") {
|
||||
const material = style.getPropertyValue("--background-material");
|
||||
|
||||
@ -238,6 +238,7 @@ class ContextMenu {
|
||||
private createCustomMenuItem(item: CustomMenuItem) {
|
||||
const element = document.createElement("li");
|
||||
element.classList.add("dropdown-custom-item");
|
||||
element.onclick = () => this.hide();
|
||||
render(h(item.componentFn, {}), element);
|
||||
return element;
|
||||
}
|
||||
@ -298,8 +299,6 @@ class ContextMenu {
|
||||
// important to use mousedown instead of click since the former does not change focus
|
||||
// (especially important for focused text for spell check)
|
||||
.on("mousedown", (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (e.which !== 1) {
|
||||
// only left click triggers menu items
|
||||
return false;
|
||||
@ -313,6 +312,11 @@ class ContextMenu {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prevent submenu from failing to expand on mobile
|
||||
if (!("items" in item && item.items)) {
|
||||
this.hide();
|
||||
}
|
||||
|
||||
if ("handler" in item && item.handler) {
|
||||
item.handler(item, e);
|
||||
}
|
||||
@ -324,16 +328,6 @@ class ContextMenu {
|
||||
return false;
|
||||
});
|
||||
|
||||
$item.on("mouseup", (e) => {
|
||||
// Prevent submenu from failing to expand on mobile
|
||||
if (!this.isMobile || !("items" in item && item.items)) {
|
||||
e.stopPropagation();
|
||||
// Hide the content menu on mouse up to prevent the mouse event from propagating to the elements below.
|
||||
this.hide();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if ("enabled" in item && item.enabled !== undefined && !item.enabled) {
|
||||
$item.addClass("disabled");
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.note-color-picker .custom-color-cell.custom-color-cell-empty {
|
||||
|
||||
@ -8,6 +8,7 @@ import Color, { ColorInstance } from "color";
|
||||
import Debouncer from "../../utils/debouncer";
|
||||
import FNote from "../../entities/fnote";
|
||||
import froca from "../../services/froca";
|
||||
import { isMobile } from "../../services/utils";
|
||||
|
||||
const COLOR_PALETTE = [
|
||||
"#e64d4d", "#e6994d", "#e5e64d", "#99e64d", "#4de64d", "#4de699",
|
||||
@ -62,13 +63,13 @@ export default function NoteColorPicker(props: NoteColorPickerProps) {
|
||||
} else {
|
||||
attributes.removeOwnedLabelByName(note, "color");
|
||||
}
|
||||
|
||||
|
||||
setCurrentColor(color);
|
||||
}
|
||||
}, [note, currentColor]);
|
||||
|
||||
return <div className="note-color-picker">
|
||||
|
||||
|
||||
<ColorCell className="color-cell-reset"
|
||||
tooltip={t("note-color.clear-color")}
|
||||
color={null}
|
||||
@ -81,8 +82,8 @@ export default function NoteColorPicker(props: NoteColorPickerProps) {
|
||||
<path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
|
||||
</svg>
|
||||
</ColorCell>
|
||||
|
||||
|
||||
|
||||
|
||||
{COLOR_PALETTE.map((color) => (
|
||||
<ColorCell key={color}
|
||||
tooltip={t("note-color.set-color")}
|
||||
@ -128,7 +129,6 @@ function CustomColorCell(props: ColorCellProps) {
|
||||
const colorInput = useRef<HTMLInputElement>(null);
|
||||
const colorInputDebouncer = useRef<Debouncer<string | null> | null>(null);
|
||||
const callbackRef = useRef(props.onSelect);
|
||||
const isSafari = useRef(/^((?!chrome|android).)*safari/i.test(navigator.userAgent));
|
||||
|
||||
useEffect(() => {
|
||||
colorInputDebouncer.current = new Debouncer(250, (color) => {
|
||||
@ -160,13 +160,13 @@ function CustomColorCell(props: ColorCellProps) {
|
||||
}, [pickedColor]);
|
||||
|
||||
return <div style={`--foreground: ${getForegroundColor(props.color)};`}
|
||||
onClick={(e) => {
|
||||
// The color picker dropdown will close on Safari if the parent context menu is
|
||||
onClick={isMobile() ? (e) => {
|
||||
// The color picker dropdown will close on some browser if the parent context menu is
|
||||
// dismissed, so stop the click propagation to prevent dismissing the menu.
|
||||
isSafari.current && e.stopPropagation();
|
||||
}}>
|
||||
e.stopPropagation();
|
||||
} : undefined}>
|
||||
<ColorCell {...props}
|
||||
color={pickedColor}
|
||||
color={pickedColor}
|
||||
className={clsx("custom-color-cell", {
|
||||
"custom-color-cell-empty": (pickedColor === null)
|
||||
})}
|
||||
@ -201,4 +201,4 @@ function tryParseColor(colorStr: string): ColorInstance | null {
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,21 +283,31 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
|
||||
const parentNotePath = treeService.getNotePath(this.node.getParent());
|
||||
const isProtected = treeService.getParentProtectedStatus(this.node);
|
||||
|
||||
noteCreateService.createNote(parentNotePath, {
|
||||
target: "after",
|
||||
targetBranchId: this.node.data.branchId,
|
||||
type: type,
|
||||
isProtected: isProtected,
|
||||
templateNoteId: templateNoteId
|
||||
});
|
||||
|
||||
noteCreateService.createNote(
|
||||
{
|
||||
target: "after",
|
||||
parentNoteLink: parentNotePath,
|
||||
targetBranchId: this.node.data.branchId,
|
||||
type: type,
|
||||
isProtected: isProtected,
|
||||
templateNoteId: templateNoteId,
|
||||
promptForType: false,
|
||||
}
|
||||
);
|
||||
} else if (command === "insertChildNote") {
|
||||
const parentNotePath = treeService.getNotePath(this.node);
|
||||
|
||||
noteCreateService.createNote(parentNotePath, {
|
||||
type: type,
|
||||
isProtected: this.node.data.isProtected,
|
||||
templateNoteId: templateNoteId
|
||||
});
|
||||
noteCreateService.createNote(
|
||||
{
|
||||
target: "into",
|
||||
parentNoteLink: parentNotePath,
|
||||
type: type,
|
||||
isProtected: this.node.data.isProtected,
|
||||
templateNoteId: templateNoteId,
|
||||
promptForType: false,
|
||||
}
|
||||
);
|
||||
} else if (command === "openNoteInSplit") {
|
||||
const subContexts = appContext.tabManager.getActiveContext()?.getSubContexts();
|
||||
const { ntxId } = subContexts?.[subContexts.length - 1] ?? {};
|
||||
|
||||
@ -50,7 +50,7 @@ async function checkNoteAccess(notePath: string, noteContext: NoteContext) {
|
||||
const hoistedNoteId = noteContext.hoistedNoteId;
|
||||
|
||||
if (!resolvedNotePath.includes(hoistedNoteId) && (!resolvedNotePath.includes("_hidden") || resolvedNotePath.includes("_lbBookmarks"))) {
|
||||
const noteId = treeService.getNoteIdFromUrl(resolvedNotePath);
|
||||
const noteId = treeService.getNoteIdFromLink(resolvedNotePath);
|
||||
if (!noteId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ export function parseNavigationStateFromUrl(url: string | undefined) {
|
||||
|
||||
return {
|
||||
notePath,
|
||||
noteId: treeService.getNoteIdFromUrl(notePath),
|
||||
noteId: treeService.getNoteIdFromLink(notePath),
|
||||
ntxId,
|
||||
hoistedNoteId,
|
||||
viewScope,
|
||||
|
||||
@ -5,6 +5,24 @@ import froca from "./froca.js";
|
||||
import { t } from "./i18n.js";
|
||||
import commandRegistry from "./command_registry.js";
|
||||
import type { MentionFeedObjectItem } from "@triliumnext/ckeditor5";
|
||||
import { CreateNoteAction } from "@triliumnext/commons"
|
||||
import FNote from "../entities/fnote.js";
|
||||
|
||||
/**
|
||||
* Extends CKEditor's MentionFeedObjectItem with extra fields used by Trilium.
|
||||
* These additional props (like action, notePath, name, etc.) carry note
|
||||
* metadata and legacy compatibility info needed for custom autocomplete
|
||||
* and link insertion behavior beyond CKEditor’s base mention support.
|
||||
*/
|
||||
type ExtendedMentionFeedObjectItem = MentionFeedObjectItem & {
|
||||
action?: string;
|
||||
noteTitle?: string;
|
||||
name?: string;
|
||||
link?: string;
|
||||
notePath?: string;
|
||||
parentNoteId?: string;
|
||||
highlightedNotePathTitle?: string;
|
||||
};
|
||||
|
||||
// this key needs to have this value, so it's hit by the tooltip
|
||||
const SELECTED_NOTE_PATH_KEY = "data-note-path";
|
||||
@ -23,14 +41,39 @@ function getSearchDelay(notesCount: number): number {
|
||||
}
|
||||
let searchDelay = getSearchDelay(notesCount);
|
||||
|
||||
// TODO: Deduplicate with server.
|
||||
// String values ensure stable, human-readable identifiers across serialization (JSON, CKEditor, logs).
|
||||
export enum SuggestionAction {
|
||||
// These values intentionally mirror CreateNoteAction string values 1:1.
|
||||
// This overlap ensures that when a suggestion triggers a note creation callback,
|
||||
// the receiving features (e.g. note creation handlers, CKEditor mentions) can interpret
|
||||
// the action type consistently
|
||||
CreateNote = CreateNoteAction.CreateNote,
|
||||
CreateChildNote = CreateNoteAction.CreateChildNote,
|
||||
CreateAndLinkNote = CreateNoteAction.CreateAndLinkNote,
|
||||
CreateAndLinkChildNote = CreateNoteAction.CreateAndLinkChildNote,
|
||||
|
||||
SearchNotes = "search-notes",
|
||||
ExternalLink = "external-link",
|
||||
Command = "command",
|
||||
}
|
||||
|
||||
export enum SuggestionMode {
|
||||
SuggestNothing = "nothing",
|
||||
SuggestCreateOnly = "create-only",
|
||||
SuggestCreateAndLink = "create-and-link"
|
||||
}
|
||||
|
||||
// NOTE: Previously marked for deduplication with a server-side type,
|
||||
// but review on 2025-10-12 (using `rg Suggestion`) found no corresponding
|
||||
// server implementation.
|
||||
// This interface appears to be client-only.
|
||||
export interface Suggestion {
|
||||
noteTitle?: string;
|
||||
externalLink?: string;
|
||||
notePathTitle?: string;
|
||||
notePath?: string;
|
||||
highlightedNotePathTitle?: string;
|
||||
action?: string | "create-note" | "search-notes" | "external-link" | "command";
|
||||
action?: SuggestionAction;
|
||||
parentNoteId?: string;
|
||||
icon?: string;
|
||||
commandId?: string;
|
||||
@ -43,7 +86,7 @@ export interface Suggestion {
|
||||
export interface Options {
|
||||
container?: HTMLElement | null;
|
||||
fastSearch?: boolean;
|
||||
allowCreatingNotes?: boolean;
|
||||
suggestionMode?: SuggestionMode;
|
||||
allowJumpToSearchNotes?: boolean;
|
||||
allowExternalLinks?: boolean;
|
||||
/** If set, hides the right-side button corresponding to go to selected note. */
|
||||
@ -54,110 +97,160 @@ export interface Options {
|
||||
isCommandPalette?: boolean;
|
||||
}
|
||||
|
||||
async function autocompleteSourceForCKEditor(queryText: string) {
|
||||
return await new Promise<MentionFeedObjectItem[]>((res, rej) => {
|
||||
async function autocompleteSourceForCKEditor(
|
||||
queryText: string,
|
||||
suggestionMode: SuggestionMode
|
||||
): Promise<MentionFeedObjectItem[]> {
|
||||
// Wrap the callback-based autocompleteSource in a Promise for async/await
|
||||
const rows = await new Promise<Suggestion[]>((resolve) => {
|
||||
autocompleteSource(
|
||||
queryText,
|
||||
(rows) => {
|
||||
res(
|
||||
rows.map((row) => {
|
||||
return {
|
||||
action: row.action,
|
||||
noteTitle: row.noteTitle,
|
||||
id: `@${row.notePathTitle}`,
|
||||
name: row.notePathTitle || "",
|
||||
link: `#${row.notePath}`,
|
||||
notePath: row.notePath,
|
||||
highlightedNotePathTitle: row.highlightedNotePathTitle
|
||||
};
|
||||
})
|
||||
);
|
||||
},
|
||||
(suggestions) => resolve(suggestions),
|
||||
{
|
||||
allowCreatingNotes: true
|
||||
suggestionMode,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Map internal suggestions to CKEditor mention feed items
|
||||
return rows.map((row): ExtendedMentionFeedObjectItem => ({
|
||||
action: row.action?.toString(),
|
||||
noteTitle: row.noteTitle,
|
||||
id: `@${row.notePathTitle}`,
|
||||
name: row.notePathTitle || "",
|
||||
link: `#${row.notePath}`,
|
||||
notePath: row.notePath,
|
||||
parentNoteId: row.parentNoteId,
|
||||
highlightedNotePathTitle: row.highlightedNotePathTitle
|
||||
}));
|
||||
}
|
||||
|
||||
async function autocompleteSource(term: string, cb: (rows: Suggestion[]) => void, options: Options = {}) {
|
||||
async function autocompleteSource(
|
||||
term: string,
|
||||
callback: (rows: Suggestion[]) => void,
|
||||
options: Options = {}
|
||||
) {
|
||||
// Check if we're in command mode
|
||||
if (options.isCommandPalette && term.startsWith(">")) {
|
||||
const commandQuery = term.substring(1).trim();
|
||||
|
||||
// Get commands (all if no query, filtered if query provided)
|
||||
const commands = commandQuery.length === 0
|
||||
? commandRegistry.getAllCommands()
|
||||
: commandRegistry.searchCommands(commandQuery);
|
||||
const commands =
|
||||
commandQuery.length === 0
|
||||
? commandRegistry.getAllCommands()
|
||||
: commandRegistry.searchCommands(commandQuery);
|
||||
|
||||
// Convert commands to suggestions
|
||||
const commandSuggestions: Suggestion[] = commands.map(cmd => ({
|
||||
action: "command",
|
||||
const commandSuggestions: Suggestion[] = commands.map((cmd) => ({
|
||||
action: SuggestionAction.Command,
|
||||
commandId: cmd.id,
|
||||
noteTitle: cmd.name,
|
||||
notePathTitle: `>${cmd.name}`,
|
||||
highlightedNotePathTitle: cmd.name,
|
||||
commandDescription: cmd.description,
|
||||
commandShortcut: cmd.shortcut,
|
||||
icon: cmd.icon
|
||||
icon: cmd.icon,
|
||||
}));
|
||||
|
||||
cb(commandSuggestions);
|
||||
callback(commandSuggestions);
|
||||
return;
|
||||
}
|
||||
|
||||
const fastSearch = options.fastSearch === false ? false : true;
|
||||
if (fastSearch === false) {
|
||||
if (term.trim().length === 0) {
|
||||
return;
|
||||
}
|
||||
cb([
|
||||
const fastSearch = options.fastSearch !== false;
|
||||
const trimmedTerm = term.trim();
|
||||
const activeNoteId = appContext.tabManager.getActiveContextNoteId();
|
||||
|
||||
if (!fastSearch && trimmedTerm.length === 0) return;
|
||||
|
||||
if (!fastSearch) {
|
||||
callback([
|
||||
{
|
||||
noteTitle: term,
|
||||
highlightedNotePathTitle: t("quick-search.searching")
|
||||
}
|
||||
noteTitle: trimmedTerm,
|
||||
highlightedNotePathTitle: t("quick-search.searching"),
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
const activeNoteId = appContext.tabManager.getActiveContextNoteId();
|
||||
const length = term.trim().length;
|
||||
|
||||
let results = await server.get<Suggestion[]>(`autocomplete?query=${encodeURIComponent(term)}&activeNoteId=${activeNoteId}&fastSearch=${fastSearch}`);
|
||||
let results = await server.get<Suggestion[]>(
|
||||
`autocomplete?query=${encodeURIComponent(trimmedTerm)}&activeNoteId=${activeNoteId}&fastSearch=${fastSearch}`
|
||||
);
|
||||
|
||||
options.fastSearch = true;
|
||||
|
||||
if (length >= 1 && options.allowCreatingNotes) {
|
||||
results = [
|
||||
{
|
||||
action: "create-note",
|
||||
noteTitle: term,
|
||||
parentNoteId: activeNoteId || "root",
|
||||
highlightedNotePathTitle: t("note_autocomplete.create-note", { term })
|
||||
} as Suggestion
|
||||
].concat(results);
|
||||
}
|
||||
|
||||
if (length >= 1 && options.allowJumpToSearchNotes) {
|
||||
results = results.concat([
|
||||
{
|
||||
action: "search-notes",
|
||||
noteTitle: term,
|
||||
highlightedNotePathTitle: `${t("note_autocomplete.search-for", { term })} <kbd style='color: var(--muted-text-color); background-color: transparent; float: right;'>Ctrl+Enter</kbd>`
|
||||
// --- Create Note suggestions ---
|
||||
if (trimmedTerm.length >= 1) {
|
||||
switch (options.suggestionMode) {
|
||||
case SuggestionMode.SuggestCreateOnly: {
|
||||
results = [
|
||||
{
|
||||
action: SuggestionAction.CreateNote,
|
||||
noteTitle: trimmedTerm,
|
||||
parentNoteId: "inbox",
|
||||
highlightedNotePathTitle: t("note_autocomplete.create-note", { term: trimmedTerm }),
|
||||
},
|
||||
{
|
||||
action: SuggestionAction.CreateChildNote,
|
||||
noteTitle: trimmedTerm,
|
||||
parentNoteId: activeNoteId || "root",
|
||||
highlightedNotePathTitle: t("note_autocomplete.create-child-note", { term: trimmedTerm }),
|
||||
},
|
||||
...results,
|
||||
];
|
||||
break;
|
||||
}
|
||||
]);
|
||||
|
||||
case SuggestionMode.SuggestCreateAndLink: {
|
||||
results = [
|
||||
{
|
||||
action: SuggestionAction.CreateAndLinkNote,
|
||||
noteTitle: trimmedTerm,
|
||||
parentNoteId: "inbox",
|
||||
highlightedNotePathTitle: t("note_autocomplete.create-and-link-note", { term: trimmedTerm }),
|
||||
},
|
||||
{
|
||||
action: SuggestionAction.CreateAndLinkChildNote,
|
||||
noteTitle: trimmedTerm,
|
||||
parentNoteId: activeNoteId || "root",
|
||||
highlightedNotePathTitle: t("note_autocomplete.create-and-link-child-note", { term: trimmedTerm }),
|
||||
},
|
||||
...results,
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// CreateMode.None or undefined → no creation suggestions
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (term.match(/^[a-z]+:\/\/.+/i) && options.allowExternalLinks) {
|
||||
// --- Jump to Search Notes ---
|
||||
if (trimmedTerm.length >= 1 && options.allowJumpToSearchNotes) {
|
||||
results = [
|
||||
...results,
|
||||
{
|
||||
action: SuggestionAction.SearchNotes,
|
||||
noteTitle: trimmedTerm,
|
||||
highlightedNotePathTitle: `${t("note_autocomplete.search-for", {
|
||||
term: trimmedTerm,
|
||||
})} <kbd style='color: var(--muted-text-color); background-color: transparent; float: right;'>Ctrl+Enter</kbd>`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// --- External Link suggestion ---
|
||||
if (/^[a-z]+:\/\/.+/i.test(trimmedTerm) && options.allowExternalLinks) {
|
||||
results = [
|
||||
{
|
||||
action: "external-link",
|
||||
externalLink: term,
|
||||
highlightedNotePathTitle: t("note_autocomplete.insert-external-link", { term })
|
||||
} as Suggestion
|
||||
].concat(results);
|
||||
action: SuggestionAction.ExternalLink,
|
||||
externalLink: trimmedTerm,
|
||||
highlightedNotePathTitle: t("note_autocomplete.insert-external-link", { term: trimmedTerm }),
|
||||
},
|
||||
...results,
|
||||
];
|
||||
}
|
||||
|
||||
cb(results);
|
||||
callback(results);
|
||||
}
|
||||
|
||||
function clearText($el: JQuery<HTMLElement>) {
|
||||
@ -198,6 +291,85 @@ function fullTextSearch($el: JQuery<HTMLElement>, options: Options) {
|
||||
$el.autocomplete("val", searchString);
|
||||
}
|
||||
|
||||
function renderCommandSuggestion(s: Suggestion): string {
|
||||
const icon = s.icon || "bx bx-terminal";
|
||||
const shortcut = s.commandShortcut
|
||||
? `<kbd class="command-shortcut">${s.commandShortcut}</kbd>`
|
||||
: "";
|
||||
|
||||
return `
|
||||
<div class="command-suggestion">
|
||||
<span class="command-icon ${icon}"></span>
|
||||
<div class="command-content">
|
||||
<div class="command-name">${s.highlightedNotePathTitle}</div>
|
||||
${s.commandDescription ? `<div class="command-description">${s.commandDescription}</div>` : ""}
|
||||
</div>
|
||||
${shortcut}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderNoteSuggestion(s: Suggestion): string {
|
||||
const actionClass =
|
||||
s.action === SuggestionAction.SearchNotes ? "search-notes-action" : "";
|
||||
|
||||
const iconClass = (() => {
|
||||
switch (s.action) {
|
||||
case SuggestionAction.SearchNotes:
|
||||
return "bx bx-search";
|
||||
case SuggestionAction.CreateAndLinkNote:
|
||||
case SuggestionAction.CreateNote:
|
||||
return "bx bx-plus";
|
||||
case SuggestionAction.CreateAndLinkChildNote:
|
||||
case SuggestionAction.CreateChildNote:
|
||||
return "bx bx-plus";
|
||||
case SuggestionAction.ExternalLink:
|
||||
return "bx bx-link-external";
|
||||
default:
|
||||
return s.icon ?? "bx bx-note";
|
||||
}
|
||||
})();
|
||||
|
||||
return `
|
||||
<div class="note-suggestion ${actionClass}" style="display:inline-flex; align-items:center;">
|
||||
<span class="icon ${iconClass}" style="display:inline-block; vertical-align:middle; line-height:1; margin-right:0.4em;"></span>
|
||||
<span class="text" style="display:inline-block; vertical-align:middle;">
|
||||
<span class="search-result-title">${s.highlightedNotePathTitle}</span>
|
||||
${s.highlightedAttributeSnippet
|
||||
? `<span class="search-result-attributes">${s.highlightedAttributeSnippet}</span>`
|
||||
: ""}
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderSuggestion(suggestion: Suggestion): string {
|
||||
return suggestion.action === SuggestionAction.Command
|
||||
? renderCommandSuggestion(suggestion)
|
||||
: renderNoteSuggestion(suggestion);
|
||||
}
|
||||
|
||||
function mapSuggestionToCreateNoteAction(
|
||||
action: SuggestionAction
|
||||
): CreateNoteAction | null {
|
||||
switch (action) {
|
||||
case SuggestionAction.CreateNote:
|
||||
return CreateNoteAction.CreateNote;
|
||||
|
||||
case SuggestionAction.CreateAndLinkNote:
|
||||
return CreateNoteAction.CreateAndLinkNote;
|
||||
|
||||
case SuggestionAction.CreateChildNote:
|
||||
return CreateNoteAction.CreateChildNote;
|
||||
|
||||
case SuggestionAction.CreateAndLinkChildNote:
|
||||
return CreateNoteAction.CreateAndLinkChildNote;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function initNoteAutocomplete($el: JQuery<HTMLElement>, options?: Options) {
|
||||
if ($el.hasClass("note-autocomplete-input")) {
|
||||
// clear any event listener added in previous invocation of this function
|
||||
@ -283,24 +455,21 @@ function initNoteAutocomplete($el: JQuery<HTMLElement>, options?: Options) {
|
||||
$el.autocomplete(
|
||||
{
|
||||
...autocompleteOptions,
|
||||
appendTo: document.querySelector("body"),
|
||||
appendTo: document.body,
|
||||
hint: false,
|
||||
autoselect: true,
|
||||
// openOnFocus has to be false, otherwise re-focus (after return from note type chooser dialog) forces
|
||||
// re-querying of the autocomplete source which then changes the currently selected suggestion
|
||||
openOnFocus: false,
|
||||
minLength: 0,
|
||||
tabAutocomplete: false
|
||||
tabAutocomplete: false,
|
||||
},
|
||||
[
|
||||
{
|
||||
source: (term, cb) => {
|
||||
source: (term, callback) => {
|
||||
clearTimeout(debounceTimeoutId);
|
||||
debounceTimeoutId = setTimeout(() => {
|
||||
if (isComposingInput) {
|
||||
return;
|
||||
if (!isComposingInput) {
|
||||
autocompleteSource(term, callback, options);
|
||||
}
|
||||
autocompleteSource(term, cb, options);
|
||||
}, searchDelay);
|
||||
|
||||
if (searchDelay === 0) {
|
||||
@ -308,109 +477,85 @@ function initNoteAutocomplete($el: JQuery<HTMLElement>, options?: Options) {
|
||||
}
|
||||
},
|
||||
displayKey: "notePathTitle",
|
||||
templates: {
|
||||
suggestion: (suggestion) => {
|
||||
if (suggestion.action === "command") {
|
||||
let html = `<div class="command-suggestion">`;
|
||||
html += `<span class="command-icon ${suggestion.icon || "bx bx-terminal"}"></span>`;
|
||||
html += `<div class="command-content">`;
|
||||
html += `<div class="command-name">${suggestion.highlightedNotePathTitle}</div>`;
|
||||
if (suggestion.commandDescription) {
|
||||
html += `<div class="command-description">${suggestion.commandDescription}</div>`;
|
||||
}
|
||||
html += `</div>`;
|
||||
if (suggestion.commandShortcut) {
|
||||
html += `<kbd class="command-shortcut">${suggestion.commandShortcut}</kbd>`;
|
||||
}
|
||||
html += '</div>';
|
||||
return html;
|
||||
}
|
||||
// Add special class for search-notes action
|
||||
const actionClass = suggestion.action === "search-notes" ? "search-notes-action" : "";
|
||||
|
||||
// Choose appropriate icon based on action
|
||||
let iconClass = suggestion.icon ?? "bx bx-note";
|
||||
if (suggestion.action === "search-notes") {
|
||||
iconClass = "bx bx-search";
|
||||
} else if (suggestion.action === "create-note") {
|
||||
iconClass = "bx bx-plus";
|
||||
} else if (suggestion.action === "external-link") {
|
||||
iconClass = "bx bx-link-external";
|
||||
}
|
||||
|
||||
// Simplified HTML structure without nested divs
|
||||
let html = `<div class="note-suggestion ${actionClass}">`;
|
||||
html += `<span class="icon ${iconClass}"></span>`;
|
||||
html += `<span class="text">`;
|
||||
html += `<span class="search-result-title">${suggestion.highlightedNotePathTitle}</span>`;
|
||||
|
||||
// Add attribute snippet inline if available
|
||||
if (suggestion.highlightedAttributeSnippet) {
|
||||
html += `<span class="search-result-attributes">${suggestion.highlightedAttributeSnippet}</span>`;
|
||||
}
|
||||
|
||||
html += `</span>`;
|
||||
html += `</div>`;
|
||||
return html;
|
||||
}
|
||||
},
|
||||
// we can't cache identical searches because notes can be created / renamed, new recent notes can be added
|
||||
cache: false
|
||||
}
|
||||
templates: { suggestion: renderSuggestion },
|
||||
cache: false,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
// TODO: Types fail due to "autocomplete:selected" not being registered in type definitions.
|
||||
($el as any).on("autocomplete:selected", async (event: Event, suggestion: Suggestion) => {
|
||||
if (suggestion.action === "command") {
|
||||
async function doCommand() {
|
||||
$el.autocomplete("close");
|
||||
$el.trigger("autocomplete:commandselected", [suggestion]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (suggestion.action === "external-link") {
|
||||
async function doExternalLink() {
|
||||
$el.setSelectedNotePath(null);
|
||||
$el.setSelectedExternalLink(suggestion.externalLink);
|
||||
|
||||
$el.autocomplete("val", suggestion.externalLink);
|
||||
$el.autocomplete("close");
|
||||
$el.trigger("autocomplete:externallinkselected", [suggestion]);
|
||||
}
|
||||
|
||||
async function resolveSuggestionNotePathUnderCurrentHoist(note: FNote) {
|
||||
const hoisted = appContext.tabManager.getActiveContext()?.hoistedNoteId;
|
||||
suggestion.notePath = note.getBestNotePathString(hoisted);
|
||||
}
|
||||
|
||||
async function doSearchNotes() {
|
||||
const searchString = suggestion.noteTitle;
|
||||
appContext.triggerCommand("searchNotes", { searchString });
|
||||
}
|
||||
|
||||
async function selectNoteFromAutocomplete(suggestion: Suggestion) {
|
||||
$el.setSelectedNotePath(suggestion.notePath);
|
||||
$el.setSelectedExternalLink(null);
|
||||
|
||||
$el.autocomplete("val", suggestion.noteTitle);
|
||||
|
||||
$el.autocomplete("close");
|
||||
|
||||
$el.trigger("autocomplete:externallinkselected", [suggestion]);
|
||||
|
||||
return;
|
||||
$el.trigger("autocomplete:noteselected", [suggestion]);
|
||||
}
|
||||
|
||||
if (suggestion.action === "create-note") {
|
||||
const { success, noteType, templateNoteId, notePath } = await noteCreateService.chooseNoteType();
|
||||
if (!success) {
|
||||
switch (suggestion.action) {
|
||||
case SuggestionAction.Command:
|
||||
await doCommand();
|
||||
return;
|
||||
|
||||
case SuggestionAction.ExternalLink:
|
||||
await doExternalLink();
|
||||
break;
|
||||
|
||||
case SuggestionAction.CreateNote:
|
||||
case SuggestionAction.CreateAndLinkNote:
|
||||
case SuggestionAction.CreateChildNote:
|
||||
case SuggestionAction.CreateAndLinkChildNote: {
|
||||
const createNoteAction = mapSuggestionToCreateNoteAction(
|
||||
suggestion.action
|
||||
)!;
|
||||
const { note } = await noteCreateService.createNoteFromAction(
|
||||
createNoteAction,
|
||||
true,
|
||||
suggestion.noteTitle,
|
||||
suggestion.parentNoteId,
|
||||
);
|
||||
|
||||
if (!note) break;
|
||||
|
||||
await resolveSuggestionNotePathUnderCurrentHoist(note);
|
||||
await selectNoteFromAutocomplete(suggestion);
|
||||
break;
|
||||
}
|
||||
const { note } = await noteCreateService.createNote( notePath || suggestion.parentNoteId, {
|
||||
title: suggestion.noteTitle,
|
||||
activate: false,
|
||||
type: noteType,
|
||||
templateNoteId: templateNoteId
|
||||
});
|
||||
|
||||
const hoistedNoteId = appContext.tabManager.getActiveContext()?.hoistedNoteId;
|
||||
suggestion.notePath = note?.getBestNotePathString(hoistedNoteId);
|
||||
case SuggestionAction.SearchNotes:
|
||||
await doSearchNotes();
|
||||
break;
|
||||
|
||||
default:
|
||||
await selectNoteFromAutocomplete(suggestion);
|
||||
}
|
||||
|
||||
if (suggestion.action === "search-notes") {
|
||||
const searchString = suggestion.noteTitle;
|
||||
appContext.triggerCommand("searchNotes", { searchString });
|
||||
return;
|
||||
}
|
||||
|
||||
$el.setSelectedNotePath(suggestion.notePath);
|
||||
$el.setSelectedExternalLink(null);
|
||||
|
||||
$el.autocomplete("val", suggestion.noteTitle);
|
||||
|
||||
$el.autocomplete("close");
|
||||
|
||||
$el.trigger("autocomplete:noteselected", [suggestion]);
|
||||
});
|
||||
|
||||
$el.on("autocomplete:closed", () => {
|
||||
|
||||
@ -10,8 +10,63 @@ import type FNote from "../entities/fnote.js";
|
||||
import type FBranch from "../entities/fbranch.js";
|
||||
import type { ChooseNoteTypeResponse } from "../widgets/dialogs/note_type_chooser.js";
|
||||
import type { CKTextEditor } from "@triliumnext/ckeditor5";
|
||||
import dateNoteService from "../services/date_notes.js";
|
||||
import { CreateNoteAction } from "@triliumnext/commons";
|
||||
|
||||
export interface CreateNoteOpts {
|
||||
/**
|
||||
* Defines the type hierarchy and rules for valid argument combinations
|
||||
* accepted by `note_create`.
|
||||
*
|
||||
* ## Overview
|
||||
* Each variant extends `CreateNoteOpts` and enforces specific constraints to
|
||||
* ensure only valid note creation options are allowed at compile time.
|
||||
*
|
||||
* ## Type Safety
|
||||
* The `PromptingRule` ensures that `promptForType` and `type` stay mutually
|
||||
* exclusive (if prompting, `type` is undefined).
|
||||
*
|
||||
* The type system prevents invalid argument mixes by design — successful type
|
||||
* checks guarantee a valid state, following Curry–Howard correspondence
|
||||
* principles (types as proofs).
|
||||
*
|
||||
* ## Maintenance
|
||||
* If adding or modifying `Opts`, ensure:
|
||||
* - All valid combinations are represented (avoid *false negatives*).
|
||||
* - No invalid ones slip through (avoid *false positives*).
|
||||
*
|
||||
* Hierarchy (general → specific):
|
||||
* - CreateNoteOpts
|
||||
* - CreateNoteWithUrlOpts
|
||||
* - CreateNoteIntoDefaultOpts
|
||||
*/
|
||||
|
||||
/** enforces a truth rule:
|
||||
* - If `promptForType` is true → `type` must be undefined.
|
||||
* - If `promptForType` is false → `type` must be defined.
|
||||
*/
|
||||
type PromptingRule = {
|
||||
promptForType: true;
|
||||
type?: never;
|
||||
} | {
|
||||
promptForType?: false;
|
||||
/**
|
||||
* The note type (e.g. "text", "code", "image", "mermaid", etc.).
|
||||
*
|
||||
* If omitted, the server will automatically default to `"text"`.
|
||||
* TypeScript still enforces explicit typing unless `promptForType` is true,
|
||||
* to encourage clarity at the call site.
|
||||
*/
|
||||
type?: string;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base type for all note creation options (domain hypernym).
|
||||
* All specific note option types extend from this.
|
||||
*
|
||||
* Combine with `&` to ensure valid logical combinations.
|
||||
*/
|
||||
type CreateNoteBase = {
|
||||
isProtected?: boolean;
|
||||
saveSelection?: boolean;
|
||||
title?: string | null;
|
||||
@ -21,10 +76,34 @@ export interface CreateNoteOpts {
|
||||
templateNoteId?: string;
|
||||
activate?: boolean;
|
||||
focus?: "title" | "content";
|
||||
target?: string;
|
||||
targetBranchId?: string;
|
||||
textEditor?: CKTextEditor;
|
||||
}
|
||||
} & PromptingRule;
|
||||
|
||||
/*
|
||||
* Defines options for creating a note at a specific path.
|
||||
* Serves as a base for "into", "before", and "after" variants,
|
||||
* sharing common URL-related fields.
|
||||
*/
|
||||
export type CreateNoteWithLinkOpts =
|
||||
| (CreateNoteBase & {
|
||||
target: "into";
|
||||
parentNoteLink?: string;
|
||||
// No branch ID needed for "into"
|
||||
})
|
||||
| (CreateNoteBase & {
|
||||
target: "before" | "after";
|
||||
// Either an Url or a Path
|
||||
parentNoteLink?: string;
|
||||
// Required for "before"/"after"
|
||||
targetBranchId: string;
|
||||
});
|
||||
|
||||
export type CreateNoteIntoDefaultOpts = CreateNoteBase & {
|
||||
target: "default";
|
||||
parentNoteLink?: never;
|
||||
};
|
||||
|
||||
export type CreateNoteOpts = CreateNoteWithLinkOpts | CreateNoteIntoDefaultOpts;
|
||||
|
||||
interface Response {
|
||||
// TODO: Deduplicate with server once we have client/server architecture.
|
||||
@ -37,7 +116,141 @@ interface DuplicateResponse {
|
||||
note: FNote;
|
||||
}
|
||||
|
||||
async function createNote(parentNotePath: string | undefined, options: CreateNoteOpts = {}) {
|
||||
// The low level note creation
|
||||
async function createNote(
|
||||
options: CreateNoteOpts
|
||||
): Promise<{ note: FNote | null; branch: FBranch | undefined }> {
|
||||
|
||||
let resolvedOptions = { ...options };
|
||||
|
||||
// handle prompts centrally to write once fix for all
|
||||
if (options.promptForType) {
|
||||
const maybeResolvedOptions = await promptForType(options);
|
||||
if (!maybeResolvedOptions) {
|
||||
return { note: null, branch: undefined };
|
||||
}
|
||||
|
||||
resolvedOptions = maybeResolvedOptions;
|
||||
}
|
||||
|
||||
|
||||
switch(resolvedOptions.target) {
|
||||
case "default":
|
||||
return createNoteIntoDefaultLocation(resolvedOptions);
|
||||
case "into":
|
||||
case "before":
|
||||
case "after":
|
||||
return createNoteWithLink(resolvedOptions);
|
||||
}
|
||||
}
|
||||
|
||||
// A wrapper to standardize note creation
|
||||
async function createNoteFromAction(
|
||||
action: CreateNoteAction,
|
||||
promptForType: boolean,
|
||||
title: string | undefined,
|
||||
parentNoteLink: string | undefined,
|
||||
): Promise<{ note: FNote | null; branch: FBranch | undefined }> {
|
||||
switch (action) {
|
||||
case CreateNoteAction.CreateNote: {
|
||||
const resp = await createNote(
|
||||
{
|
||||
target: "default",
|
||||
title: title,
|
||||
activate: true,
|
||||
promptForType,
|
||||
}
|
||||
);
|
||||
return resp;
|
||||
}
|
||||
case CreateNoteAction.CreateAndLinkNote: {
|
||||
const resp = await createNote(
|
||||
{
|
||||
target: "default",
|
||||
title,
|
||||
activate: false,
|
||||
promptForType,
|
||||
}
|
||||
);
|
||||
return resp;
|
||||
}
|
||||
case CreateNoteAction.CreateChildNote: {
|
||||
if (!parentNoteLink) {
|
||||
console.warn("createNoteFromAction: Missing parentNoteLink");
|
||||
return { note: null, branch: undefined };
|
||||
}
|
||||
|
||||
const resp = await createNote(
|
||||
{
|
||||
target: "into",
|
||||
parentNoteLink,
|
||||
title,
|
||||
activate: true,
|
||||
promptForType,
|
||||
},
|
||||
);
|
||||
return resp
|
||||
}
|
||||
case CreateNoteAction.CreateAndLinkChildNote: {
|
||||
if (!parentNoteLink) {
|
||||
console.warn("createNoteFromAction: Missing parentNoteLink");
|
||||
return { note: null, branch: undefined };
|
||||
}
|
||||
const resp = await createNote(
|
||||
{
|
||||
target: "into",
|
||||
parentNoteLink: parentNoteLink,
|
||||
title,
|
||||
activate: false,
|
||||
promptForType,
|
||||
},
|
||||
)
|
||||
return resp;
|
||||
}
|
||||
|
||||
default:
|
||||
console.warn("Unknown CreateNoteAction:", action);
|
||||
return { note: null, branch: undefined };
|
||||
}
|
||||
}
|
||||
|
||||
async function promptForType(
|
||||
options: CreateNoteOpts
|
||||
) : Promise<CreateNoteOpts | null> {
|
||||
const { success, noteType, templateNoteId, notePath } = await chooseNoteType();
|
||||
|
||||
if (!success) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let resolvedOptions: CreateNoteOpts = {
|
||||
...options,
|
||||
promptForType: false,
|
||||
type: noteType,
|
||||
templateNoteId,
|
||||
};
|
||||
|
||||
if (notePath) {
|
||||
resolvedOptions = {
|
||||
...resolvedOptions,
|
||||
target: "into",
|
||||
parentNoteLink: notePath,
|
||||
};
|
||||
}
|
||||
|
||||
return resolvedOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new note under a specified parent note path.
|
||||
*
|
||||
* @param target - Mirrors the `createNote` API in apps/server/src/routes/api/notes.ts.
|
||||
* @param options - Note creation options
|
||||
* @returns A promise resolving with the created note and its branch.
|
||||
*/
|
||||
async function createNoteWithLink(
|
||||
options: CreateNoteWithLinkOpts
|
||||
): Promise<{ note: FNote | null; branch: FBranch | undefined }> {
|
||||
options = Object.assign(
|
||||
{
|
||||
activate: true,
|
||||
@ -61,7 +274,8 @@ async function createNote(parentNotePath: string | undefined, options: CreateNot
|
||||
[options.title, options.content] = parseSelectedHtml(options.textEditor.getSelectedHtml());
|
||||
}
|
||||
|
||||
const parentNoteId = treeService.getNoteIdFromUrl(parentNotePath);
|
||||
const parentNoteLink = options.parentNoteLink;
|
||||
const parentNoteId = treeService.getNoteIdFromLink(parentNoteLink);
|
||||
|
||||
if (options.type === "mermaid" && !options.content && !options.templateNoteId) {
|
||||
options.content = `graph TD;
|
||||
@ -71,7 +285,12 @@ async function createNote(parentNotePath: string | undefined, options: CreateNot
|
||||
C-->D;`;
|
||||
}
|
||||
|
||||
const { note, branch } = await server.post<Response>(`notes/${parentNoteId}/children?target=${options.target}&targetBranchId=${options.targetBranchId || ""}`, {
|
||||
const query =
|
||||
options.target === "into"
|
||||
? `target=${options.target}`
|
||||
: `target=${options.target}&targetBranchId=${options.targetBranchId}`;
|
||||
|
||||
const { note, branch } = await server.post<Response>(`notes/${parentNoteId}/children?${query}`, {
|
||||
title: options.title,
|
||||
content: options.content || "",
|
||||
isProtected: options.isProtected,
|
||||
@ -89,7 +308,7 @@ async function createNote(parentNotePath: string | undefined, options: CreateNot
|
||||
|
||||
const activeNoteContext = appContext.tabManager.getActiveContext();
|
||||
if (activeNoteContext && options.activate) {
|
||||
await activeNoteContext.setNote(`${parentNotePath}/${note.noteId}`);
|
||||
await activeNoteContext.setNote(`${parentNoteId}/${note.noteId}`);
|
||||
|
||||
if (options.focus === "title") {
|
||||
appContext.triggerEvent("focusAndSelectTitle", { isNewNote: true });
|
||||
@ -107,25 +326,46 @@ async function createNote(parentNotePath: string | undefined, options: CreateNot
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new note inside the user's Inbox.
|
||||
*
|
||||
* @param {CreateNoteIntoDefaultOpts} [options] - Optional settings such as title, type, template, or content.
|
||||
* @returns {Promise<{ note: FNote | null; branch: FBranch | undefined }>}
|
||||
* Resolves with the created note and its branch, or `{ note: null, branch: undefined }` if the inbox is missing.
|
||||
*/
|
||||
async function createNoteIntoDefaultLocation(
|
||||
options: CreateNoteIntoDefaultOpts
|
||||
): Promise<{ note: FNote | null; branch: FBranch | undefined }> {
|
||||
const inboxNote = await dateNoteService.getInboxNote();
|
||||
if (!inboxNote) {
|
||||
console.warn("Missing inbox note.");
|
||||
// always return a defined object
|
||||
return { note: null, branch: undefined };
|
||||
}
|
||||
|
||||
if (options.isProtected === undefined) {
|
||||
options.isProtected =
|
||||
inboxNote.isProtected && protectedSessionHolder.isProtectedSessionAvailable();
|
||||
}
|
||||
|
||||
const result = await createNoteWithLink(
|
||||
{
|
||||
...options,
|
||||
target: "into",
|
||||
parentNoteLink: inboxNote.getBestNotePathString(),
|
||||
}
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async function chooseNoteType() {
|
||||
return new Promise<ChooseNoteTypeResponse>((res) => {
|
||||
appContext.triggerCommand("chooseNoteType", { callback: res });
|
||||
});
|
||||
}
|
||||
|
||||
async function createNoteWithTypePrompt(parentNotePath: string, options: CreateNoteOpts = {}) {
|
||||
const { success, noteType, templateNoteId, notePath } = await chooseNoteType();
|
||||
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
options.type = noteType;
|
||||
options.templateNoteId = templateNoteId;
|
||||
|
||||
return await createNote(notePath || parentNotePath, options);
|
||||
}
|
||||
|
||||
/* If the first element is heading, parse it out and use it as a new heading. */
|
||||
function parseSelectedHtml(selectedHtml: string) {
|
||||
const dom = $.parseHTML(selectedHtml);
|
||||
@ -146,7 +386,7 @@ function parseSelectedHtml(selectedHtml: string) {
|
||||
}
|
||||
|
||||
async function duplicateSubtree(noteId: string, parentNotePath: string) {
|
||||
const parentNoteId = treeService.getNoteIdFromUrl(parentNotePath);
|
||||
const parentNoteId = treeService.getNoteIdFromLink(parentNotePath);
|
||||
const { note } = await server.post<DuplicateResponse>(`notes/${noteId}/duplicate/${parentNoteId}`);
|
||||
|
||||
await ws.waitForMaxKnownEntityChangeId();
|
||||
@ -159,7 +399,6 @@ async function duplicateSubtree(noteId: string, parentNotePath: string) {
|
||||
|
||||
export default {
|
||||
createNote,
|
||||
createNoteWithTypePrompt,
|
||||
createNoteFromAction,
|
||||
duplicateSubtree,
|
||||
chooseNoteType
|
||||
};
|
||||
|
||||
@ -92,7 +92,7 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
|
||||
if (effectivePathSegments.includes(hoistedNoteId) && effectivePathSegments.includes('root')) {
|
||||
return effectivePathSegments;
|
||||
} else {
|
||||
const noteId = getNoteIdFromUrl(notePath);
|
||||
const noteId = getNoteIdFromLink(notePath);
|
||||
if (!noteId) {
|
||||
throw new Error(`Unable to find note with ID: ${noteId}.`);
|
||||
}
|
||||
@ -129,7 +129,7 @@ function getParentProtectedStatus(node: Fancytree.FancytreeNode) {
|
||||
return hoistedNoteService.isHoistedNode(node) ? false : node.getParent().data.isProtected;
|
||||
}
|
||||
|
||||
function getNoteIdFromUrl(urlOrNotePath: string | null | undefined) {
|
||||
function getNoteIdFromLink(urlOrNotePath: string | null | undefined) {
|
||||
if (!urlOrNotePath) {
|
||||
return null;
|
||||
}
|
||||
@ -306,7 +306,7 @@ export default {
|
||||
getParentProtectedStatus,
|
||||
getNotePath,
|
||||
getNotePathTitleComponents,
|
||||
getNoteIdFromUrl,
|
||||
getNoteIdFromLink,
|
||||
getNoteIdAndParentIdFromUrl,
|
||||
getBranchIdFromUrl,
|
||||
getNoteTitle,
|
||||
|
||||
@ -439,7 +439,8 @@ body.desktop .tabulator-popup-container,
|
||||
}
|
||||
|
||||
body.desktop .dropdown-menu:not(#context-menu-container) .dropdown-item,
|
||||
body #context-menu-container .dropdown-item > span {
|
||||
body #context-menu-container .dropdown-item > span,
|
||||
body.mobile .dropdown .dropdown-submenu > span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@ -1315,11 +1316,11 @@ body.mobile #context-menu-container.mobile-bottom-menu {
|
||||
inset-inline-end: 0 !important;
|
||||
bottom: 0 !important;
|
||||
top: unset !important;
|
||||
max-height: 70vh;
|
||||
max-height: 90vh;
|
||||
overflow: auto !important;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
padding-bottom: env(safe-area-inset-bottom) !important;
|
||||
padding-bottom: max(env(safe-area-inset-bottom), var(--padding, var(--menu-padding-size))) !important;
|
||||
}
|
||||
|
||||
body.mobile .dropdown-menu {
|
||||
@ -2008,7 +2009,7 @@ body.electron.platform-darwin:not(.native-titlebar) .tab-row-container {
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
body.electron.platform-darwin:not(.native-titlebar) #tab-row-left-spacer {
|
||||
body.electron.platform-darwin:not(.native-titlebar):not(.full-screen) #tab-row-left-spacer {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
|
||||
@ -119,17 +119,6 @@ body.backdrop-effects-disabled {
|
||||
font-size: 0.9rem !important;
|
||||
}
|
||||
|
||||
body.mobile .dropdown-menu {
|
||||
backdrop-filter: var(--dropdown-backdrop-filter);
|
||||
border-radius: var(--dropdown-border-radius);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body.mobile .dropdown-menu .dropdown-menu {
|
||||
backdrop-filter: unset !important;
|
||||
border-radius: unset !important;
|
||||
}
|
||||
|
||||
body.desktop .dropdown-menu::before,
|
||||
:root .ck.ck-dropdown__panel::before,
|
||||
:root .excalidraw .popover::before,
|
||||
@ -157,17 +146,12 @@ body.desktop .dropdown-submenu .dropdown-menu::before {
|
||||
content: unset;
|
||||
}
|
||||
|
||||
body.mobile .dropdown-submenu .dropdown-menu {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
body.desktop .dropdown-submenu .dropdown-menu {
|
||||
backdrop-filter: var(--dropdown-backdrop-filter);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.dropdown-item,
|
||||
body.mobile .dropdown-submenu .dropdown-toggle,
|
||||
.excalidraw .context-menu .context-menu-item {
|
||||
--menu-item-start-padding: 8px;
|
||||
--menu-item-end-padding: 22px;
|
||||
@ -201,10 +185,6 @@ body.mobile .dropdown-item:not(:last-of-type) {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
body.mobile .dropdown-submenu:hover {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
html body .dropdown-item.disabled,
|
||||
html body .dropdown-item[disabled] {
|
||||
color: var(--menu-text-color) !important;
|
||||
@ -321,17 +301,102 @@ body.desktop .dropdown-menu.static .dropdown-item.active {
|
||||
--active-item-text-color: var(--menu-text-color);
|
||||
}
|
||||
|
||||
/* #region Mobile tweaks for dropdown menus */
|
||||
body.mobile #context-menu-cover {
|
||||
transition: background-color 150ms ease-in;
|
||||
|
||||
&.show {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
}
|
||||
|
||||
body.mobile .dropdown-menu {
|
||||
--dropdown-menu-padding-vertical: 0.7em;
|
||||
--dropdown-menu-padding-horizontal: 1em;
|
||||
--hover-item-background-color: var(--card-background-color);
|
||||
font-size: 1em !important;
|
||||
backdrop-filter: var(--dropdown-backdrop-filter);
|
||||
border-radius: var(--dropdown-border-radius) var(--dropdown-border-radius) 0 0;
|
||||
position: relative;
|
||||
|
||||
.dropdown-toggle::after {
|
||||
top: 0.5em;
|
||||
right: var(--dropdown-menu-padding-horizontal);
|
||||
transform: translateX(50%) rotate(90deg);
|
||||
}
|
||||
|
||||
.dropdown-item.submenu-open .dropdown-toggle::after {
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
.dropdown-item,
|
||||
.dropdown-custom-item {
|
||||
margin-bottom: 0;
|
||||
padding: var(--dropdown-menu-padding-vertical) var(--dropdown-menu-padding-horizontal) !important;
|
||||
background: var(--card-background-color);
|
||||
border-bottom: 1px solid var(--main-border-color) !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.dropdown-item:first-of-type,
|
||||
.dropdown-divider + .dropdown-item,
|
||||
.dropdown-custom-item:first-of-type,
|
||||
.dropdown-divider + .dropdown-custom-item {
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
}
|
||||
|
||||
.dropdown-item:last-of-type,
|
||||
.dropdown-item:has(+ .dropdown-divider),
|
||||
.dropdown-custom-item:last-of-type,
|
||||
.dropdown-custom-item:has(+ .dropdown-divider) {
|
||||
border-bottom-left-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.dropdown-divider {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.dropdown-submenu {
|
||||
padding: 0 !important;
|
||||
backdrop-filter: unset !important;
|
||||
|
||||
.dropdown-toggle {
|
||||
padding: var(--dropdown-menu-padding-vertical) var(--dropdown-menu-padding-horizontal);
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
--menu-background-color: rgba(0, 0, 0, 0.15);
|
||||
border-radius: 0;
|
||||
max-height: 0;
|
||||
transition: max-height 100ms ease-in;
|
||||
display: block !important;
|
||||
|
||||
&.show {
|
||||
max-height: 1000px;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&.submenu-open {
|
||||
.dropdown-toggle {
|
||||
padding-bottom: var(--dropdown-menu-padding-vertical);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
body.desktop .dropdown-menu .dropdown-toggle::after {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body.mobile .dropdown-menu .dropdown-toggle::after {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
body.mobile .dropdown-menu .dropdown-item.submenu-open .dropdown-toggle::after {
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
/* Dropdown item button (used in zoom buttons in global menu) */
|
||||
|
||||
|
||||
@ -230,7 +230,6 @@
|
||||
"geo-map": "الخريطة الجغرافية",
|
||||
"collapse_all_notes": "طي كل الملاحظات",
|
||||
"include_archived_notes": "عرض الملاحظات المؤرشفة",
|
||||
"expand_all_children": "توسيع جميع العناصر الفرعية",
|
||||
"presentation": "عرض تقديمي",
|
||||
"invalid_view_type": "نوع العرض {{type}} غير صالح"
|
||||
},
|
||||
|
||||
@ -764,7 +764,6 @@
|
||||
"grid": "网格",
|
||||
"list": "列表",
|
||||
"collapse_all_notes": "折叠所有笔记",
|
||||
"expand_all_children": "展开所有子项",
|
||||
"collapse": "折叠",
|
||||
"expand": "展开",
|
||||
"invalid_view_type": "无效的查看类型 '{{type}}'",
|
||||
@ -774,7 +773,11 @@
|
||||
"geo-map": "地理地图",
|
||||
"board": "看板",
|
||||
"include_archived_notes": "展示归档笔记",
|
||||
"presentation": "演示"
|
||||
"presentation": "演示",
|
||||
"expand_tooltip": "展开此集合的直接子代(单层深度)。点击右方箭头以查看更多选项。",
|
||||
"expand_first_level": "展开直接子代",
|
||||
"expand_nth_level": "展开 {{depth}} 层",
|
||||
"expand_all_levels": "展开所有层级"
|
||||
},
|
||||
"edited_notes": {
|
||||
"no_edited_notes_found": "今天还没有编辑过的笔记...",
|
||||
@ -1151,7 +1154,10 @@
|
||||
"unit": "字符"
|
||||
},
|
||||
"code_mime_types": {
|
||||
"title": "下拉菜单可用的MIME文件类型"
|
||||
"title": "下拉菜单可用的MIME文件类型",
|
||||
"tooltip_syntax_highlighting": "语法高亮",
|
||||
"tooltip_code_block_syntax": "文本笔记中的代码块",
|
||||
"tooltip_code_note_syntax": "代码笔记"
|
||||
},
|
||||
"vim_key_bindings": {
|
||||
"use_vim_keybindings_in_code_notes": "Vim 快捷键",
|
||||
@ -1695,7 +1701,8 @@
|
||||
"copy-link": "复制链接",
|
||||
"paste": "粘贴",
|
||||
"paste-as-plain-text": "以纯文本粘贴",
|
||||
"search_online": "用 {{searchEngine}} 搜索 \"{{term}}\""
|
||||
"search_online": "用 {{searchEngine}} 搜索 \"{{term}}\"",
|
||||
"search_in_trilium": "在 Trilium 中搜索「{{term}}」"
|
||||
},
|
||||
"image_context_menu": {
|
||||
"copy_reference_to_clipboard": "复制引用到剪贴板",
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
"link_title_arbitrary": "titulek odkazu může být změněn libovolně"
|
||||
},
|
||||
"branch_prefix": {
|
||||
"prefix": "Prefix: ",
|
||||
"prefix": "Předpona: ",
|
||||
"save": "Uložit",
|
||||
"edit_branch_prefix": "Upravit prefix větve",
|
||||
"edit_branch_prefix_multiple": "Upravit prefix větve pro {{count}} větví",
|
||||
@ -63,24 +63,59 @@
|
||||
"bulk_actions_executed": "Hromadné akce byly úspěšně provedeny.",
|
||||
"labels": "Štítky",
|
||||
"relations": "Relace",
|
||||
"other": "Ostatní"
|
||||
"other": "Ostatní",
|
||||
"none_yet": "Zatím žádné akce... přidejte akci kliknutím na jednu z dostupných výše."
|
||||
},
|
||||
"confirm": {
|
||||
"cancel": "Zrušit",
|
||||
"ok": "OK"
|
||||
"ok": "OK",
|
||||
"confirmation": "Potvrzení",
|
||||
"are_you_sure_remove_note": "Opravdu chcete odstranit poznámku „{{title}}“ z mapy vztahů?",
|
||||
"if_you_dont_check": "Pokud tuto možnost nezaškrtnete, poznámka bude odstraněna pouze z mapy vztahů.",
|
||||
"also_delete_note": "Odstraňte také poznámku"
|
||||
},
|
||||
"delete_notes": {
|
||||
"cancel": "Zrušit",
|
||||
"ok": "OK",
|
||||
"close": "Zavřít"
|
||||
"close": "Zavřít",
|
||||
"delete_notes_preview": "Odstranit náhled poznámek",
|
||||
"delete_all_clones_description": "Odstraňte také všechny klony (lze vrátit zpět v nedávných změnách)",
|
||||
"erase_notes_description": "Normální (měkké) smazání pouze označí poznámky jako smazané a lze je během určité doby obnovit (v dialogovém okně posledních změn). Zaškrtnutím této možnosti se poznámky okamžitě vymažou a nebude možné je obnovit.",
|
||||
"erase_notes_warning": "Trvale smažte poznámky (nelze vrátit zpět), včetně všech klonů. Tím se vynutí opětovné načtení aplikace.",
|
||||
"notes_to_be_deleted": "Následující poznámky budou smazány ({{notesCount}})",
|
||||
"no_note_to_delete": "Žádná poznámka nebude smazána (pouze klony).",
|
||||
"broken_relations_to_be_deleted": "Následující vazby budou přerušeny a smazány ({{relationCount}})",
|
||||
"deleted_relation_text": "Poznámka {{- note}} (bude smazána) je odkazována vazbou {{- relation}} pocházející z {{- source}}."
|
||||
},
|
||||
"export": {
|
||||
"close": "Zavřít"
|
||||
"close": "Zavřít",
|
||||
"export_note_title": "Exportovat poznámku",
|
||||
"export_type_subtree": "Tato poznámka a všechny její odvozené poznámky",
|
||||
"format_html": "HTML – doporučeno, protože zachovává veškeré formátování",
|
||||
"format_html_zip": "HTML v archivu ZIP – toto se doporučuje, protože se tak zachová veškeré formátování.",
|
||||
"format_markdown": "Markdown – zachovává většinu formátování.",
|
||||
"format_opml": "OPML – formát pro výměnu osnov pouze pro text. Formátování, obrázky a soubory nejsou zahrnuty.",
|
||||
"opml_version_1": "OPML v1.0 – pouze prostý text",
|
||||
"opml_version_2": "OPML v2.0 – umožňuje také HTML",
|
||||
"export_type_single": "Pouze tato poznámka bez jejích potomků",
|
||||
"export": "Exportovat",
|
||||
"choose_export_type": "Nejprve vyberte typ exportu",
|
||||
"export_status": "Stav exportu",
|
||||
"export_in_progress": "Export probíhá: {{progressCount}}",
|
||||
"export_finished_successfully": "Export byl úspěšně dokončen.",
|
||||
"format_pdf": "PDF – pro tisk nebo sdílení.",
|
||||
"share-format": "HTML pro publikování na webu – používá stejný motiv jako sdílené poznámky, ale lze jej publikovat jako statický web."
|
||||
},
|
||||
"clone_to": {
|
||||
"clone_notes_to": "Klonovat poznámky do...",
|
||||
"help_on_links": "Nápověda k odkazům",
|
||||
"notes_to_clone": "Poznámky na klonování",
|
||||
"search_for_note_by_its_name": "hledat poznámku dle jejího názvu"
|
||||
"search_for_note_by_its_name": "hledat poznámku dle jejího názvu",
|
||||
"prefix_optional": "Předpona (volitelná)",
|
||||
"target_parent_note": "Zaměřit rodičovskou poznámku",
|
||||
"cloned_note_prefix_title": "Klonovaná poznámka se zobrazí ve stromu poznámek s danou předponou",
|
||||
"clone_to_selected_note": "Klonovat vybranou poznámku",
|
||||
"no_path_to_clone_to": "Žádná cest pro klonování.",
|
||||
"note_cloned": "Poznámka: „{{clonedTitle}}“ bylo naklonováno do „{{targetTitle}}“"
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +39,9 @@
|
||||
"help_on_tree_prefix": "Hilfe zum Baumpräfix",
|
||||
"prefix": "Präfix: ",
|
||||
"save": "Speichern",
|
||||
"branch_prefix_saved": "Zweigpräfix wurde gespeichert."
|
||||
"branch_prefix_saved": "Zweigpräfix wurde gespeichert.",
|
||||
"branch_prefix_saved_multiple": "Der Zweigpräfix wurde für {{count}} Zweige gespeichert.",
|
||||
"edit_branch_prefix_multiple": "Präfix für {{count}} Zweige bearbeiten"
|
||||
},
|
||||
"bulk_actions": {
|
||||
"bulk_actions": "Massenaktionen",
|
||||
@ -684,7 +686,8 @@
|
||||
"convert_into_attachment_failed": "Konvertierung der Notiz '{{title}}' fehlgeschlagen.",
|
||||
"convert_into_attachment_successful": "Notiz '{{title}}' wurde als Anhang konvertiert.",
|
||||
"convert_into_attachment_prompt": "Bist du dir sicher, dass du die Notiz '{{title}}' in ein Anhang der übergeordneten Notiz konvertieren möchtest?",
|
||||
"print_pdf": "Export als PDF..."
|
||||
"print_pdf": "Export als PDF...",
|
||||
"open_note_on_server": "Öffne Notiz auf dem Server"
|
||||
},
|
||||
"onclick_button": {
|
||||
"no_click_handler": "Das Schaltflächen-Widget „{{componentId}}“ hat keinen definierten Klick-Handler"
|
||||
@ -757,7 +760,6 @@
|
||||
"grid": "Gitter",
|
||||
"list": "Liste",
|
||||
"collapse_all_notes": "Alle Notizen einklappen",
|
||||
"expand_all_children": "Unternotizen ausklappen",
|
||||
"collapse": "Einklappen",
|
||||
"expand": "Ausklappen",
|
||||
"invalid_view_type": "Ungültiger Ansichtstyp „{{type}}“",
|
||||
@ -767,7 +769,8 @@
|
||||
"geo-map": "Weltkarte",
|
||||
"board": "Tafel",
|
||||
"include_archived_notes": "Zeige archivierte Notizen",
|
||||
"presentation": "Präsentation"
|
||||
"presentation": "Präsentation",
|
||||
"expand_all_levels": "Alle Ebenen erweitern"
|
||||
},
|
||||
"edited_notes": {
|
||||
"no_edited_notes_found": "An diesem Tag wurden noch keine Notizen bearbeitet...",
|
||||
@ -1104,7 +1107,8 @@
|
||||
"title": "Inhaltsbreite",
|
||||
"default_description": "Trilium begrenzt standardmäßig die maximale Inhaltsbreite, um die Lesbarkeit für maximierte Bildschirme auf Breitbildschirmen zu verbessern.",
|
||||
"max_width_label": "Maximale Inhaltsbreite in Pixel",
|
||||
"max_width_unit": "Pixel"
|
||||
"max_width_unit": "Pixel",
|
||||
"centerContent": "Inhalt zentriert halten"
|
||||
},
|
||||
"native_title_bar": {
|
||||
"title": "Native Titelleiste (App-Neustart erforderlich)",
|
||||
@ -1143,7 +1147,10 @@
|
||||
"unit": "Zeichen"
|
||||
},
|
||||
"code_mime_types": {
|
||||
"title": "Verfügbare MIME-Typen im Dropdown-Menü"
|
||||
"title": "Verfügbare MIME-Typen im Dropdown-Menü",
|
||||
"tooltip_syntax_highlighting": "Syntaxhervorhebung",
|
||||
"tooltip_code_block_syntax": "Code-Blöcke in Textnotizen",
|
||||
"tooltip_code_note_syntax": "Code-Notizen"
|
||||
},
|
||||
"vim_key_bindings": {
|
||||
"use_vim_keybindings_in_code_notes": "Verwende VIM-Tastenkombinationen in Codenotizen (kein Ex-Modus)",
|
||||
@ -1654,7 +1661,8 @@
|
||||
"copy-link": "Link kopieren",
|
||||
"paste": "Einfügen",
|
||||
"paste-as-plain-text": "Als unformatierten Text einfügen",
|
||||
"search_online": "Suche nach \"{{term}}\" mit {{searchEngine}} starten"
|
||||
"search_online": "Suche nach \"{{term}}\" mit {{searchEngine}} starten",
|
||||
"search_in_trilium": "Suche nach \"{{term}}\" in Trilium"
|
||||
},
|
||||
"image_context_menu": {
|
||||
"copy_reference_to_clipboard": "Referenz in Zwischenablage kopieren",
|
||||
@ -2028,7 +2036,8 @@
|
||||
"new-item-placeholder": "Notiz Titel eingeben...",
|
||||
"add-column-placeholder": "Spaltenname eingeben...",
|
||||
"edit-note-title": "Klicke zum Editieren des Notiz-Titels",
|
||||
"edit-column-title": "Klicke zum Editieren des Spalten-Titels"
|
||||
"edit-column-title": "Klicke zum Editieren des Spalten-Titels",
|
||||
"column-already-exists": "Die Spalte ist auf dem Board bereits vorhanden."
|
||||
},
|
||||
"command_palette": {
|
||||
"tree-action-name": "Struktur: {{name}}",
|
||||
@ -2078,5 +2087,19 @@
|
||||
"edit-slide": "Folie bearbeiten",
|
||||
"start-presentation": "Präsentation starten",
|
||||
"slide-overview": "Übersicht der Folien ein-/ausblenden"
|
||||
},
|
||||
"read-only-info": {
|
||||
"read-only-note": "Aktuell wird eine Notiz nur im Lese-Modus angezeigt.",
|
||||
"auto-read-only-note": "Diese Notiz wird im Nur-Lesen-Modus angezeigt, um ein schnelleres Laden zu ermöglichen.",
|
||||
"auto-read-only-learn-more": "Mehr erfahren",
|
||||
"edit-note": "Notiz bearbeiten"
|
||||
},
|
||||
"calendar_view": {
|
||||
"delete_note": "Notiz löschen..."
|
||||
},
|
||||
"note-color": {
|
||||
"clear-color": "Notizfarbe entfernen",
|
||||
"set-color": "Notizfarbe wählen",
|
||||
"set-custom-color": "Eigene Notizfarbe wählen"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1727,7 +1727,8 @@
|
||||
"refresh-saved-search-results": "Refresh saved search results",
|
||||
"create-child-note": "Create child note",
|
||||
"unhoist": "Unhoist",
|
||||
"toggle-sidebar": "Toggle sidebar"
|
||||
"toggle-sidebar": "Toggle sidebar",
|
||||
"dropping-not-allowed": "Dropping notes into this location is not allowed."
|
||||
},
|
||||
"title_bar_buttons": {
|
||||
"window-on-top": "Keep Window on Top"
|
||||
@ -1830,7 +1831,8 @@
|
||||
"duplicate-launcher": "Duplicate launcher <kbd data-command=\"duplicateSubtree\">"
|
||||
},
|
||||
"editable-text": {
|
||||
"auto-detect-language": "Auto-detected"
|
||||
"auto-detect-language": "Auto-detected",
|
||||
"keeps-crashing": "Editing component keeps crashing. Please try restarting Trilium. If problem persists, consider creating a bug report."
|
||||
},
|
||||
"highlighting": {
|
||||
"title": "Code Blocks",
|
||||
@ -1895,7 +1897,10 @@
|
||||
},
|
||||
"note_autocomplete": {
|
||||
"search-for": "Search for \"{{term}}\"",
|
||||
"create-note": "Create and link child note \"{{term}}\"",
|
||||
"create-child-note": "Create child note \"{{term}}\"",
|
||||
"create-note": "Create note \"{{term}}\"",
|
||||
"create-and-link-child-note": "Create and link child note \"{{term}}\"",
|
||||
"create-and-link-note": "Create and link note \"{{term}}\"",
|
||||
"insert-external-link": "Insert external link to \"{{term}}\"",
|
||||
"clear-text-field": "Clear text field",
|
||||
"show-recent-notes": "Show recent notes",
|
||||
|
||||
@ -690,7 +690,8 @@
|
||||
"convert_into_attachment_failed": "La conversión de nota '{{title}}' falló.",
|
||||
"convert_into_attachment_successful": "La nota '{{title}}' ha sido convertida a un archivo adjunto.",
|
||||
"convert_into_attachment_prompt": "¿Está seguro que desea convertir la nota '{{title}}' en un archivo adjunto de la nota padre?",
|
||||
"print_pdf": "Exportar como PDF..."
|
||||
"print_pdf": "Exportar como PDF...",
|
||||
"open_note_on_server": "Abrir nota en el servidor"
|
||||
},
|
||||
"onclick_button": {
|
||||
"no_click_handler": "El widget de botón '{{componentId}}' no tiene un controlador de clics definido"
|
||||
@ -763,7 +764,6 @@
|
||||
"grid": "Cuadrícula",
|
||||
"list": "Lista",
|
||||
"collapse_all_notes": "Contraer todas las notas",
|
||||
"expand_all_children": "Ampliar todas las subnotas",
|
||||
"collapse": "Colapsar",
|
||||
"expand": "Expandir",
|
||||
"invalid_view_type": "Tipo de vista inválida '{{type}}'",
|
||||
@ -773,7 +773,11 @@
|
||||
"geo-map": "Mapa Geo",
|
||||
"board": "Tablero",
|
||||
"include_archived_notes": "Mostrar notas archivadas",
|
||||
"presentation": "Presentación"
|
||||
"presentation": "Presentación",
|
||||
"expand_tooltip": "Expande las notas hijas inmediatas de esta colección (un nivel). Para más opciones, pulsa la flecha a la derecha.",
|
||||
"expand_first_level": "Expandir hijos inmediatos",
|
||||
"expand_nth_level": "Expandir {{depth}} niveles",
|
||||
"expand_all_levels": "Expandir todos los niveles"
|
||||
},
|
||||
"edited_notes": {
|
||||
"no_edited_notes_found": "Aún no hay notas editadas en este día...",
|
||||
@ -1301,7 +1305,10 @@
|
||||
"title": "Editor"
|
||||
},
|
||||
"code_mime_types": {
|
||||
"title": "Tipos MIME disponibles en el menú desplegable"
|
||||
"title": "Tipos MIME disponibles en el menú desplegable",
|
||||
"tooltip_syntax_highlighting": "Resaltado de sintaxis",
|
||||
"tooltip_code_block_syntax": "Bloques de código en notas de texto",
|
||||
"tooltip_code_note_syntax": "Notas de código"
|
||||
},
|
||||
"vim_key_bindings": {
|
||||
"use_vim_keybindings_in_code_notes": "Atajos de teclas de Vim",
|
||||
@ -1851,7 +1858,8 @@
|
||||
"copy-link": "Copiar enlace",
|
||||
"paste": "Pegar",
|
||||
"paste-as-plain-text": "Pegar como texto plano",
|
||||
"search_online": "Buscar \"{{term}}\" con {{searchEngine}}"
|
||||
"search_online": "Buscar \"{{term}}\" con {{searchEngine}}",
|
||||
"search_in_trilium": "Buscar \"{{term}}\" en Trilium"
|
||||
},
|
||||
"image_context_menu": {
|
||||
"copy_reference_to_clipboard": "Copiar referencia al portapapeles",
|
||||
@ -1992,7 +2000,8 @@
|
||||
"add-column-placeholder": "Ingresar título de la columna...",
|
||||
"edit-note-title": "Haga clic para editar el título de la nota",
|
||||
"edit-column-title": "Haga clic para editar el título de la columna",
|
||||
"remove-from-board": "Eliminar del tablero"
|
||||
"remove-from-board": "Eliminar del tablero",
|
||||
"column-already-exists": "Esta columna ya existe en el tablero."
|
||||
},
|
||||
"content_renderer": {
|
||||
"open_externally": "Abrir externamente"
|
||||
@ -2092,5 +2101,10 @@
|
||||
},
|
||||
"calendar_view": {
|
||||
"delete_note": "Eliminar nota..."
|
||||
},
|
||||
"note-color": {
|
||||
"clear-color": "Borrar color de nota",
|
||||
"set-color": "Asignar color de nota",
|
||||
"set-custom-color": "Asignar color de nota personalizado"
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,7 +762,6 @@
|
||||
"grid": "Grille",
|
||||
"list": "Liste",
|
||||
"collapse_all_notes": "Réduire toutes les notes",
|
||||
"expand_all_children": "Développer tous les enfants",
|
||||
"collapse": "Réduire",
|
||||
"expand": "Développer",
|
||||
"invalid_view_type": "Type de vue non valide '{{type}}'",
|
||||
|
||||
@ -1337,7 +1337,6 @@
|
||||
"grid": "Griglia",
|
||||
"list": "Lista",
|
||||
"collapse_all_notes": "Comprimi tutte le note",
|
||||
"expand_all_children": "Espandi tutti i bambini",
|
||||
"collapse": "Crollo",
|
||||
"expand": "Espandere",
|
||||
"book_properties": "Proprietà della raccolta",
|
||||
|
||||
@ -531,7 +531,6 @@
|
||||
"grid": "グリッド",
|
||||
"list": "リスト",
|
||||
"collapse_all_notes": "すべてのノートを折りたたむ",
|
||||
"expand_all_children": "すべての子を展開",
|
||||
"collapse": "折りたたむ",
|
||||
"expand": "展開",
|
||||
"book_properties": "コレクションプロパティ",
|
||||
@ -542,7 +541,11 @@
|
||||
"geo-map": "ジオマップ",
|
||||
"board": "ボード",
|
||||
"include_archived_notes": "アーカイブされたノートを表示",
|
||||
"presentation": "プレゼンテーション"
|
||||
"presentation": "プレゼンテーション",
|
||||
"expand_tooltip": "このコレクションの直下の子(1階層下)を展開します。その他のオプションについては、右側の矢印を押してください。",
|
||||
"expand_first_level": "直下の子を展開",
|
||||
"expand_nth_level": "{{depth}} 階層下まで展開",
|
||||
"expand_all_levels": "すべての階層を展開"
|
||||
},
|
||||
"note_types": {
|
||||
"geo-map": "ジオマップ",
|
||||
@ -1301,7 +1304,8 @@
|
||||
"copy-link": "リンクをコピー",
|
||||
"paste": "貼り付け",
|
||||
"paste-as-plain-text": "プレーンテキストで貼り付け",
|
||||
"search_online": "{{searchEngine}} で \"{{term}}\" を検索"
|
||||
"search_online": "{{searchEngine}} で \"{{term}}\" を検索",
|
||||
"search_in_trilium": "Triliumで「{{term}}」を検索"
|
||||
},
|
||||
"duration": {
|
||||
"seconds": "秒",
|
||||
|
||||
@ -165,7 +165,6 @@
|
||||
"view_type": "Typ widoku",
|
||||
"grid": "Siatka",
|
||||
"collapse_all_notes": "Zwiń wszystkie notatki",
|
||||
"expand_all_children": "Rozwiń wszystkie dzieci",
|
||||
"collapse": "Zwiń",
|
||||
"expand": "Rozwiń",
|
||||
"book_properties": "Właściwości kolekcji",
|
||||
|
||||
@ -739,7 +739,6 @@
|
||||
"grid": "Grade",
|
||||
"list": "Lista",
|
||||
"collapse_all_notes": "Recolher todas as notas",
|
||||
"expand_all_children": "Expandir todos os filhos",
|
||||
"collapse": "Recolher",
|
||||
"expand": "Expandir",
|
||||
"book_properties": "Propriedades da Coleção",
|
||||
|
||||
@ -1004,7 +1004,6 @@
|
||||
"grid": "Grade",
|
||||
"list": "Lista",
|
||||
"collapse_all_notes": "Recolher todas as notas",
|
||||
"expand_all_children": "Expandir todos os filhos",
|
||||
"collapse": "Recolher",
|
||||
"expand": "Expandir",
|
||||
"book_properties": "Propriedades da Coleção",
|
||||
|
||||
@ -279,7 +279,6 @@
|
||||
"collapse": "Minimizează",
|
||||
"collapse_all_notes": "Minimizează toate notițele",
|
||||
"expand": "Expandează",
|
||||
"expand_all_children": "Expandează toate subnotițele",
|
||||
"grid": "Grilă",
|
||||
"invalid_view_type": "Mod de afișare incorect „{{type}}”",
|
||||
"list": "Listă",
|
||||
@ -290,7 +289,11 @@
|
||||
"geo-map": "Hartă geografică",
|
||||
"board": "Tablă Kanban",
|
||||
"include_archived_notes": "Afișează notițele arhivate",
|
||||
"presentation": "Prezentare"
|
||||
"presentation": "Prezentare",
|
||||
"expand_tooltip": "Expandează subnotițele directe ale acestei colecții (un singur nivel de adâncime). Pentru mai multe opțiuni, apăsați săgeata din dreapta.",
|
||||
"expand_first_level": "Expandează subnotițele directe",
|
||||
"expand_nth_level": "Expandează pe {{depth}} nivele",
|
||||
"expand_all_levels": "Expandează pe toate nivelele"
|
||||
},
|
||||
"bookmark_switch": {
|
||||
"bookmark": "Semn de carte",
|
||||
@ -384,7 +387,10 @@
|
||||
"trilium_api_docs_button_title": "Deschide documentația API pentru Trilium"
|
||||
},
|
||||
"code_mime_types": {
|
||||
"title": "Tipuri MIME disponibile în meniul derulant"
|
||||
"title": "Tipuri MIME disponibile în meniul derulant",
|
||||
"tooltip_syntax_highlighting": "Evidențiere de sintaxă",
|
||||
"tooltip_code_block_syntax": "Blocuri de cod în notițe text",
|
||||
"tooltip_code_note_syntax": "Notițe de tip cod"
|
||||
},
|
||||
"confirm": {
|
||||
"also_delete_note": "Șterge și notița",
|
||||
@ -1659,7 +1665,8 @@
|
||||
"cut": "Decupează",
|
||||
"paste": "Lipește",
|
||||
"paste-as-plain-text": "Lipește doar textul",
|
||||
"search_online": "Caută „{{term}}” cu {{searchEngine}}"
|
||||
"search_online": "Caută „{{term}}” cu {{searchEngine}}",
|
||||
"search_in_trilium": "Caută „{{term}}” în Trilium"
|
||||
},
|
||||
"image_context_menu": {
|
||||
"copy_image_to_clipboard": "Copiază imaginea în clipboard",
|
||||
@ -2096,7 +2103,7 @@
|
||||
"calendar_view": {
|
||||
"delete_note": "Șterge notița..."
|
||||
},
|
||||
"note-color": {
|
||||
"note-color": {
|
||||
"clear-color": "Înlăturați culoarea notiței",
|
||||
"set-color": "Setați culoarea notiței",
|
||||
"set-custom-color": "Setați culoare personalizată pentru notiță"
|
||||
|
||||
@ -1013,7 +1013,6 @@
|
||||
"book_properties": "Свойства коллекции",
|
||||
"geo-map": "Карта",
|
||||
"invalid_view_type": "Недопустимый тип представления '{{type}}'",
|
||||
"expand_all_children": "Развернуть все дочерние элементы",
|
||||
"collapse_all_notes": "Свернуть все заметки",
|
||||
"include_archived_notes": "Показать заархивированные заметки"
|
||||
},
|
||||
|
||||
@ -761,7 +761,6 @@
|
||||
"grid": "網格",
|
||||
"list": "列表",
|
||||
"collapse_all_notes": "收摺所有筆記",
|
||||
"expand_all_children": "展開所有子項",
|
||||
"collapse": "收摺",
|
||||
"expand": "展開",
|
||||
"invalid_view_type": "無效的查看類型 '{{type}}'",
|
||||
@ -771,7 +770,11 @@
|
||||
"geo-map": "地理地圖",
|
||||
"board": "看板",
|
||||
"include_archived_notes": "顯示已封存筆記",
|
||||
"presentation": "簡報"
|
||||
"presentation": "簡報",
|
||||
"expand_tooltip": "展開此集合的直接子級(單層深度)。按下右側箭頭以查看更多選項。",
|
||||
"expand_first_level": "展開直接子級",
|
||||
"expand_nth_level": "展開 {{depth}} 層",
|
||||
"expand_all_levels": "展開所有層級"
|
||||
},
|
||||
"edited_notes": {
|
||||
"no_edited_notes_found": "今天還沒有編輯過的筆記...",
|
||||
@ -1148,7 +1151,10 @@
|
||||
"unit": "字元"
|
||||
},
|
||||
"code_mime_types": {
|
||||
"title": "下拉選單可用的 MIME 文件類型"
|
||||
"title": "下拉選單可用的 MIME 文件類型",
|
||||
"tooltip_syntax_highlighting": "語法高亮顯示",
|
||||
"tooltip_code_block_syntax": "文字筆記中的程式碼區塊",
|
||||
"tooltip_code_note_syntax": "程式碼筆記"
|
||||
},
|
||||
"vim_key_bindings": {
|
||||
"use_vim_keybindings_in_code_notes": "Vim 快捷鍵",
|
||||
@ -1654,7 +1660,8 @@
|
||||
"copy-link": "複製連結",
|
||||
"paste": "貼上",
|
||||
"paste-as-plain-text": "以純文字貼上",
|
||||
"search_online": "用 {{searchEngine}} 搜尋 \"{{term}}\""
|
||||
"search_online": "用 {{searchEngine}} 搜尋 \"{{term}}\"",
|
||||
"search_in_trilium": "在 Trilium 中搜尋「{{term}}」"
|
||||
},
|
||||
"image_context_menu": {
|
||||
"copy_reference_to_clipboard": "複製引用到剪貼簿",
|
||||
|
||||
@ -867,7 +867,6 @@
|
||||
"grid": "Сітка",
|
||||
"list": "Список",
|
||||
"collapse_all_notes": "Згорнути всі нотатки",
|
||||
"expand_all_children": "Розгорнути всі дочірні",
|
||||
"collapse": "Згорнути",
|
||||
"expand": "Розгорнути",
|
||||
"book_properties": "Властивості Колекції",
|
||||
|
||||
@ -3,7 +3,7 @@ import server from "../../services/server.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import linkService from "../../services/link.js";
|
||||
import attributeAutocompleteService from "../../services/attribute_autocomplete.js";
|
||||
import noteAutocompleteService from "../../services/note_autocomplete.js";
|
||||
import noteAutocompleteService, { SuggestionMode } from "../../services/note_autocomplete.js";
|
||||
import promotedAttributeDefinitionParser from "../../services/promoted_attribute_definition_parser.js";
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import SpacedUpdate from "../../services/spaced_update.js";
|
||||
@ -429,7 +429,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
|
||||
this.$rowTargetNote = this.$widget.find(".attr-row-target-note");
|
||||
this.$inputTargetNote = this.$widget.find(".attr-input-target-note");
|
||||
|
||||
noteAutocompleteService.initNoteAutocomplete(this.$inputTargetNote, { allowCreatingNotes: true }).on("autocomplete:noteselected", (event, suggestion, dataset) => {
|
||||
noteAutocompleteService.initNoteAutocomplete(this.$inputTargetNote, { suggestionMode: SuggestionMode.SuggestCreateAndLink }).on("autocomplete:noteselected", (event, suggestion, dataset) => {
|
||||
if (!suggestion.notePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import branches from "../../../services/branches";
|
||||
import { executeBulkActions } from "../../../services/bulk_action";
|
||||
import froca from "../../../services/froca";
|
||||
import { t } from "../../../services/i18n";
|
||||
import note_create from "../../../services/note_create";
|
||||
import note_create from "../../../services/note_create.js";
|
||||
import server from "../../../services/server";
|
||||
import { ColumnMap } from "./data";
|
||||
|
||||
@ -39,9 +39,11 @@ export default class BoardApi {
|
||||
const parentNotePath = this.parentNote.noteId;
|
||||
|
||||
// Create a new note as a child of the parent note
|
||||
const { note: newNote, branch: newBranch } = await note_create.createNote(parentNotePath, {
|
||||
const { note: newNote, branch: newBranch } = await note_create.createNote({
|
||||
target: "into",
|
||||
parentNoteLink: parentNotePath,
|
||||
activate: false,
|
||||
title
|
||||
title,
|
||||
});
|
||||
|
||||
if (newNote && newBranch) {
|
||||
@ -139,13 +141,17 @@ export default class BoardApi {
|
||||
async insertRowAtPosition(
|
||||
column: string,
|
||||
relativeToBranchId: string,
|
||||
direction: "before" | "after") {
|
||||
const { note, branch } = await note_create.createNote(this.parentNote.noteId, {
|
||||
activate: false,
|
||||
targetBranchId: relativeToBranchId,
|
||||
target: direction,
|
||||
title: t("board_view.new-item")
|
||||
});
|
||||
direction: "before" | "after"
|
||||
) {
|
||||
const { note, branch } = await note_create.createNote(
|
||||
{
|
||||
target: direction,
|
||||
parentNoteLink: this.parentNote.noteId,
|
||||
activate: false,
|
||||
targetBranchId: relativeToBranchId,
|
||||
title: t("board_view.new-item"),
|
||||
}
|
||||
);
|
||||
|
||||
if (!note || !branch) {
|
||||
throw new Error("Failed to create note");
|
||||
|
||||
@ -57,12 +57,18 @@ export function openNoteContextMenu(api: Api, event: ContextMenuEvent, note: FNo
|
||||
{
|
||||
title: t("board_view.insert-above"),
|
||||
uiIcon: "bx bx-list-plus",
|
||||
handler: () => api.insertRowAtPosition(column, branchId, "before")
|
||||
handler: () => api.insertRowAtPosition(
|
||||
column,
|
||||
branchId,
|
||||
"before")
|
||||
},
|
||||
{
|
||||
title: t("board_view.insert-below"),
|
||||
uiIcon: "bx bx-empty",
|
||||
handler: () => api.insertRowAtPosition(column, branchId, "after")
|
||||
handler: () => api.insertRowAtPosition(
|
||||
column,
|
||||
branchId,
|
||||
"after")
|
||||
},
|
||||
{ kind: "separator" },
|
||||
{
|
||||
|
||||
@ -15,6 +15,7 @@ import FormTextArea from "../../react/FormTextArea";
|
||||
import FNote from "../../../entities/fnote";
|
||||
import NoteAutocomplete from "../../react/NoteAutocomplete";
|
||||
import toast from "../../../services/toast";
|
||||
import { SuggestionMode } from "../../../services/note_autocomplete";
|
||||
|
||||
export interface BoardViewData {
|
||||
columns?: BoardColumnData[];
|
||||
@ -164,12 +165,12 @@ export default function BoardView({ note: parentNote, noteIds, viewConfig, saveC
|
||||
onWheel={onWheelHorizontalScroll}
|
||||
>
|
||||
<BoardViewContext.Provider value={boardViewContext}>
|
||||
<div
|
||||
{byColumn && columns && <div
|
||||
className="board-view-container"
|
||||
onDragOver={handleColumnDragOver}
|
||||
onDrop={handleContainerDrop}
|
||||
>
|
||||
{byColumn && columns?.map((column, index) => (
|
||||
{columns.map((column, index) => (
|
||||
<>
|
||||
{columnDropPosition === index && (
|
||||
<div className="column-drop-placeholder show" />
|
||||
@ -191,7 +192,7 @@ export default function BoardView({ note: parentNote, noteIds, viewConfig, saveC
|
||||
)}
|
||||
|
||||
<AddNewColumn api={api} isInRelationMode={isInRelationMode} />
|
||||
</div>
|
||||
</div>}
|
||||
</BoardViewContext.Provider>
|
||||
</div>
|
||||
)
|
||||
@ -298,7 +299,7 @@ export function TitleEditor({ currentValue, placeholder, save, dismiss, mode, is
|
||||
noteId={currentValue ?? ""}
|
||||
opts={{
|
||||
hideAllButtons: true,
|
||||
allowCreatingNotes: true
|
||||
suggestionMode: SuggestionMode.SuggestCreateAndLink
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Escape") {
|
||||
|
||||
@ -6,6 +6,7 @@ import Icon from "../../react/Icon.jsx";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import froca from "../../../services/froca.js";
|
||||
import NoteAutocomplete from "../../react/NoteAutocomplete.jsx";
|
||||
import { SuggestionMode } from "../../../services/note_autocomplete.js";
|
||||
|
||||
type ColumnType = LabelType | "relation";
|
||||
|
||||
@ -227,7 +228,7 @@ function RelationEditor({ cell, success }: EditorOpts) {
|
||||
inputRef={inputRef}
|
||||
noteId={cell.getValue()}
|
||||
opts={{
|
||||
allowCreatingNotes: true,
|
||||
suggestionMode: SuggestionMode.SuggestCreateAndLink,
|
||||
hideAllButtons: true
|
||||
}}
|
||||
noteIdChanged={success}
|
||||
|
||||
@ -181,8 +181,8 @@ export function showRowContextMenu(parentComponent: Component, e: MouseEvent, ro
|
||||
uiIcon: "bx bx-horizontal-left bx-rotate-90",
|
||||
enabled: !sorters.length,
|
||||
handler: () => parentComponent?.triggerCommand("addNewRow", {
|
||||
parentNotePath: parentNoteId,
|
||||
customOpts: {
|
||||
parentNoteLink: parentNoteId,
|
||||
target: "before",
|
||||
targetBranchId: rowData.branchId,
|
||||
}
|
||||
@ -194,9 +194,12 @@ export function showRowContextMenu(parentComponent: Component, e: MouseEvent, ro
|
||||
handler: async () => {
|
||||
const branchId = row.getData().branchId;
|
||||
const note = await froca.getBranch(branchId)?.getNote();
|
||||
if (!note) {
|
||||
return;
|
||||
}
|
||||
parentComponent?.triggerCommand("addNewRow", {
|
||||
parentNotePath: note?.noteId,
|
||||
customOpts: {
|
||||
parentNoteLink: note.noteId,
|
||||
target: "after",
|
||||
targetBranchId: branchId,
|
||||
}
|
||||
@ -208,8 +211,8 @@ export function showRowContextMenu(parentComponent: Component, e: MouseEvent, ro
|
||||
uiIcon: "bx bx-horizontal-left bx-rotate-270",
|
||||
enabled: !sorters.length,
|
||||
handler: () => parentComponent?.triggerCommand("addNewRow", {
|
||||
parentNotePath: parentNoteId,
|
||||
customOpts: {
|
||||
parentNoteLink: parentNoteId,
|
||||
target: "after",
|
||||
targetBranchId: rowData.branchId,
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { EventCallBackMethods, RowComponent, Tabulator } from "tabulator-tables";
|
||||
import { CommandListenerData } from "../../../components/app_context";
|
||||
import note_create, { CreateNoteOpts } from "../../../services/note_create";
|
||||
import note_create from "../../../services/note_create";
|
||||
import { useLegacyImperativeHandlers } from "../../react/hooks";
|
||||
import { RefObject } from "preact";
|
||||
import { setAttribute, setLabel } from "../../../services/attributes";
|
||||
@ -9,17 +9,23 @@ import server from "../../../services/server";
|
||||
import branches from "../../../services/branches";
|
||||
import AttributeDetailWidget from "../../attribute_widgets/attribute_detail";
|
||||
|
||||
/**
|
||||
* Hook for handling row table editing, including adding new rows.
|
||||
*/
|
||||
export default function useRowTableEditing(api: RefObject<Tabulator>, attributeDetailWidget: AttributeDetailWidget, parentNotePath: string): Partial<EventCallBackMethods> {
|
||||
// Adding new rows
|
||||
useLegacyImperativeHandlers({
|
||||
addNewRowCommand({ customOpts, parentNotePath: customNotePath }: CommandListenerData<"addNewRow">) {
|
||||
const notePath = customNotePath ?? parentNotePath;
|
||||
if (notePath) {
|
||||
const opts: CreateNoteOpts = {
|
||||
activate: false,
|
||||
...customOpts
|
||||
}
|
||||
note_create.createNote(notePath, opts).then(({ branch }) => {
|
||||
addNewRowCommand({ customOpts }: CommandListenerData<"addNewRow">) {
|
||||
if (!customOpts) {
|
||||
customOpts = {
|
||||
target: "into",
|
||||
};
|
||||
}
|
||||
|
||||
const noteUrl = customOpts.parentNoteLink ?? parentNotePath;
|
||||
if (noteUrl) {
|
||||
customOpts.parentNoteLink = noteUrl;
|
||||
customOpts.activate = false;
|
||||
note_create.createNote(customOpts).then(({ branch }) => {
|
||||
if (branch) {
|
||||
setTimeout(() => {
|
||||
if (!api.current) return;
|
||||
@ -27,6 +33,7 @@ export default function useRowTableEditing(api: RefObject<Tabulator>, attributeD
|
||||
}, 100);
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -5,7 +5,7 @@ import FormRadioGroup from "../react/FormRadioGroup";
|
||||
import NoteAutocomplete from "../react/NoteAutocomplete";
|
||||
import { useRef, useState, useEffect } from "preact/hooks";
|
||||
import tree from "../../services/tree";
|
||||
import note_autocomplete, { Suggestion } from "../../services/note_autocomplete";
|
||||
import note_autocomplete, { SuggestionMode, Suggestion } from "../../services/note_autocomplete";
|
||||
import { logError } from "../../services/ws";
|
||||
import FormGroup from "../react/FormGroup.js";
|
||||
import { refToJQuerySelector } from "../react/react_utils";
|
||||
@ -58,7 +58,7 @@ export default function AddLinkDialog() {
|
||||
}
|
||||
|
||||
if (suggestion.notePath) {
|
||||
const noteId = tree.getNoteIdFromUrl(suggestion.notePath);
|
||||
const noteId = tree.getNoteIdFromLink(suggestion.notePath);
|
||||
if (noteId) {
|
||||
setDefaultLinkTitle(noteId);
|
||||
}
|
||||
@ -133,7 +133,7 @@ export default function AddLinkDialog() {
|
||||
onChange={setSuggestion}
|
||||
opts={{
|
||||
allowExternalLinks: true,
|
||||
allowCreatingNotes: true
|
||||
suggestionMode: SuggestionMode.SuggestCreateAndLink,
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@ -5,7 +5,7 @@ import FormRadioGroup from "../react/FormRadioGroup";
|
||||
import Modal from "../react/Modal";
|
||||
import NoteAutocomplete from "../react/NoteAutocomplete";
|
||||
import Button from "../react/Button";
|
||||
import { Suggestion, triggerRecentNotes } from "../../services/note_autocomplete";
|
||||
import { SuggestionMode, Suggestion, triggerRecentNotes } from "../../services/note_autocomplete.js";
|
||||
import tree from "../../services/tree";
|
||||
import froca from "../../services/froca";
|
||||
import { useTriliumEvent } from "../react/hooks";
|
||||
@ -50,7 +50,7 @@ export default function IncludeNoteDialog() {
|
||||
inputRef={autoCompleteRef}
|
||||
opts={{
|
||||
hideGoToSelectedNoteButton: true,
|
||||
allowCreatingNotes: true
|
||||
suggestionMode: SuggestionMode.SuggestCreateOnly,
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
@ -71,7 +71,7 @@ export default function IncludeNoteDialog() {
|
||||
}
|
||||
|
||||
async function includeNote(notePath: string, editorApi: CKEditorApi, boxSize: BoxSize) {
|
||||
const noteId = tree.getNoteIdFromUrl(notePath);
|
||||
const noteId = tree.getNoteIdFromLink(notePath);
|
||||
if (!noteId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import Button from "../react/Button";
|
||||
import NoteAutocomplete from "../react/NoteAutocomplete";
|
||||
import { t } from "../../services/i18n";
|
||||
import { useRef, useState } from "preact/hooks";
|
||||
import note_autocomplete, { Suggestion } from "../../services/note_autocomplete";
|
||||
import note_autocomplete, { SuggestionMode, Suggestion } from "../../services/note_autocomplete.js";
|
||||
import appContext from "../../components/app_context";
|
||||
import commandRegistry from "../../services/command_registry";
|
||||
import { refToJQuerySelector } from "../react/react_utils";
|
||||
@ -12,34 +12,53 @@ import shortcutService from "../../services/shortcuts";
|
||||
|
||||
const KEEP_LAST_SEARCH_FOR_X_SECONDS = 120;
|
||||
|
||||
type Mode = "last-search" | "recent-notes" | "commands";
|
||||
enum Mode {
|
||||
LastSearch,
|
||||
RecentNotes,
|
||||
Commands,
|
||||
}
|
||||
|
||||
export default function JumpToNoteDialogComponent() {
|
||||
const [ mode, setMode ] = useState<Mode>();
|
||||
const [ lastOpenedTs, setLastOpenedTs ] = useState<number>(0);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const autocompleteRef = useRef<HTMLInputElement>(null);
|
||||
const [ isCommandMode, setIsCommandMode ] = useState(mode === "commands");
|
||||
const [ isCommandMode, setIsCommandMode ] = useState(mode === Mode.Commands);
|
||||
const [ initialText, setInitialText ] = useState(isCommandMode ? "> " : "");
|
||||
const actualText = useRef<string>(initialText);
|
||||
const [ shown, setShown ] = useState(false);
|
||||
|
||||
async function openDialog(commandMode: boolean) {
|
||||
|
||||
async function openDialog(requestedMode: Mode) {
|
||||
let newMode: Mode;
|
||||
let initialText = "";
|
||||
|
||||
if (commandMode) {
|
||||
newMode = "commands";
|
||||
initialText = ">";
|
||||
} else if (Date.now() - lastOpenedTs <= KEEP_LAST_SEARCH_FOR_X_SECONDS * 1000 && actualText.current) {
|
||||
// if you open the Jump To dialog soon after using it previously, it can often mean that you
|
||||
// actually want to search for the same thing (e.g., you opened the wrong note at first try)
|
||||
// so we'll keep the content.
|
||||
// if it's outside of this time limit, then we assume it's a completely new search and show recent notes instead.
|
||||
newMode = "last-search";
|
||||
initialText = actualText.current;
|
||||
} else {
|
||||
newMode = "recent-notes";
|
||||
switch (requestedMode) {
|
||||
case Mode.Commands:
|
||||
newMode = Mode.Commands;
|
||||
initialText = ">";
|
||||
break;
|
||||
|
||||
case Mode.LastSearch:
|
||||
// if you open the Jump To dialog soon after using it previously, it can often mean that you
|
||||
// actually want to search for the same thing (e.g., you opened the wrong note at first try)
|
||||
// so we'll keep the content.
|
||||
// if it's outside of this time limit, then we assume it's a completely new search and show recent notes instead.
|
||||
if (Date.now() - lastOpenedTs <= KEEP_LAST_SEARCH_FOR_X_SECONDS * 1000 && actualText.current) {
|
||||
newMode = Mode.LastSearch;
|
||||
initialText = actualText.current;
|
||||
} else {
|
||||
newMode = Mode.RecentNotes;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Date.now() - lastOpenedTs <= KEEP_LAST_SEARCH_FOR_X_SECONDS * 1000 && actualText.current) {
|
||||
newMode = Mode.LastSearch;
|
||||
initialText = actualText.current;
|
||||
} else {
|
||||
newMode = Mode.RecentNotes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode !== newMode) {
|
||||
@ -51,14 +70,14 @@ export default function JumpToNoteDialogComponent() {
|
||||
setLastOpenedTs(Date.now());
|
||||
}
|
||||
|
||||
useTriliumEvent("jumpToNote", () => openDialog(false));
|
||||
useTriliumEvent("commandPalette", () => openDialog(true));
|
||||
useTriliumEvent("jumpToNote", () => openDialog(Mode.RecentNotes));
|
||||
useTriliumEvent("commandPalette", () => openDialog(Mode.Commands));
|
||||
|
||||
async function onItemSelected(suggestion?: Suggestion | null) {
|
||||
if (!suggestion) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setShown(false);
|
||||
if (suggestion.notePath) {
|
||||
appContext.tabManager.getActiveContext()?.setNote(suggestion.notePath);
|
||||
@ -70,12 +89,12 @@ export default function JumpToNoteDialogComponent() {
|
||||
function onShown() {
|
||||
const $autoComplete = refToJQuerySelector(autocompleteRef);
|
||||
switch (mode) {
|
||||
case "last-search":
|
||||
case Mode.LastSearch:
|
||||
break;
|
||||
case "recent-notes":
|
||||
case Mode.RecentNotes:
|
||||
note_autocomplete.showRecentNotes($autoComplete);
|
||||
break;
|
||||
case "commands":
|
||||
case Mode.Commands:
|
||||
note_autocomplete.showAllCommands($autoComplete);
|
||||
break;
|
||||
}
|
||||
@ -83,7 +102,7 @@ export default function JumpToNoteDialogComponent() {
|
||||
$autoComplete
|
||||
.trigger("focus")
|
||||
.trigger("select");
|
||||
|
||||
|
||||
// Add keyboard shortcut for full search
|
||||
shortcutService.bindElShortcut($autoComplete, "ctrl+return", () => {
|
||||
if (!isCommandMode) {
|
||||
@ -91,7 +110,7 @@ export default function JumpToNoteDialogComponent() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function showInFullSearch() {
|
||||
try {
|
||||
setShown(false);
|
||||
@ -116,7 +135,7 @@ export default function JumpToNoteDialogComponent() {
|
||||
container={containerRef}
|
||||
text={initialText}
|
||||
opts={{
|
||||
allowCreatingNotes: true,
|
||||
suggestionMode: SuggestionMode.SuggestCreateOnly,
|
||||
hideGoToSelectedNoteButton: true,
|
||||
allowJumpToSearchNotes: true,
|
||||
isCommandPalette: true
|
||||
@ -129,9 +148,9 @@ export default function JumpToNoteDialogComponent() {
|
||||
/>}
|
||||
onShown={onShown}
|
||||
onHidden={() => setShown(false)}
|
||||
footer={!isCommandMode && <Button
|
||||
className="show-in-full-text-button"
|
||||
text={t("jump_to_note.search_button")}
|
||||
footer={!isCommandMode && <Button
|
||||
className="show-in-full-text-button"
|
||||
text={t("jump_to_note.search_button")}
|
||||
keyboardShortcut="Ctrl+Enter"
|
||||
onClick={showInFullSearch}
|
||||
/>}
|
||||
|
||||
@ -7,7 +7,7 @@ import { useEffect, useState } from "preact/hooks";
|
||||
import note_types from "../../services/note_types";
|
||||
import { MenuCommandItem, MenuItem } from "../../menus/context_menu";
|
||||
import { TreeCommandNames } from "../../menus/tree_context_menu";
|
||||
import { Suggestion } from "../../services/note_autocomplete";
|
||||
import { SuggestionMode, Suggestion } from "../../services/note_autocomplete.js";
|
||||
import Badge from "../react/Badge";
|
||||
import { useTriliumEvent } from "../react/hooks";
|
||||
|
||||
@ -76,6 +76,7 @@ export default function NoteTypeChooserDialogComponent() {
|
||||
onHidden={() => {
|
||||
callback?.({ success: false });
|
||||
setShown(false);
|
||||
setParentNote(null);
|
||||
}}
|
||||
show={shown}
|
||||
stackable
|
||||
@ -85,7 +86,7 @@ export default function NoteTypeChooserDialogComponent() {
|
||||
onChange={setParentNote}
|
||||
placeholder={t("note_type_chooser.search_placeholder")}
|
||||
opts={{
|
||||
allowCreatingNotes: false,
|
||||
suggestionMode: SuggestionMode.SuggestNothing,
|
||||
hideGoToSelectedNoteButton: true,
|
||||
allowJumpToSearchNotes: false,
|
||||
}}
|
||||
|
||||
@ -5,7 +5,7 @@ import BasicWidget from "../basic_widget.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import server from "../../services/server.js";
|
||||
import noteAutocompleteService from "../../services/note_autocomplete.js";
|
||||
import noteAutocompleteService, { SuggestionMode } from "../../services/note_autocomplete.js";
|
||||
|
||||
import { TPL, addMessageToChat, showSources, hideSources, showLoadingIndicator, hideLoadingIndicator } from "./ui.js";
|
||||
import { formatMarkdown } from "./utils.js";
|
||||
@ -163,7 +163,7 @@ export default class LlmChatPanel extends BasicWidget {
|
||||
const mentionSetup: MentionFeed[] = [
|
||||
{
|
||||
marker: "@",
|
||||
feed: (queryText: string) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
|
||||
feed: (queryText: string) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText, SuggestionMode.SuggestCreateAndLink),
|
||||
itemRenderer: (item) => {
|
||||
const suggestion = item as Suggestion;
|
||||
const itemElement = document.createElement("button");
|
||||
|
||||
@ -29,7 +29,14 @@ export default function MobileDetailMenu() {
|
||||
],
|
||||
selectMenuItemHandler: async ({ command }) => {
|
||||
if (command === "insertChildNote") {
|
||||
note_create.createNote(appContext.tabManager.getActiveContextNotePath() ?? undefined);
|
||||
const parentNoteUrl = appContext.tabManager.getActiveContextNotePath();
|
||||
|
||||
if (parentNoteUrl) {
|
||||
note_create.createNote({
|
||||
target: "into",
|
||||
parentNoteLink: parentNoteUrl,
|
||||
});
|
||||
}
|
||||
} else if (command === "delete") {
|
||||
const notePath = appContext.tabManager.getActiveContextNotePath();
|
||||
if (!notePath) {
|
||||
|
||||
@ -224,7 +224,13 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
} else if (target.classList.contains("add-note-button")) {
|
||||
const node = $.ui.fancytree.getNode(e as unknown as Event);
|
||||
const parentNotePath = treeService.getNotePath(node);
|
||||
noteCreateService.createNote(parentNotePath, { isProtected: node.data.isProtected });
|
||||
noteCreateService.createNote(
|
||||
{
|
||||
target: "into",
|
||||
parentNoteLink: parentNotePath,
|
||||
isProtected: node.data.isProtected
|
||||
},
|
||||
);
|
||||
} else if (target.classList.contains("enter-workspace-button")) {
|
||||
const node = $.ui.fancytree.getNode(e as unknown as Event);
|
||||
this.triggerCommand("hoistNote", { noteId: node.data.noteId });
|
||||
@ -508,7 +514,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
(data.hitMode === "over" && node.data.noteType === "search") ||
|
||||
(["after", "before"].includes(data.hitMode) && (node.data.noteId === hoistedNoteService.getHoistedNoteId() || node.getParent().data.noteType === "search"))
|
||||
) {
|
||||
await dialogService.info("Dropping notes into this location is not allowed.");
|
||||
await dialogService.info(t("note_tree.dropping-not-allowed"));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1403,10 +1409,10 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
|
||||
let node: Fancytree.FancytreeNode | null | undefined = await this.expandToNote(activeNotePath, false);
|
||||
|
||||
if (node && node.data.noteId !== treeService.getNoteIdFromUrl(activeNotePath)) {
|
||||
if (node && node.data.noteId !== treeService.getNoteIdFromLink(activeNotePath)) {
|
||||
// if the active note has been moved elsewhere then it won't be found by the path,
|
||||
// so we switch to the alternative of trying to find it by noteId
|
||||
const noteId = treeService.getNoteIdFromUrl(activeNotePath);
|
||||
const noteId = treeService.getNoteIdFromLink(activeNotePath);
|
||||
|
||||
if (noteId) {
|
||||
const notesById = this.getNodesByNoteId(noteId);
|
||||
@ -1836,9 +1842,13 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
const node = this.getActiveNode();
|
||||
if (!node) return;
|
||||
const notePath = treeService.getNotePath(node);
|
||||
noteCreateService.createNote(notePath, {
|
||||
isProtected: node.data.isProtected
|
||||
});
|
||||
noteCreateService.createNote(
|
||||
{
|
||||
target: "into",
|
||||
parentNoteLink: notePath,
|
||||
isProtected: node.data.isProtected
|
||||
}
|
||||
)
|
||||
}
|
||||
}),
|
||||
new TouchBar.TouchBarButton({
|
||||
|
||||
@ -2,7 +2,7 @@ import { MutableRef, useEffect, useImperativeHandle, useMemo, useRef, useState }
|
||||
import { AttributeEditor as CKEditorAttributeEditor, MentionFeed, ModelElement, ModelNode, ModelPosition } from "@triliumnext/ckeditor5";
|
||||
import { t } from "../../../services/i18n";
|
||||
import server from "../../../services/server";
|
||||
import note_autocomplete, { Suggestion } from "../../../services/note_autocomplete";
|
||||
import note_autocomplete, { SuggestionMode, Suggestion } from "../../../services/note_autocomplete.js";
|
||||
import CKEditor, { CKEditorApi } from "../../react/CKEditor";
|
||||
import { useLegacyImperativeHandlers, useLegacyWidget, useTooltip, useTriliumEvent, useTriliumOption } from "../../react/hooks";
|
||||
import FAttribute from "../../../entities/fattribute";
|
||||
@ -20,6 +20,7 @@ import type { CommandData, FilteredCommandNames } from "../../../components/app_
|
||||
import { AttributeType } from "@triliumnext/commons";
|
||||
import attributes from "../../../services/attributes";
|
||||
import note_create from "../../../services/note_create";
|
||||
import { CreateNoteAction } from "@triliumnext/commons";
|
||||
|
||||
type AttributeCommandNames = FilteredCommandNames<CommandData>;
|
||||
|
||||
@ -33,7 +34,7 @@ const HELP_TEXT = `
|
||||
const mentionSetup: MentionFeed[] = [
|
||||
{
|
||||
marker: "@",
|
||||
feed: (queryText) => note_autocomplete.autocompleteSourceForCKEditor(queryText),
|
||||
feed: (queryText) => note_autocomplete.autocompleteSourceForCKEditor(queryText, SuggestionMode.SuggestCreateAndLink),
|
||||
itemRenderer: (_item) => {
|
||||
const item = _item as Suggestion;
|
||||
const itemElement = document.createElement("button");
|
||||
@ -247,16 +248,18 @@ export default function AttributeEditor({ api, note, componentId, notePath, ntxI
|
||||
|
||||
$el.text(title);
|
||||
},
|
||||
createNoteForReferenceLink: async (title: string) => {
|
||||
let result;
|
||||
if (notePath) {
|
||||
result = await note_create.createNoteWithTypePrompt(notePath, {
|
||||
activate: false,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
return result?.note?.getBestNotePathString();
|
||||
createNoteFromCkEditor: async (
|
||||
title: string,
|
||||
parentNotePath: string | undefined,
|
||||
action: CreateNoteAction
|
||||
): Promise<string> => {
|
||||
const { note } = await note_create.createNoteFromAction(
|
||||
action,
|
||||
true,
|
||||
title,
|
||||
parentNotePath,
|
||||
);
|
||||
return note?.getBestNotePathString() ?? "";
|
||||
}
|
||||
}), [ notePath ]));
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import FormGroup from "../react/FormGroup";
|
||||
import NoteAutocomplete from "../react/NoteAutocomplete";
|
||||
import "./Empty.css";
|
||||
import { ParentComponent, refToJQuerySelector } from "../react/react_utils";
|
||||
import note_autocomplete from "../../services/note_autocomplete";
|
||||
import note_autocomplete, { SuggestionMode } from "../../services/note_autocomplete";
|
||||
import appContext from "../../components/app_context";
|
||||
import FNote from "../../entities/fnote";
|
||||
import search from "../../services/search";
|
||||
@ -38,7 +38,7 @@ function NoteSearch() {
|
||||
inputRef={autocompleteRef}
|
||||
opts={{
|
||||
hideGoToSelectedNoteButton: true,
|
||||
allowCreatingNotes: true,
|
||||
suggestionMode: SuggestionMode.SuggestCreateOnly,
|
||||
allowJumpToSearchNotes: true,
|
||||
}}
|
||||
onChange={suggestion => {
|
||||
|
||||
@ -16,7 +16,8 @@ import note_create from "../../../services/note_create";
|
||||
import TouchBar, { TouchBarButton, TouchBarGroup, TouchBarSegmentedControl } from "../../react/TouchBar";
|
||||
import { RefObject } from "preact";
|
||||
import { buildSelectedBackgroundColor } from "../../../components/touch_bar";
|
||||
import { deferred } from "@triliumnext/commons";
|
||||
import { CreateNoteAction, deferred } from "@triliumnext/commons";
|
||||
import { t } from "../../../services/i18n";
|
||||
|
||||
/**
|
||||
* The editor can operate into two distinct modes:
|
||||
@ -106,17 +107,18 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
},
|
||||
loadIncludedNote,
|
||||
// Creating notes in @-completion
|
||||
async createNoteForReferenceLink(title: string) {
|
||||
const notePath = noteContext?.notePath;
|
||||
if (!notePath) return;
|
||||
|
||||
const resp = await note_create.createNoteWithTypePrompt(notePath, {
|
||||
activate: false,
|
||||
title: title
|
||||
});
|
||||
|
||||
if (!resp || !resp.note) return;
|
||||
return resp.note.getBestNotePathString();
|
||||
async createNoteFromCkEditor (
|
||||
title: string,
|
||||
parentNotePath: string | undefined,
|
||||
action: CreateNoteAction
|
||||
): Promise<string> {
|
||||
const { note }= await note_create.createNoteFromAction(
|
||||
action,
|
||||
true,
|
||||
title,
|
||||
parentNotePath,
|
||||
)
|
||||
return note?.getBestNotePathString() ?? "";
|
||||
},
|
||||
// Keyboard shortcut
|
||||
async followLinkUnderCursorCommand() {
|
||||
@ -153,7 +155,9 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
// without await as this otherwise causes deadlock through component mutex
|
||||
const parentNotePath = appContext.tabManager.getActiveContextNotePath();
|
||||
if (noteContext && parentNotePath) {
|
||||
note_create.createNote(parentNotePath, {
|
||||
note_create.createNote({
|
||||
parentNoteLink: parentNotePath,
|
||||
target: "into",
|
||||
isProtected: note.isProtected,
|
||||
saveSelection: true,
|
||||
textEditor: await noteContext?.getTextEditor()
|
||||
@ -279,7 +283,7 @@ function onWatchdogStateChange(watchdog: EditorWatchdog) {
|
||||
logError(`CKEditor crash logs: ${JSON.stringify(watchdog.crashes, null, 4)}`);
|
||||
|
||||
if (currentState === "crashedPermanently") {
|
||||
dialog.info(`Editing component keeps crashing. Please try restarting Trilium. If problem persists, consider creating a bug report.`);
|
||||
dialog.info(t("editable-text.keeps-crashing"));
|
||||
watchdog.editor?.enableReadOnlyMode("crashed-editor");
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import emojiDefinitionsUrl from "@triliumnext/ckeditor5/src/emoji_definitions/en
|
||||
import { copyTextWithToast } from "../../../services/clipboard_ext.js";
|
||||
import { t } from "../../../services/i18n.js";
|
||||
import { getMermaidConfig } from "../../../services/mermaid.js";
|
||||
import noteAutocompleteService, { type Suggestion } from "../../../services/note_autocomplete.js";
|
||||
import noteAutocompleteService, { SuggestionMode, type Suggestion } from "../../../services/note_autocomplete.js";
|
||||
import mimeTypesService from "../../../services/mime_types.js";
|
||||
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
|
||||
import { buildToolbarConfig } from "./toolbar.js";
|
||||
@ -181,7 +181,7 @@ export async function buildConfig(opts: BuildEditorOptions): Promise<EditorConfi
|
||||
feeds: [
|
||||
{
|
||||
marker: "@",
|
||||
feed: (queryText: string) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
|
||||
feed: (queryText: string) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText, SuggestionMode.SuggestCreateAndLink),
|
||||
itemRenderer: (item) => {
|
||||
const itemElement = document.createElement("button");
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
"@triliumnext/commons": "workspace:*",
|
||||
"@triliumnext/server": "workspace:*",
|
||||
"copy-webpack-plugin": "13.0.1",
|
||||
"electron": "38.7.1",
|
||||
"electron": "38.7.2",
|
||||
"@electron-forge/cli": "7.10.2",
|
||||
"@electron-forge/maker-deb": "7.10.2",
|
||||
"@electron-forge/maker-dmg": "7.10.2",
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
"@triliumnext/desktop": "workspace:*",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"copy-webpack-plugin": "13.0.1",
|
||||
"electron": "38.7.1",
|
||||
"electron": "38.7.2",
|
||||
"fs-extra": "11.3.2"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@ -8,6 +8,7 @@ interface GotoOpts {
|
||||
}
|
||||
|
||||
const BASE_URL = "http://127.0.0.1:8082";
|
||||
const NUM_OF_CREATE_NOTE_OPTIONS = 2;
|
||||
|
||||
interface DropdownLocator extends Locator {
|
||||
selectOptionByText: (text: string) => Promise<void>;
|
||||
@ -73,7 +74,8 @@ export default class App {
|
||||
const resultsSelector = this.currentNoteSplit.locator(".note-detail-empty-results");
|
||||
await expect(resultsSelector).toContainText(noteTitle);
|
||||
await resultsSelector.locator(".aa-suggestion", { hasText: noteTitle })
|
||||
.nth(1) // Select the second one, as the first one is "Create a new note"
|
||||
// Select the n+1 one, as the first one is "Create a new note"
|
||||
.nth(NUM_OF_CREATE_NOTE_OPTIONS)
|
||||
.click();
|
||||
}
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
"debounce": "3.0.0",
|
||||
"debug": "4.4.3",
|
||||
"ejs": "3.1.10",
|
||||
"electron": "38.7.1",
|
||||
"electron": "38.7.2",
|
||||
"electron-debug": "4.1.0",
|
||||
"electron-window-state": "5.0.3",
|
||||
"escape-html": "1.0.3",
|
||||
|
||||
@ -5,69 +5,50 @@
|
||||
Keyboard shortcuts. Using <code>global:</code> prefix, you can assign a shortcut
|
||||
which will work even without Trilium being in focus (requires app restart
|
||||
to take effect).</p>
|
||||
<h2>Tree</h2>
|
||||
<p>See the corresponding section: <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/oPVyFC7WL2Lp/_help_DvdZhoQZY9Yd">Keyboard shortcuts</a>
|
||||
</p>
|
||||
<h2>Note navigation</h2>
|
||||
<ul>
|
||||
<li><kbd><span>↑</span></kbd>, <kbd><span>↓</span></kbd> - go up/down in the
|
||||
list of notes, <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd><span>↑</span></kbd> and <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd><span>↓</span></kbd> work
|
||||
also from editor</li>
|
||||
<li><kbd><span>←</span></kbd>, <kbd><span>→</span></kbd> - collapse/expand node</li>
|
||||
<li><kbd>Alt</kbd> + <kbd><span>←</span></kbd>, <kbd>Alt</kbd> + <kbd><span>→</span></kbd> -
|
||||
<li data-list-item-id="ed8fd9c2ab08ae80ea76c1ae5dc943e90"><kbd>Alt</kbd> + <kbd><span>←</span></kbd>, <kbd>Alt</kbd> + <kbd><span>→</span></kbd> –
|
||||
go back / forwards in the history</li>
|
||||
<li><kbd>Ctrl</kbd> + <kbd>J</kbd> - show <a href="#root/_help_MMiBEQljMQh2">"Jump to" dialog</a>
|
||||
<li data-list-item-id="eff3c5760b3d985e7808f1524982fcb9b"><kbd>Ctrl</kbd> + <kbd>J</kbd> – show <a href="#root/_help_MMiBEQljMQh2">"Jump to" dialog</a>
|
||||
</li>
|
||||
<li><kbd>Ctrl</kbd> + <kbd>.</kbd> - scroll to current note (useful when you
|
||||
<li data-list-item-id="e1fdee08a424868922b0579e78584279c"><kbd>Ctrl</kbd> + <kbd>.</kbd> – scroll to current note (useful when you
|
||||
scroll away from your note or your focus is currently in the editor)</li>
|
||||
<li><kbd><span>Backspace</span></kbd> - jumps to parent note</li>
|
||||
<li><kbd>Alt</kbd> + <kbd>C</kbd> - collapse whole note tree</li>
|
||||
<li><kbd>Alt</kbd> + <kbd>-</kbd> (alt with minus sign) - collapse subtree (if
|
||||
some subtree takes too much space on tree pane you can collapse it)</li>
|
||||
<li>you can define a <a href="#root/_help_zEY4DaJG4YT5">label</a> <code>#keyboardShortcut</code> with
|
||||
e.g. value <kbd>Ctrl</kbd> + <kbd>I</kbd> . Pressing this keyboard combination
|
||||
will then bring you to the note on which it is defined. Note that Trilium
|
||||
must be reloaded/restarted (<kbd>Ctrl</kbd> + <kbd>R</kbd> ) for changes to
|
||||
be in effect.</li>
|
||||
<li
|
||||
data-list-item-id="e9bbc51f19a729c10997010a915779d07"><kbd><span>Backspace</span></kbd> – jumps to parent note</li>
|
||||
<li data-list-item-id="eaaa0f36b2e561d4a24358552e633d924"><kbd>Alt</kbd> + <kbd>C</kbd> – collapse whole note tree</li>
|
||||
<li data-list-item-id="ee625a141f5298dbd52ecb6e56693e647"><kbd>Alt</kbd> + <kbd>-</kbd> (alt with minus sign) – collapse subtree (if
|
||||
some subtree takes too much space on tree pane you can collapse it)</li>
|
||||
<li
|
||||
data-list-item-id="ec1bf00840a017ea798880470e419f3d9">you can define a <a href="#root/_help_zEY4DaJG4YT5">label</a> <code>#keyboardShortcut</code> with
|
||||
e.g. value <kbd>Ctrl</kbd> + <kbd>I</kbd> . Pressing this keyboard combination
|
||||
will then bring you to the note on which it is defined. Note that Trilium
|
||||
must be reloaded/restarted (<kbd>Ctrl</kbd> + <kbd>R</kbd> ) for changes to
|
||||
be in effect.</li>
|
||||
</ul>
|
||||
<p>See demo of some of these features in <a href="#root/_help_MMiBEQljMQh2">note navigation</a>.</p>
|
||||
<h2>Tabs</h2>
|
||||
<ul>
|
||||
<li><kbd>Ctrl</kbd> + <kbd>🖱 Left click</kbd> - (or middle mouse click) on note
|
||||
<li data-list-item-id="e6a9d460427c0394177000c8a0eecfca4"><kbd>Ctrl</kbd> + <kbd>🖱 Left click</kbd> – (or middle mouse click) on note
|
||||
link opens note in a new tab</li>
|
||||
</ul>
|
||||
<p>Only in desktop (electron build):</p>
|
||||
<ul>
|
||||
<li><kbd>Ctrl</kbd> + <kbd>T</kbd> - opens empty tab</li>
|
||||
<li><kbd>Ctrl</kbd> + <kbd>W</kbd> - closes active tab</li>
|
||||
<li><kbd>Ctrl</kbd> + <kbd>Tab</kbd> - activates next tab</li>
|
||||
<li><kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Tab</kbd> - activates previous tab</li>
|
||||
<li data-list-item-id="e745e6690db1a4bee718faa94b272013e"><kbd>Ctrl</kbd> + <kbd>T</kbd> – opens empty tab</li>
|
||||
<li data-list-item-id="ec34c224c2c0dd74367753a6aff4f9721"><kbd>Ctrl</kbd> + <kbd>W</kbd> – closes active tab</li>
|
||||
<li data-list-item-id="e4b9a2163cccc3ab7dbdcf6fb7f149315"><kbd>Ctrl</kbd> + <kbd>Tab</kbd> – activates next tab</li>
|
||||
<li data-list-item-id="eeeabd750227ec42c30b282b9b8ab5c8d"><kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Tab</kbd> – activates previous tab</li>
|
||||
</ul>
|
||||
<h2>Creating notes</h2>
|
||||
<ul>
|
||||
<li><code>CTRL+O</code> - creates new note after the current note</li>
|
||||
<li><code>CTRL+P</code> - creates new sub-note into current note</li>
|
||||
<li><code>F2</code> - edit <a href="#root/_help_MMiBEQljMQh2">prefix</a> of current
|
||||
note clone</li>
|
||||
</ul>
|
||||
<h2>Moving / cloning notes</h2>
|
||||
<ul>
|
||||
<li><kbd>Ctrl</kbd> + <kbd><span>↑</span></kbd> , Ctrl + <kbd><span>↓</span></kbd> -
|
||||
move note up/down in the note list</li>
|
||||
<li><kbd>Ctrl</kbd> + <kbd><span>←</span></kbd> - move note up in the note tree</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd><span>→</span></kbd> - move note down in the note
|
||||
tree</li>
|
||||
<li><kbd>Shift</kbd>+<kbd><span>↑</span></kbd>, <kbd>Shift</kbd><code>+</code><kbd><span>↓</span></kbd> -
|
||||
multi-select note above/below</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>A</kbd> - select all notes in the current level</li>
|
||||
<li><kbd>Shift</kbd>+<kbd>🖱 Left click</kbd> - multi select note which you
|
||||
clicked on</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>C</kbd> - copies current note (or current selection)
|
||||
into clipboard (used for <a href="#root/_help_IakOLONlIfGI">cloning</a>
|
||||
</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>X</kbd> - cuts current (or current selection) note
|
||||
into clipboard (used for moving notes)</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>V</kbd> - pastes note(s) as sub-note into current
|
||||
note (which is either move or clone depending on whether it was copied
|
||||
or cut into clipboard)</li>
|
||||
<li><kbd>Del</kbd> - delete note / sub-tree</li>
|
||||
<li data-list-item-id="e90a7441e67297c921f8bb2145829dd55"><kbd>CTRL</kbd>+<kbd>O</kbd> – creates new note after the current note</li>
|
||||
<li
|
||||
data-list-item-id="e6064f6dd7b09083448cfb52247c94baa"><kbd>CTRL</kbd>+<kbd>P</kbd> – creates new sub-note into current note</li>
|
||||
<li
|
||||
data-list-item-id="e191cb0e7231c4439632d70da65dcf800"><kbd>F2</kbd> – edit <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/BFs8mudNFgCS/IakOLONlIfGI/_help_TBwsyfadTA18">Branch prefix</a> of
|
||||
current note clone</li>
|
||||
</ul>
|
||||
<h2>Editing notes</h2>
|
||||
<aside class="admonition note">
|
||||
@ -77,30 +58,32 @@
|
||||
class="reference-link" href="#root/_help_QrtTYPmdd1qq">Markdown-like formatting</a>.</p>
|
||||
</aside>
|
||||
<ul>
|
||||
<li><kbd>Enter</kbd> in tree pane switches from tree pane into note title.
|
||||
<li data-list-item-id="eea3611b470b2482ccf07e8844e4f66b9"><kbd>Enter</kbd> in tree pane switches from tree pane into note title.
|
||||
Enter from note title switches focus to text editor. <kbd>Ctrl</kbd>+<kbd>.</kbd> switches
|
||||
back from editor to tree pane.</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>.</kbd> - jump away from the editor to tree pane and
|
||||
<li data-list-item-id="e5dab831910ac694ccef7bc474b2e67fc"><kbd>Ctrl</kbd>+<kbd>.</kbd> – jump away from the editor to tree pane and
|
||||
scroll to current note</li>
|
||||
</ul>
|
||||
<h2>Runtime shortcuts</h2>
|
||||
<p>These are hooked in Electron to be similar to native browser keyboard
|
||||
shortcuts.</p>
|
||||
<ul>
|
||||
<li><kbd>F5</kbd>, <kbd>Ctrl</kbd>-<kbd>R</kbd> - reloads Trilium front-end</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>I</kbd> - show developer tools</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>F</kbd> - show search dialog</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>-</kbd> - zoom out</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>=</kbd> - zoom in</li>
|
||||
<li data-list-item-id="e1a17ce297e78109362180536b7eabd68"><kbd>F5</kbd>, <kbd>Ctrl</kbd>+<kbd>R</kbd> – reloads Trilium front-end</li>
|
||||
<li
|
||||
data-list-item-id="e07d1b25dc46ce0b0bd76a8db13373198"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>I</kbd> – show developer tools</li>
|
||||
<li
|
||||
data-list-item-id="e7dc66078ba520c48364952f2ac48aa79"><kbd>Ctrl</kbd>+<kbd>F</kbd> – show search dialog</li>
|
||||
<li data-list-item-id="e63161bd165a51e19fd04dd1223173e68"><kbd>Ctrl</kbd>+<kbd>-</kbd> – zoom out</li>
|
||||
<li data-list-item-id="e961144d0a57b51792830a2182459c8cf"><kbd>Ctrl</kbd>+<kbd>=</kbd> – zoom in</li>
|
||||
</ul>
|
||||
<h2>Other</h2>
|
||||
<ul>
|
||||
<li><kbd>Alt</kbd>+<kbd>O</kbd> - show SQL console (use only if you know what
|
||||
<li data-list-item-id="eb007c4ea2f2cd6eefbc8972d538c724c"><kbd>Alt</kbd> + <kbd>O</kbd> – show SQL console (use only if you know what
|
||||
you're doing)</li>
|
||||
<li><kbd>Alt</kbd>+<kbd>M</kbd> - distraction-free mode - display only note
|
||||
<li data-list-item-id="e9caedb43e6c66fc7c57b4899bd6d5d76"><kbd>Alt</kbd> + <kbd>M</kbd> – distraction-free mode - display only note
|
||||
editor, everything else is hidden</li>
|
||||
<li><kbd>F11</kbd> - toggle full screen</li>
|
||||
<li><kbd>Ctrl</kbd> + <kbd>S</kbd> - toggle <a href="#root/_help_eIg8jdvaoNNd">search</a> form
|
||||
<li data-list-item-id="ec55bd0e5ff7da0c488a5378c0bdabed5"><kbd>F11</kbd> – toggle full screen</li>
|
||||
<li data-list-item-id="e8d4ec0d76155371de5d060ad661cb19e"><kbd>Ctrl</kbd> + <kbd>S</kbd> – toggle <a href="#root/_help_eIg8jdvaoNNd">search</a> form
|
||||
in tree pane</li>
|
||||
<li><kbd>Alt</kbd> +<kbd>A</kbd> - show note <a href="#root/_help_zEY4DaJG4YT5">attributes</a> dialog</li>
|
||||
<li data-list-item-id="eb938081f527f44b158be7c3ed4af4925"><kbd>Alt</kbd> +<kbd>A</kbd> – show note <a href="#root/_help_zEY4DaJG4YT5">attributes</a> dialog</li>
|
||||
</ul>
|
||||
@ -1,33 +1,53 @@
|
||||
<p>The <a class="reference-link" href="#root/_help_oPVyFC7WL2Lp">Note Tree</a> comes
|
||||
with multiple keyboard shortcuts to make editing faster:</p>
|
||||
<h2>Navigation within the tree</h2>
|
||||
<ul>
|
||||
<li>Opening notes:
|
||||
<ul>
|
||||
<li><kbd>Click</kbd> to open the note in the current tab.</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>Click</kbd> or <kbd>Middle click</kbd> to open the note
|
||||
in a new tab.</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>Right click</kbd> to open the note in <a class="reference-link"
|
||||
href="#root/_help_ZjLYv08Rp3qC">Quick edit</a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Navigation within the tree:
|
||||
<ul>
|
||||
<li><kbd>Up</kbd> and <kbd>Down</kbd> to navigate between notes.</li>
|
||||
<li><kbd>Left</kbd> to collapse a note, or <kbd>Right</kbd> to expand it.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Clipboard management:
|
||||
<ul>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>C</kbd> to copy a note.</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>X</kbd> to cut a note.</li>
|
||||
<li><kbd>Ctrl</kbd>+<kbd>V</kbd> to paste it somewhere.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>For <a class="reference-link" href="#root/_help_yTjUdsOi4CIE">Multiple selection</a>:
|
||||
<ul>
|
||||
<li><kbd>Alt</kbd>+<kbd>Click</kbd>to add a single note to the current selection.</li>
|
||||
<li><kbd>Shift</kbd>+<kbd>Click</kbd>to select a range of notes, starting
|
||||
from the current note (the highlighted one) to the one that is being clicked.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="eede1a5721dab5213153c6bb25bad38c9"><kbd><span>↑</span></kbd> and <kbd><span>↑</span></kbd> to navigate between
|
||||
notes.</li>
|
||||
<li data-list-item-id="ec4c4ab60720b34a95f73e93223ed3628"><kbd><span>←</span></kbd> to collapse a note with children, or <kbd><span>→</span></kbd> to
|
||||
expand it.</li>
|
||||
<li data-list-item-id="eb5ad59d78e70611d0233ffbb5ede3b96"><kbd><span>←</span></kbd> on a note with no children to navigate to its
|
||||
parent.</li>
|
||||
</ul>
|
||||
<h2>Opening notes</h2>
|
||||
<ul>
|
||||
<li data-list-item-id="e3d92e8c3a1e5b9d6f2efe5067004ef5c"><kbd>Click</kbd> to open the note in the current tab.</li>
|
||||
<li data-list-item-id="e8ae44ff429a0da1d529c627874f54908"><kbd>Ctrl</kbd>+<kbd>Click</kbd> or <kbd>Middle click</kbd> to open the note
|
||||
in a new tab.</li>
|
||||
<li data-list-item-id="e183b1a014e2bd563450dac0c8913c6f0"><kbd>Ctrl</kbd>+<kbd>Right click</kbd> to open the note in <a class="reference-link"
|
||||
href="#root/_help_ZjLYv08Rp3qC">Quick edit</a>.</li>
|
||||
</ul>
|
||||
<h2>Clipboard management</h2>
|
||||
<ul>
|
||||
<li data-list-item-id="e28fb424bcc0d06b97ddcbcbc5145c350"><kbd>Ctrl</kbd>+<kbd>C</kbd> to copy one or more notes based on selection
|
||||
(see <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/BFs8mudNFgCS/_help_IakOLONlIfGI">Cloning Notes</a>).</li>
|
||||
<li
|
||||
data-list-item-id="e11c4c9fcdfeb566a58d9319a340ff893"><kbd>Ctrl</kbd>+<kbd>X</kbd> to cut one or more notes (for moving them).</li>
|
||||
<li
|
||||
data-list-item-id="e242519cf16b3414242c4d11f20688b5b"><kbd>Ctrl</kbd>+<kbd>V</kbd> to paste them somewhere (which results in
|
||||
a copy or move based on the shortcut used).</li>
|
||||
</ul>
|
||||
<h2>Moving notes</h2>
|
||||
<ul>
|
||||
<li data-list-item-id="ee2d0e5633e0ab23d0fcde7b968731794"><kbd>Ctrl</kbd> + <kbd><span>↑</span></kbd> , <kbd>Ctrl</kbd> + <kbd><span>↓</span></kbd> -
|
||||
move note up/down in the note list.</li>
|
||||
<li data-list-item-id="e14146e7aacfc92aa7daf8215ce4b379c"><kbd>Ctrl</kbd> + <kbd><span>←</span></kbd> - move note up in the note tree.</li>
|
||||
<li
|
||||
data-list-item-id="e21a7f5ab9d62af04b6ab81b0cc4cf8c7"><kbd>Ctrl</kbd>+<kbd><span>→</span></kbd> - move note down in the note
|
||||
tree.</li>
|
||||
<li data-list-item-id="e99f4b0aef9693ad25ca0ce62c5b67418"><kbd>Del</kbd> - deletes note and optionally its subtree (asked in the
|
||||
dialog).</li>
|
||||
</ul>
|
||||
<h2>Multiple selection</h2>
|
||||
<p>See <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/oPVyFC7WL2Lp/_help_yTjUdsOi4CIE">Multiple selection</a> for
|
||||
more information about how selection works.</p>
|
||||
<ul>
|
||||
<li data-list-item-id="ebe4907d702229ab599e50f753d23cfb6"><kbd>Alt</kbd>+<kbd>Click</kbd> – add a single note to the current selection.</li>
|
||||
<li
|
||||
data-list-item-id="ecf6bb49f8d993d376382dcab4e4a7ee8"><kbd>Shift</kbd>+<kbd>Click</kbd> – select a range of notes, starting from
|
||||
the current note (the highlighted one) to the one that is being clicked.</li>
|
||||
<li
|
||||
data-list-item-id="eb1398c2cf85b53eafc3b7ab7a0974668"><kbd>Shift</kbd>+<kbd><span>↑</span></kbd>, <kbd>Shift</kbd>+<kbd><span>↓</span></kbd> –
|
||||
multi-select not above/below.</li>
|
||||
<li data-list-item-id="ebc1274f576f67d08a6d665a7318d80a8"><kbd>Ctrl</kbd>+<kbd>A</kbd> – select all notes in the current level</li>
|
||||
</ul>
|
||||
13
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html
generated
vendored
13
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html
generated
vendored
@ -12,9 +12,9 @@
|
||||
as a single continuous document.</p>
|
||||
<h2>Interaction</h2>
|
||||
<ul>
|
||||
<li data-list-item-id="e8a9709d9f325dab560cb24289d5ab231">Each note can be expanded or collapsed by clicking on the arrow to the
|
||||
<li>Each note can be expanded or collapsed by clicking on the arrow to the
|
||||
left of the title.</li>
|
||||
<li data-list-item-id="e38647a2388fb38e1c6de17b617db9e76">In the <a class="reference-link" href="#root/_help_BlN9DFI679QC">Ribbon</a>,
|
||||
<li>In the <a class="reference-link" href="#root/_help_BlN9DFI679QC">Ribbon</a>,
|
||||
in the <em>Collection</em> tab there are options to expand and to collapse
|
||||
all notes easily.</li>
|
||||
</ul>
|
||||
@ -25,16 +25,15 @@
|
||||
<p>If exported to PDF within the desktop application, there is additional
|
||||
functionality:</p>
|
||||
<ul>
|
||||
<li data-list-item-id="e06095ff0a3876a29bdc11f1a2f18dfdc">The table of contents of the PDF will reflect the structure of the notes.</li>
|
||||
<li
|
||||
data-list-item-id="e656526a5aa019d58af324ae5c3d39216">Reference and inline links to other notes within the same hierarchy will
|
||||
<li>The table of contents of the PDF will reflect the structure of the notes.</li>
|
||||
<li>Reference and inline links to other notes within the same hierarchy will
|
||||
be functional (will jump to the corresponding page). If a link refers to
|
||||
a note that is not in the printed hierarchy, it will be unlinked.</li>
|
||||
</ul>
|
||||
<h2>Expanding and collapsing multiple notes at once</h2>
|
||||
<p>Apart from individually expanding or collapsing notes, it's also possible
|
||||
to expand or collapse them all at once. To do so, go to the <em>Collection Properties</em> tab
|
||||
in the <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_BlN9DFI679QC">Ribbon</a> and
|
||||
in the <a class="reference-link" href="#root/_help_BlN9DFI679QC">Ribbon</a> and
|
||||
look for the corresponding button.</p>
|
||||
<p>By default, the <em>Expand</em> button will only expand the direct children
|
||||
(first level) of the collection. Starting with v0.100.0, it's possible
|
||||
@ -45,7 +44,7 @@
|
||||
<aside class="admonition tip">
|
||||
<p>By design, the UI provides only a handful of levels of depth for expanding
|
||||
notes (direct children, 2-5, all levels). It's also possible to specify
|
||||
any desired depth by manually setting the <a href="#root/pOsGYCXsbNQG/tC7s2alapj8V/zEY4DaJG4YT5/_help_HI6GBBIduIgv">corresponding label</a>.
|
||||
any desired depth by manually setting the <a href="#root/_help_HI6GBBIduIgv">corresponding label</a>.
|
||||
For example: <code>#expanded=100</code> to expand up to 100 levels of depth.</p>
|
||||
</aside>
|
||||
<aside class="admonition note">
|
||||
|
||||
@ -19,6 +19,94 @@
|
||||
"move-note-up": "Posunout poznámku nahoru",
|
||||
"move-note-down": "Posunout poznámku dolů",
|
||||
"move-note-up-in-hierarchy": "Přesunout poznámku o úroveň výše",
|
||||
"move-note-down-in-hierarchy": "Přesunout poznámku ve struktuře níže"
|
||||
"move-note-down-in-hierarchy": "Přesunout poznámku ve struktuře níže",
|
||||
"edit-note-title": "Přejděte ze stromu k podrobnostem poznámky a upravte název",
|
||||
"edit-branch-prefix": "Zobrazit dialogové okno „Upravit předponu větve“",
|
||||
"add-note-above-to-the-selection": "Přidat poznámku nad výběr",
|
||||
"add-note-below-to-selection": "Přidejte poznámku pod výběr",
|
||||
"clone-notes-to": "Klonovat vybrané poznámky",
|
||||
"move-notes-to": "Přemístit vybrané poznámky",
|
||||
"note-clipboard": "Schránka na poznámky",
|
||||
"copy-notes-to-clipboard": "Zkopírujte vybrané poznámky do schránky",
|
||||
"paste-notes-from-clipboard": "Vložit poznámku ze schránky do aktivní poznámky",
|
||||
"cut-notes-to-clipboard": "Vyjměte vybrané poznámky do schránky",
|
||||
"select-all-notes-in-parent": "Vybrat všechny poznámky na aktuální úrovni poznámek",
|
||||
"duplicate-subtree": "Duplikovat podstrom",
|
||||
"tabs-and-windows": "Záložky a okna",
|
||||
"open-new-tab": "Otevřít novou záložku",
|
||||
"close-active-tab": "Zavřít aktivní záložku",
|
||||
"reopen-last-tab": "Znovu otevřít poslední zavřenou záložku",
|
||||
"activate-next-tab": "Aktivní záložka napravo",
|
||||
"activate-previous-tab": "Aktivní záložka nalevo",
|
||||
"open-new-window": "Otevřít nové prázdné okno",
|
||||
"toggle-tray": "Zobrazit/skrýt aplikaci z oznamovací oblasti systému",
|
||||
"first-tab": "Přejít na první záložku v seznamu",
|
||||
"second-tab": "Přejít na druhou záložku v seznamu",
|
||||
"third-tab": "Přejít na třetí záložku v seznamu",
|
||||
"fourth-tab": "Přejít na čtvrtou záložku v seznamu",
|
||||
"fifth-tab": "Přejít na pátou záložku v seznamu",
|
||||
"sixth-tab": "Přejít na šestou záložku v seznamu",
|
||||
"seventh-tab": "Přejít na sedmou záložku v seznamu",
|
||||
"eight-tab": "Přejít na osmou záložku v seznamu",
|
||||
"ninth-tab": "Přejít na devátou záložku v seznamu",
|
||||
"last-tab": "Přejít na poslední záložku v seznamu",
|
||||
"show-options": "Otevřít stránku „Nastavení“",
|
||||
"show-sql-console": "Otevřít stránku „SQL Konzole“",
|
||||
"show-backend-log": "Otevřít stránku „Backend Log“",
|
||||
"show-help": "Otevřít vestavěného uživatelského průvodce",
|
||||
"show-recent-changes": "Ukázat dialog „Poslední změny“",
|
||||
"show-note-source": "Ukázat dialog „Zdroj poznámky“",
|
||||
"edit-readonly-note": "Upravit poznámku pouze pro čtení",
|
||||
"other": "Ostatní",
|
||||
"run-active-note": "Spustit aktivní kód JavaScript (frontend/backend) poznámky",
|
||||
"open-dev-tools": "Otevřít vývojářské nástroje",
|
||||
"zoom-out": "Oddálit",
|
||||
"zoom-in": "Přiblížit",
|
||||
"text-note-operations": "Operace textových poznámek",
|
||||
"show-cheatsheet": "Zobrazit modal s běžnými operacemi klávesnice",
|
||||
"add-new-label": "Vytvořít nový štítek",
|
||||
"insert-date-and-time-to-text": "Vložit do textu současné datum a čas",
|
||||
"dialogs": "Dialogy",
|
||||
"show-revisions": "Ukázat dialog „Revize poznámky“",
|
||||
"add-link-to-text": "Otevřít dialog pro přidání odkazu do textu",
|
||||
"follow-link-under-cursor": "Následujte odkaz, na kterém je umístěna kurzorová šipka",
|
||||
"paste-markdown-into-text": "Vložit Markdown ze schránky do poznámky",
|
||||
"cut-into-note": "Vyjmout výběr z aktuální poznámky a vytvořit podpoznámku s vybraným textem",
|
||||
"add-include-note-to-text": "Otevřít dialog pro vložení poznámky",
|
||||
"attributes-labels-and-relations": "Atributy (štítky a vazby)",
|
||||
"create-new-relation": "Vytvořit novou vazbu",
|
||||
"ribbon-tabs": "Karty pásu záložek",
|
||||
"print-active-note": "Vytiskonout aktiivní poznámku",
|
||||
"render-active-note": "Vykreslit (znovu vykreslit) aktivní poznámku",
|
||||
"open-note-externally": "Otevřít poznámku jako soubor ve výchozí aplikaci",
|
||||
"reload-frontend-app": "Znovu načíst frontend",
|
||||
"unhoist": "Odpojit všude",
|
||||
"note-navigation": "Navigace v poznámce",
|
||||
"reset-zoom-level": "Resetovat úroveň přiblížení",
|
||||
"copy-without-formatting": "Kopírovat vybraný text bez formátování",
|
||||
"force-save-revision": "Vynutit vytvoření / uložení nové revize aktivní poznámky",
|
||||
"export-as-pdf": "Exportovat současnou poznámku jako PDF",
|
||||
"toggle-zen-mode": "Zapnout/vypnout režim zen (minimalistické uživatelské rozhraní pro soustředěnější úpravy)"
|
||||
},
|
||||
"keyboard_action_names": {
|
||||
"jump-to-note": "Přejít na...",
|
||||
"quick-search": "Rychlé hledání",
|
||||
"move-note-up": "Posunout poznámku výše",
|
||||
"move-note-down": "Posunout poznámku níže",
|
||||
"move-note-up-in-hierarchy": "Posunout poznámku výše v hierarchii",
|
||||
"move-note-down-in-hierarchy": "Posunout poznámku níže v hierarchii",
|
||||
"edit-note-title": "Upravit nadpis poznámky",
|
||||
"clone-notes-to": "Klonovat poznámku do",
|
||||
"move-notes-to": "Přemístit poznámku do",
|
||||
"copy-notes-to-clipboard": "Kopírovat poznámky do schránky",
|
||||
"back-in-note-history": "Zpět v historii poznámky",
|
||||
"forward-in-note-history": "Vpřed v historii poznámky",
|
||||
"command-palette": "Paleta příkazů",
|
||||
"scroll-to-active-note": "Posunout na aktivní poznámku",
|
||||
"search-in-subtree": "Hledat v podstromu",
|
||||
"expand-subtree": "Otevřít podstrom",
|
||||
"collapse-tree": "Zavřít strom",
|
||||
"collapse-subtree": "Zavřít podstrom",
|
||||
"sort-child-notes": "Seřadit dceřiné poznámky"
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,7 +256,9 @@
|
||||
"multi-factor-authentication-title": "MFA",
|
||||
"ai-llm-title": "AI/LLM",
|
||||
"localization": "Sprache & Region",
|
||||
"inbox-title": "Posteingang"
|
||||
"inbox-title": "Posteingang",
|
||||
"zen-mode": "Zen-Modus",
|
||||
"command-palette": "Befehlspalette öffnen"
|
||||
},
|
||||
"notes": {
|
||||
"new-note": "Neue Notiz",
|
||||
@ -302,7 +304,7 @@
|
||||
"end-time": "Endzeit",
|
||||
"geolocation": "Geolokation",
|
||||
"built-in-templates": "Integrierte Vorlagen",
|
||||
"board": "Tafel",
|
||||
"board": "Kanban-Board",
|
||||
"status": "Status",
|
||||
"board_note_first": "Erste Notiz",
|
||||
"board_note_second": "Zweite Notiz",
|
||||
|
||||
@ -27,7 +27,8 @@ async function register(app: express.Application) {
|
||||
appType: "custom",
|
||||
cacheDir: path.join(srcRoot, "../../.cache/vite"),
|
||||
base: `/${assetUrlFragment}/`,
|
||||
root: clientDir
|
||||
root: clientDir,
|
||||
css: { devSourcemap: true }
|
||||
});
|
||||
app.use(`/${assetUrlFragment}/`, (req, res, next) => {
|
||||
req.url = `/${assetUrlFragment}` + req.url;
|
||||
|
||||
@ -3,10 +3,137 @@
|
||||
"title": "Začínáme",
|
||||
"desktop_title": "Stažení aplikace pro osobní počítače (v{{version}})",
|
||||
"architecture": "Architektura:",
|
||||
"older_releases": "Starší vydání"
|
||||
"older_releases": "Starší vydání",
|
||||
"server_title": "Nastavte server pro přístup z více zařízení"
|
||||
},
|
||||
"hero_section": {
|
||||
"get_started": "Start",
|
||||
"github": "GitHub"
|
||||
"github": "GitHub",
|
||||
"title": "Uspořádejte si myšlenky. Vytvořte si osobní znalostní bázi.",
|
||||
"subtitle": "Trilium je open-source řešení pro pořizování poznámek a organizaci osobní znalostní báze. Používejte jej lokálně na svém počítači nebo jej synchronizujte se svým vlastním serverem, abyste měli své poznámky vždy po ruce, ať jste kdekoli.",
|
||||
"dockerhub": "Docker Hub",
|
||||
"screenshot_alt": "Snímek obrazovky desktopové aplikace Trilium Notes"
|
||||
},
|
||||
"organization_benefits": {
|
||||
"title": "Organizace",
|
||||
"note_structure_title": "Struktura poznámek",
|
||||
"note_structure_description": "Poznámky lze uspořádat hierarchicky. Není třeba používat složky, protože každá poznámka může obsahovat podpoznámky. Jednu poznámku lze přidat na více míst v hierarchii.",
|
||||
"attributes_title": "Poznámky k štítkům a vztahům",
|
||||
"attributes_description": "Využijte vztahy mezi poznámkami nebo přidejte štítky pro snadnou kategorizaci. Pomocí propagovaných atributů zadejte strukturované informace, které lze použít v tabulkách.",
|
||||
"hoisting_title": "Pracovní prostředí a hoisting",
|
||||
"hoisting_description": "Snadno oddělte své osobní a pracovní poznámky tím, že je seskupíte do pracovního prostoru, který zaměří strom poznámek tak, aby zobrazoval pouze konkrétní sadu poznámek."
|
||||
},
|
||||
"productivity_benefits": {
|
||||
"title": "Produktivita a bezpečnost",
|
||||
"revisions_title": "Revize poznámek",
|
||||
"revisions_content": "Poznámky se pravidelně ukládají na pozadí a revize lze použít k přezkoumání nebo ke zrušení náhodných změn. Revize lze také vytvářet na požádání.",
|
||||
"search_content": "Nebo vyhledávejte text uvnitř poznámek a zúžte vyhledávání filtrováním podle nadřazené poznámky nebo podle hloubky.",
|
||||
"web_clipper_title": "Webový výstřižek",
|
||||
"web_clipper_content": "Zachyťte webové stránky (nebo snímky obrazovky) a vložte je přímo do Trilium pomocí rozšíření prohlížeče Webového výstřižku.",
|
||||
"sync_title": "Synchoronizace",
|
||||
"sync_content": "Pomocí vlastní nebo cloudové instance můžete snadno synchronizovat své poznámky mezi více zařízeními a přistupovat k nim ze svého mobilního telefonu pomocí PWA.",
|
||||
"protected_notes_title": "Chráněné poznámky",
|
||||
"protected_notes_content": "Chraňte citlivé osobní údaje šifrováním poznámek a jejich uzamčením za heslem chráněnou relací.",
|
||||
"jump_to_title": "Rychlé hledání a příkazy",
|
||||
"jump_to_content": "Rychle přejděte k poznámkám nebo příkazům uživatelského rozhraní v celé hierarchii pomocí vyhledávání podle názvu, přičemž fuzzy vyhledávání zohledňuje překlepy nebo drobné rozdíly.",
|
||||
"search_title": "Výkonné vyhledávání"
|
||||
},
|
||||
"note_types": {
|
||||
"title": "Několik způsobů, jak prezentovat vaše informace",
|
||||
"text_title": "Textová poznámka",
|
||||
"text_description": "Poznámky se upravují pomocí vizuálního editoru (WYSIWYG) s podporou tabulek, obrázků, matematických výrazů a bloků kódu se zvýrazněním syntaxe. Text lze rychle formátovat pomocí syntaxe podobné Markdownu nebo pomocí příkazů s lomítkem.",
|
||||
"code_title": "Poznámka kódu",
|
||||
"code_description": "Velké vzorky zdrojového kódu nebo skriptů používají speciální editor s barevným zvýrazněním syntaxe pro mnoho programovacích jazyků a s různými barevnými motivy.",
|
||||
"file_title": "Souborové poznámky",
|
||||
"file_description": "Vložte multimediální soubory, jako jsou PDF, obrázky, videa, s náhledem v aplikaci.",
|
||||
"canvas_title": "Plátno",
|
||||
"canvas_description": "Uspořádejte tvary, obrázky a text na nekonečném plátně pomocí stejné technologie, jaká se používá na webu excalidraw.com. Ideální pro diagramy, náčrtky a vizuální plánování.",
|
||||
"mermaid_title": "Mermaid diagramy",
|
||||
"mermaid_description": "Vytvářejte diagramy, jako jsou vývojové diagramy, diagramy tříd a sekvencí, Ganttovy diagramy a mnoho dalších, pomocí syntaxe Mermaid.",
|
||||
"mindmap_title": "Myšlenková mapa",
|
||||
"mindmap_description": "Zorganizujte si myšlenky vizuálně nebo uspořádejte brainstorming.",
|
||||
"others_list": "a další: <0>mapa poznámek</0>, <1>mapa vztahů</1>, <2>uložená vyhledávání</2>, <3>zobrazení poznámky</3> a <4>webové zobrazení</4>."
|
||||
},
|
||||
"extensibility_benefits": {
|
||||
"title": "Sdílení a rozšiřitelnost",
|
||||
"import_export_title": "Import/export",
|
||||
"import_export_description": "Snadná interakce s jinými aplikacemi pomocí formátů Markdown, ENEX a OML.",
|
||||
"share_title": "Sdílet poznámky na webu",
|
||||
"share_description": "Pokud máte server, můžete jej použít ke sdílení části svých poznámek s ostatními lidmi.",
|
||||
"scripting_title": "Pokročilé skriptování",
|
||||
"scripting_description": "Vytvořte si vlastní integrace v rámci Trilium pomocí přizpůsobených widgetů nebo logiky na straně serveru.",
|
||||
"api_title": "REST API",
|
||||
"api_description": "Komunikujte s Trilium programově pomocí jeho vestavěného REST API."
|
||||
},
|
||||
"collections": {
|
||||
"title": "Kolekce",
|
||||
"calendar_title": "Kalendář",
|
||||
"calendar_description": "Organizujte své osobní nebo pracovní události pomocí kalendáře, který podporuje celodenní i vícedenní události. Zobrazte si své události na první pohled v týdenním, měsíčním a ročním přehledu. Snadná interakce pro přidávání nebo přetahování událostí.",
|
||||
"table_title": "Tabulka",
|
||||
"table_description": "Zobrazujte a upravujte informace o poznámkách v tabulkové struktuře s různými typy sloupců, jako jsou text, čísla, zaškrtávací políčka, datum a čas, odkazy a barvy, a podporou vztahů. Volitelně můžete poznámky zobrazit v hierarchické struktuře stromu uvnitř tabulky.",
|
||||
"board_title": "Kanbanová tabule",
|
||||
"board_description": "Uspořádejte si úkoly nebo stav projektu do tabule Kanban, kde můžete snadno vytvářet nové položky a sloupce a jednoduše měnit jejich stav přetahováním po tabuli.",
|
||||
"geomap_title": "Geomapa",
|
||||
"geomap_description": "Naplánujte si dovolenou nebo si označte místa, která vás zajímají, přímo na geografické mapě pomocí přizpůsobitelných značek. Zobrazte zaznamenané trasy GPX a sledujte itineráře.",
|
||||
"presentation_title": "Prezentace",
|
||||
"presentation_description": "Uspořádejte informace do snímků a prezentujte je na celé obrazovce s plynulými přechody. Snímky lze také exportovat do formátu PDF pro snadné sdílení."
|
||||
},
|
||||
"faq": {
|
||||
"title": "Často kladené otázky",
|
||||
"mobile_question": "Existuje mobilní aplikace?",
|
||||
"mobile_answer": "V současné době neexistuje žádná oficiální mobilní aplikace. Pokud však máte instanci serveru, můžete k ní přistupovat pomocí webového prohlížeče a dokonce ji nainstalovat jako PWA. Pro Android existuje neoficiální aplikace s názvem TriliumDroid, která funguje i offline (stejně jako desktopový klient).",
|
||||
"database_question": "Kde jsou má data uložena?",
|
||||
"database_answer": "Všechny vaše poznámky budou uloženy v databázi SQLite ve složce aplikace. Důvodem, proč Trilium používá databázi namísto prostých textových souborů, je jak výkon, tak i skutečnost, že některé funkce by byly mnohem obtížnější implementovat, například klony (stejná poznámka na více místech ve stromu). Chcete-li najít složku aplikace, stačí přejít do okna O aplikaci.",
|
||||
"server_question": "Potřebuju server pro používání Trilium?",
|
||||
"server_answer": "Ne, server umožňuje přístup přes webový prohlížeč a spravuje synchronizaci, pokud máte více zařízení. Chcete-li začít, stačí si stáhnout desktopovou aplikaci a začít ji používat.",
|
||||
"scaling_question": "Jak dobře se aplikace přizpůsobuje velkému množství poznámek?",
|
||||
"scaling_answer": "V závislosti na použití by aplikace měla být schopna bez problémů zpracovat alespoň 100 000 poznámek. Upozorňujeme, že proces synchronizace může někdy selhat, pokud nahráváte mnoho velkých souborů (1 GB na soubor), protože Trilium je spíše aplikací pro správu znalostí než úložištěm souborů (jako například NextCloud).",
|
||||
"network_share_question": "Mohu sdílet svou databázi přes síťový disk?",
|
||||
"network_share_answer": "Ne, sdílení databáze SQLite přes síťový disk obecně není dobrý nápad. I když to někdy může fungovat, existuje riziko, že se databáze poškodí kvůli nedokonalému zamykání souborů v síti.",
|
||||
"security_question": "Jak jsou má data chráněna?",
|
||||
"security_answer": "Ve výchozím nastavení nejsou poznámky šifrovány a lze je číst přímo z databáze. Jakmile je poznámka označena jako šifrovaná, je zašifrována pomocí AES-128-CBC."
|
||||
},
|
||||
"final_cta": {
|
||||
"title": "Jste připraveni začít používat Trilium Notes?",
|
||||
"description": "Vytvořte si svou osobní znalostní bázi s výkonnými funkcemi a plným soukromím.",
|
||||
"get_started": "Začít"
|
||||
},
|
||||
"components": {
|
||||
"link_learn_more": "Zjistit více..."
|
||||
},
|
||||
"download_now": {
|
||||
"text": "Stáhnout nyní ",
|
||||
"platform_big": "v{{version}} pro{{platform}}",
|
||||
"platform_small": "pro {{platform}}",
|
||||
"linux_big": "v{{version}} pro Linux",
|
||||
"linux_small": "pro Linux",
|
||||
"more_platforms": "Další platformy a nastavení serveru"
|
||||
},
|
||||
"header": {
|
||||
"get-started": "Začít",
|
||||
"documentation": "Dokumentace",
|
||||
"support-us": "Podpořte nás"
|
||||
},
|
||||
"footer": {
|
||||
"copyright_and_the": " a ",
|
||||
"copyright_community": "komunita"
|
||||
},
|
||||
"social_buttons": {
|
||||
"github": "GitHub",
|
||||
"github_discussions": "GitHub diskuze",
|
||||
"matrix": "Matrix",
|
||||
"reddit": "Reddit"
|
||||
},
|
||||
"support_us": {
|
||||
"title": "Podpořte nás",
|
||||
"financial_donations_title": "Finanční dary",
|
||||
"financial_donations_description": "Trilium je vyvíjeno a udržováno díky <Link>stovkám hodin práce</Link>. Vaše podpora zajišťuje, že zůstane open-source, vylepšuje jeho funkce a pokrývá náklady, jako je hosting.",
|
||||
"financial_donations_cta": "Zvažte podporu hlavního vývojáře (<Link>eliandoran</Link>) aplikace prostřednictvím:",
|
||||
"github_sponsors": "Sponzoři GitHubu",
|
||||
"paypal": "PayPal",
|
||||
"buy_me_a_coffee": "Buy Me A Coffee"
|
||||
},
|
||||
"contribute": {
|
||||
"title": "Další způsoby, jak přispět"
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +36,9 @@
|
||||
"code_title": "Code Notizen",
|
||||
"canvas_title": "Canvas",
|
||||
"mermaid_title": "Mermaid Diagramm",
|
||||
"mindmap_title": "Mind Map"
|
||||
"mindmap_title": "Mind Map",
|
||||
"text_description": "Die Notizen werden mit einem visuellen Editor (WYSIWYG) bearbeitet, der Tabellen, Bilder, mathematische Ausdrücke und Code-Blöcke mit Syntaxhervorhebung unterstützt. Formatieren Sie den Text schnell mit einer Markdown-ähnlichen Syntax oder mit Slash-Befehlen.",
|
||||
"code_description": "Große Quellcode- oder Skriptdateien werden mit einem speziellen Editor bearbeitet, der Syntaxhervorhebung für viele Programmiersprachen und diverse Farbschemata bietet."
|
||||
},
|
||||
"extensibility_benefits": {
|
||||
"import_export_title": "Import/Export",
|
||||
@ -45,5 +47,41 @@
|
||||
},
|
||||
"collections": {
|
||||
"calendar_title": "Kalender"
|
||||
},
|
||||
"download_helper_desktop_macos": {
|
||||
"quick_start": "Installieren mit Homebrew:",
|
||||
"download_dmg": "Installer (.dmg) herunterladen",
|
||||
"download_zip": "Portable (.zip)",
|
||||
"download_homebrew_cask": "Die Homebrew Cask",
|
||||
"description_arm64": "Für Apple Silicon Macs, beispielsweise mit M1-, M2-, M3- oder M4-Chips.",
|
||||
"description_x64": "Für Intel-Macs ab macOS Monterey und neuer.",
|
||||
"title_x64": "macOS für Intel",
|
||||
"title_arm64": "macOS für Apple Silicon"
|
||||
},
|
||||
"download_helper_server_docker": {
|
||||
"title": "Self-hosted mit Docker",
|
||||
"description": "Schnelle Installation auf Windows, Linux oder macOS mit einem Docker-Container.",
|
||||
"download_dockerhub": "Docker-Hub",
|
||||
"download_ghcr": "ghcr.io"
|
||||
},
|
||||
"download_helper_desktop_linux": {
|
||||
"download_aur": "AUR",
|
||||
"download_nixpkgs": "nixpkgs",
|
||||
"download_zip": "Portable (.zip)",
|
||||
"download_flatpak": ".flatpak",
|
||||
"download_rpm": ".rpm"
|
||||
},
|
||||
"download_helper_server_linux": {
|
||||
"title": "Self-hosted auf Linux",
|
||||
"description": "Trilium Notes auf Ihrem eigenen Server oder VPS bereitstellen – kompatibel mit den meisten Linux-Distributionen.",
|
||||
"download_tar_x64": "x64 (.tar.xz)",
|
||||
"download_tar_arm64": "ARM (.tar.xz)",
|
||||
"download_nixos": "NixOS Module"
|
||||
},
|
||||
"download_helper_server_hosted": {
|
||||
"title": "Kostenpflichtiges Hosting",
|
||||
"description": "Trilium Notes wird auf PikaPods gehostet, einem kostenpflichtigen Dienst für einfachen Zugriff und Verwaltung. Es besteht keine direkte Verbindung zum Trilium-Team.",
|
||||
"download_pikapod": "Auf PikaPods installieren",
|
||||
"download_triliumcc": "Alternativ siehe trilium.cc"
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,5 +5,13 @@
|
||||
"architecture": "Mimari:",
|
||||
"older_releases": "Eski sürümleri görüntüle",
|
||||
"server_title": "Birden fazla cihazdan erişim için bir sunucu kurun"
|
||||
},
|
||||
"hero_section": {
|
||||
"title": "Düşüncelerinizi organize edin. Kişisel bilgi birikiminizi oluşturun.",
|
||||
"subtitle": "Trilium, not tutma ve kişisel bir bilgi tabanını düzenleme için açık kaynaklı bir çözümdür. Bunu masaüstünü bilgisayarınızda kullanabilir veya kendi barındırdığınız sunucuyla senkronize ederek notlarınızı gittiğiniz her yerde yanınızda bulundurabilirsiniz.",
|
||||
"get_started": "Başlayın",
|
||||
"github": "GitHub",
|
||||
"dockerhub": "Docker Hub",
|
||||
"screenshot_alt": "Trilium Notes masaüstü uygulamasının ekran görüntüsü"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Documentation
|
||||
There are multiple types of documentation for Trilium:<img class="image-style-align-right" src="api/images/VUKpkCok5Zh4/Documentation_image.png" width="205" height="162">
|
||||
There are multiple types of documentation for Trilium:<img class="image-style-align-right" src="api/images/Xtlv3JlumknM/Documentation_image.png" width="205" height="162">
|
||||
|
||||
* The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing <kbd>F1</kbd>.
|
||||
* The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers.
|
||||
|
||||
125
docs/README-cs.md
vendored
125
docs/README-cs.md
vendored
@ -11,14 +11,14 @@
|
||||
|
||||
# Trilium Notes
|
||||
|
||||

|
||||
\
|
||||
 \
|
||||

|
||||
\
|
||||
\
|
||||
[](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp)
|
||||
[](https://hosted.weblate.org/engage/trilium/)
|
||||
[](https://hosted.weblate.org/engage/trilium/)
|
||||
|
||||
[Angličtina](./README.md) | [Čínština (Zjednodušená)](./docs/README-ZH_CN.md) |
|
||||
[Čínština (Tradiční)](./docs/README-ZH_TW.md) | [Ruština](./docs/README-ru.md) |
|
||||
@ -28,8 +28,8 @@ status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted
|
||||
Trilium Notes je open-source, cross-platform aplikace pro hierarchiální psaní
|
||||
poznámek.
|
||||
|
||||
See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for
|
||||
quick overview:
|
||||
Pro rychlý přehled viz
|
||||
[screenshot](https://triliumnext.github.io/Docs/Wiki/screenshot-tour):
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./docs/app.png" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
@ -37,8 +37,7 @@ quick overview:
|
||||
- [Nejnovější verze](https://github.com/TriliumNext/Trilium/releases/latest) –
|
||||
stabilní verze, doporučena pro většinu uživatelů.
|
||||
- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) –
|
||||
unstable development version, updated daily with the latest features and
|
||||
fixes.
|
||||
nestabilní vývojová verze, denně aktualizovaná o nejnovější funkce a opravy.
|
||||
|
||||
## 📚 Dokumentace
|
||||
|
||||
@ -61,62 +60,64 @@ Naše dokumenatce je dostupná ve vícero formátech:
|
||||
Dockeru](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md)
|
||||
- [Aktualizování
|
||||
TriliumNext](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Upgrading%20TriliumNext.md)
|
||||
- [Basic Concepts and
|
||||
Features](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md)
|
||||
- [Patterns of Personal Knowledge
|
||||
Base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)
|
||||
- [Základní pojmy a
|
||||
funkce](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md)
|
||||
- [Vzory osobní znalostní
|
||||
báze](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)
|
||||
|
||||
## 🎁 Funkce
|
||||
|
||||
* Notes can be arranged into arbitrarily deep tree. Single note can be placed
|
||||
into multiple places in the tree (see
|
||||
[cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
|
||||
* Rich WYSIWYG note editor including e.g. tables, images and
|
||||
[math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown
|
||||
* Poznámky lze uspořádat do libovolně hlubokého stromu. Jedna poznámka může být
|
||||
umístěna na více místech ve stromu (viz
|
||||
[klonování](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
|
||||
* Bohatý editor poznámek WYSIWYG zahrnující např. tabulky, obrázky a
|
||||
[math](https://triliumnext.github.io/Docs/Wiki/text-notes) s automatickým
|
||||
formátováním
|
||||
[autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)
|
||||
* Support for editing [notes with source
|
||||
code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax
|
||||
highlighting
|
||||
* Fast and easy [navigation between
|
||||
notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text
|
||||
search and [note
|
||||
hoisting](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
|
||||
* Seamless [note
|
||||
versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be
|
||||
used for note organization, querying and advanced
|
||||
[scripting](https://triliumnext.github.io/Docs/Wiki/scripts)
|
||||
* UI available in English, German, Spanish, French, Romanian, and Chinese
|
||||
(simplified and traditional)
|
||||
* Direct [OpenID and TOTP
|
||||
integration](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md)
|
||||
for more secure login
|
||||
* [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization)
|
||||
with self-hosted sync server
|
||||
* there's a [3rd party service for hosting synchronisation
|
||||
server](https://trilium.cc/paid-hosting)
|
||||
* [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes
|
||||
to public internet
|
||||
* Strong [note
|
||||
encryption](https://triliumnext.github.io/Docs/Wiki/protected-notes) with
|
||||
per-note granularity
|
||||
* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type
|
||||
"canvas")
|
||||
* [Relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map) and
|
||||
[link maps](https://triliumnext.github.io/Docs/Wiki/link-map) for visualizing
|
||||
notes and their relations
|
||||
* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/)
|
||||
* [Geo maps](./docs/User%20Guide/User%20Guide/Note%20Types/Geo%20Map.md) with
|
||||
location pins and GPX tracks
|
||||
* [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - see [Advanced
|
||||
showcases](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
* [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) for automation
|
||||
* Scales well in both usability and performance upwards of 100 000 notes
|
||||
* Touch optimized [mobile
|
||||
frontend](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) for
|
||||
smartphones and tablets
|
||||
* Built-in [dark theme](https://triliumnext.github.io/Docs/Wiki/themes), support
|
||||
for user themes
|
||||
* Podpora pro úpravy [poznámek se zdrojovým
|
||||
kódem](https://triliumnext.github.io/Docs/Wiki/code-notes), včetně zvýraznění
|
||||
syntaxe
|
||||
* Rychlá a snadná [navigace mezi
|
||||
poznámkami](https://triliumnext.github.io/Docs/Wiki/note-navigation),
|
||||
vyhledávání v plném textu a [zvedání
|
||||
poznámek](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
|
||||
* Bezproblémová [poznámka k
|
||||
verzím](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* Poznámka [atributy](https://triliumnext.github.io/Docs/Wiki/attributes) lze
|
||||
použít pro organizaci poznámek, dotazování a pokročilé
|
||||
[skriptování](https://triliumnext.github.io/Docs/Wiki/scripts)
|
||||
* Uživatelské rozhraní je k dispozici v angličtině, češtině, němčině,
|
||||
španělštině, francouzštině, rumunštině a čínštině (zjednodušené a tradiční)
|
||||
* Přímá integrace [OpenID a
|
||||
TOTP](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md)
|
||||
pro bezpečnější přihlášení
|
||||
* [Synchronizace](https://triliumnext.github.io/Docs/Wiki/synchronization) s
|
||||
vlastním synchronizačním serverem
|
||||
* existuje [služba třetí strany pro hostování synchronizačního
|
||||
serveru](https://trilium.cc/paid-hosting)
|
||||
* [Sdílení](https://triliumnext.github.io/Docs/Wiki/sharing) (zveřejňování)
|
||||
poznámek na veřejném internetu
|
||||
* Silné [šifrování
|
||||
poznámek](https://triliumnext.github.io/Docs/Wiki/protected-notes) s
|
||||
granularitou na úrovni jednotlivých poznámek
|
||||
* Náčrt diagramů na základě [Excalidraw](https://excalidraw.com/) (poznámka typu
|
||||
„plátno“)
|
||||
* [Mapy vztahů](https://triliumnext.github.io/Docs/Wiki/relation-map) a [mapy
|
||||
odkazů](https://triliumnext.github.io/Docs/Wiki/link-map) pro vizualizaci
|
||||
poznámek a jejich vztahů
|
||||
* Myšlenkové mapy založené na [Mind Elixir](https://docs.mind-elixir.com/)
|
||||
* [Geo mapy](./docs/User%20Guide/User%20Guide/Note%20Types/Geo%20Map.md) s
|
||||
lokalizačními značkami a trasami GPX
|
||||
* [Skriptování](https://triliumnext.github.io/Docs/Wiki/scripts) – viz
|
||||
[Pokročilé ukázky](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
* [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) pro automatizaci
|
||||
* Dobře škálovatelný jak z hlediska použitelnosti, tak výkonu až do 100 000
|
||||
poznámek
|
||||
* Optimalizované pro dotykové ovládání [mobilní
|
||||
rozhraní](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) pro
|
||||
smartphony a tablety
|
||||
* Vestavěný [tmavý motiv](https://triliumnext.github.io/Docs/Wiki/themes),
|
||||
podpora uživatelských motivů
|
||||
* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) and
|
||||
[Markdown import & export](https://triliumnext.github.io/Docs/Wiki/markdown)
|
||||
* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) for easy
|
||||
|
||||
18
docs/README-tr.md
vendored
18
docs/README-tr.md
vendored
@ -34,19 +34,19 @@ görüntülerine](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) bakı
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./docs/app.png" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
## ⏬ Download
|
||||
- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) –
|
||||
stable version, recommended for most users.
|
||||
## İndir
|
||||
- [Son sürüm](https://github.com/TriliumNext/Trilium/releases/latest) – stabil
|
||||
versiyon, standart kullanıcılar için tavsiye edilir.
|
||||
- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) –
|
||||
unstable development version, updated daily with the latest features and
|
||||
fixes.
|
||||
kararsız geliştirme sürümü, son özellikler ve iyileştirmelerle günlük olarak
|
||||
güncellenir.
|
||||
|
||||
## 📚 Documentation
|
||||
## Dokümantasyon
|
||||
|
||||
**Visit our comprehensive documentation at
|
||||
[docs.triliumnotes.org](https://docs.triliumnotes.org/)**
|
||||
**Kapsamlı dokümanlarımızı [docs.triliumnotes.org] adresinden ziyaret
|
||||
edin(https://docs.triliumnotes.org/)**
|
||||
|
||||
Our documentation is available in multiple formats:
|
||||
Dokümantasyonumuz birden fazla formatta mevcuttur:
|
||||
- **Online Documentation**: Browse the full documentation at
|
||||
[docs.triliumnotes.org](https://docs.triliumnotes.org/)
|
||||
- **In-App Help**: Press `F1` within Trilium to access the same documentation
|
||||
|
||||
56
docs/User Guide/!!!meta.json
vendored
56
docs/User Guide/!!!meta.json
vendored
@ -2380,13 +2380,6 @@
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "yTjUdsOi4CIE",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
@ -2400,6 +2393,20 @@
|
||||
"value": "keyboard-shortcuts",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "IakOLONlIfGI",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "yTjUdsOi4CIE",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -5211,13 +5218,6 @@
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "IakOLONlIfGI",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
@ -5259,6 +5259,20 @@
|
||||
"value": "bx bxs-keyboard",
|
||||
"isInheritable": false,
|
||||
"position": 80
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "DvdZhoQZY9Yd",
|
||||
"isInheritable": false,
|
||||
"position": 90
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "TBwsyfadTA18",
|
||||
"isInheritable": false,
|
||||
"position": 100
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -10576,6 +10590,13 @@
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "HI6GBBIduIgv",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
@ -10589,13 +10610,6 @@
|
||||
"value": "list",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "HI6GBBIduIgv",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
|
||||
@ -3,49 +3,38 @@ This is supposed to be a complete list of keyboard shortcuts. Note that some of
|
||||
|
||||
It is also possible to configure most keyboard shortcuts in Options -> Keyboard shortcuts. Using `global:` prefix, you can assign a shortcut which will work even without Trilium being in focus (requires app restart to take effect).
|
||||
|
||||
## Tree
|
||||
|
||||
See the corresponding section: <a class="reference-link" href="UI%20Elements/Note%20Tree/Keyboard%20shortcuts.md">Keyboard shortcuts</a>
|
||||
|
||||
## Note navigation
|
||||
|
||||
* <kbd><span>↑</span></kbd>, <kbd><span>↓</span></kbd> - go up/down in the list of notes, <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd><span>↑</span></kbd> and <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd><span>↓</span></kbd> work also from editor
|
||||
* <kbd><span>←</span></kbd>, <kbd><span>→</span></kbd> - collapse/expand node
|
||||
* <kbd>Alt</kbd> + <kbd><span>←</span></kbd>, <kbd>Alt</kbd> + <kbd><span>→</span></kbd> - go back / forwards in the history
|
||||
* <kbd>Ctrl</kbd> + <kbd>J</kbd> - show ["Jump to" dialog](Navigation/Note%20Navigation.md)
|
||||
* <kbd>Ctrl</kbd> + <kbd>.</kbd> - scroll to current note (useful when you scroll away from your note or your focus is currently in the editor)
|
||||
* <kbd><span>Backspace</span></kbd> - jumps to parent note
|
||||
* <kbd>Alt</kbd> + <kbd>C</kbd> - collapse whole note tree
|
||||
* <kbd>Alt</kbd> + <kbd>-</kbd> (alt with minus sign) - collapse subtree (if some subtree takes too much space on tree pane you can collapse it)
|
||||
* <kbd>Alt</kbd> + <kbd><span>←</span></kbd>, <kbd>Alt</kbd> + <kbd><span>→</span></kbd> – go back / forwards in the history
|
||||
* <kbd>Ctrl</kbd> + <kbd>J</kbd> – show ["Jump to" dialog](Navigation/Note%20Navigation.md)
|
||||
* <kbd>Ctrl</kbd> + <kbd>.</kbd> – scroll to current note (useful when you scroll away from your note or your focus is currently in the editor)
|
||||
* <kbd><span>Backspace</span></kbd> – jumps to parent note
|
||||
* <kbd>Alt</kbd> + <kbd>C</kbd> – collapse whole note tree
|
||||
* <kbd>Alt</kbd> + <kbd>-</kbd> (alt with minus sign) – collapse subtree (if some subtree takes too much space on tree pane you can collapse it)
|
||||
* you can define a [label](../Advanced%20Usage/Attributes.md) `#keyboardShortcut` with e.g. value <kbd>Ctrl</kbd> + <kbd>I</kbd> . Pressing this keyboard combination will then bring you to the note on which it is defined. Note that Trilium must be reloaded/restarted (<kbd>Ctrl</kbd> + <kbd>R</kbd> ) for changes to be in effect.
|
||||
|
||||
See demo of some of these features in [note navigation](Navigation/Note%20Navigation.md).
|
||||
|
||||
## Tabs
|
||||
|
||||
* <kbd>Ctrl</kbd> + <kbd>🖱 Left click</kbd> - (or middle mouse click) on note link opens note in a new tab
|
||||
* <kbd>Ctrl</kbd> + <kbd>🖱 Left click</kbd> – (or middle mouse click) on note link opens note in a new tab
|
||||
|
||||
Only in desktop (electron build):
|
||||
|
||||
* <kbd>Ctrl</kbd> + <kbd>T</kbd> - opens empty tab
|
||||
* <kbd>Ctrl</kbd> + <kbd>W</kbd> - closes active tab
|
||||
* <kbd>Ctrl</kbd> + <kbd>Tab</kbd> - activates next tab
|
||||
* <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Tab</kbd> - activates previous tab
|
||||
* <kbd>Ctrl</kbd> + <kbd>T</kbd> – opens empty tab
|
||||
* <kbd>Ctrl</kbd> + <kbd>W</kbd> – closes active tab
|
||||
* <kbd>Ctrl</kbd> + <kbd>Tab</kbd> – activates next tab
|
||||
* <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Tab</kbd> – activates previous tab
|
||||
|
||||
## Creating notes
|
||||
|
||||
* `CTRL+O` - creates new note after the current note
|
||||
* `CTRL+P` - creates new sub-note into current note
|
||||
* `F2` - edit [prefix](Navigation/Note%20Navigation.md) of current note clone
|
||||
|
||||
## Moving / cloning notes
|
||||
|
||||
* <kbd>Ctrl</kbd> + <kbd><span>↑</span></kbd> , Ctrl + <kbd><span>↓</span></kbd> - move note up/down in the note list
|
||||
* <kbd>Ctrl</kbd> + <kbd><span>←</span></kbd> - move note up in the note tree
|
||||
* <kbd>Ctrl</kbd>+<kbd><span>→</span></kbd> - move note down in the note tree
|
||||
* <kbd>Shift</kbd>+<kbd><span>↑</span></kbd>, <kbd>Shift</kbd>`+`<kbd><span>↓</span></kbd> - multi-select note above/below
|
||||
* <kbd>Ctrl</kbd>+<kbd>A</kbd> - select all notes in the current level
|
||||
* <kbd>Shift</kbd>+<kbd>🖱 Left click</kbd> - multi select note which you clicked on
|
||||
* <kbd>Ctrl</kbd>+<kbd>C</kbd> - copies current note (or current selection) into clipboard (used for [cloning](Notes/Cloning%20Notes.md)
|
||||
* <kbd>Ctrl</kbd>+<kbd>X</kbd> - cuts current (or current selection) note into clipboard (used for moving notes)
|
||||
* <kbd>Ctrl</kbd>+<kbd>V</kbd> - pastes note(s) as sub-note into current note (which is either move or clone depending on whether it was copied or cut into clipboard)
|
||||
* <kbd>Del</kbd> - delete note / sub-tree
|
||||
* <kbd>CTRL</kbd>+<kbd>O</kbd> – creates new note after the current note
|
||||
* <kbd>CTRL</kbd>+<kbd>P</kbd> – creates new sub-note into current note
|
||||
* <kbd>F2</kbd> – edit <a class="reference-link" href="Notes/Cloning%20Notes/Branch%20prefix.md">Branch prefix</a> of current note clone
|
||||
|
||||
## Editing notes
|
||||
|
||||
@ -53,22 +42,22 @@ Only in desktop (electron build):
|
||||
> For keyboard shortcuts specific to <a class="reference-link" href="../Note%20Types/Text.md">Text</a> notes, refer to <a class="reference-link" href="../Note%20Types/Text/Keyboard%20shortcuts.md">Keyboard shortcuts</a> and <a class="reference-link" href="../Note%20Types/Text/Markdown-like%20formatting.md">Markdown-like formatting</a>.
|
||||
|
||||
* <kbd>Enter</kbd> in tree pane switches from tree pane into note title. Enter from note title switches focus to text editor. <kbd>Ctrl</kbd>+<kbd>.</kbd> switches back from editor to tree pane.
|
||||
* <kbd>Ctrl</kbd>+<kbd>.</kbd> - jump away from the editor to tree pane and scroll to current note
|
||||
* <kbd>Ctrl</kbd>+<kbd>.</kbd> – jump away from the editor to tree pane and scroll to current note
|
||||
|
||||
## Runtime shortcuts
|
||||
|
||||
These are hooked in Electron to be similar to native browser keyboard shortcuts.
|
||||
|
||||
* <kbd>F5</kbd>, <kbd>Ctrl</kbd>\-<kbd>R</kbd> - reloads Trilium front-end
|
||||
* <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>I</kbd> - show developer tools
|
||||
* <kbd>Ctrl</kbd>+<kbd>F</kbd> - show search dialog
|
||||
* <kbd>Ctrl</kbd>+<kbd>-</kbd> - zoom out
|
||||
* <kbd>Ctrl</kbd>+<kbd>=</kbd> - zoom in
|
||||
* <kbd>F5</kbd>, <kbd>Ctrl</kbd>+<kbd>R</kbd> – reloads Trilium front-end
|
||||
* <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>I</kbd> – show developer tools
|
||||
* <kbd>Ctrl</kbd>+<kbd>F</kbd> – show search dialog
|
||||
* <kbd>Ctrl</kbd>+<kbd>-</kbd> – zoom out
|
||||
* <kbd>Ctrl</kbd>+<kbd>=</kbd> – zoom in
|
||||
|
||||
## Other
|
||||
|
||||
* <kbd>Alt</kbd>+<kbd>O</kbd> - show SQL console (use only if you know what you're doing)
|
||||
* <kbd>Alt</kbd>+<kbd>M</kbd> - distraction-free mode - display only note editor, everything else is hidden
|
||||
* <kbd>F11</kbd> - toggle full screen
|
||||
* <kbd>Ctrl</kbd> + <kbd>S</kbd> - toggle [search](Navigation/Search.md) form in tree pane
|
||||
* <kbd>Alt</kbd> +<kbd>A</kbd> - show note [attributes](../Advanced%20Usage/Attributes.md) dialog
|
||||
* <kbd>Alt</kbd> + <kbd>O</kbd> – show SQL console (use only if you know what you're doing)
|
||||
* <kbd>Alt</kbd> + <kbd>M</kbd> – distraction-free mode - display only note editor, everything else is hidden
|
||||
* <kbd>F11</kbd> – toggle full screen
|
||||
* <kbd>Ctrl</kbd> + <kbd>S</kbd> – toggle [search](Navigation/Search.md) form in tree pane
|
||||
* <kbd>Alt</kbd> +<kbd>A</kbd> – show note [attributes](../Advanced%20Usage/Attributes.md) dialog
|
||||
@ -1,17 +1,36 @@
|
||||
# Keyboard shortcuts
|
||||
The <a class="reference-link" href="../Note%20Tree.md">Note Tree</a> comes with multiple keyboard shortcuts to make editing faster:
|
||||
|
||||
* Opening notes:
|
||||
* <kbd>Click</kbd> to open the note in the current tab.
|
||||
* <kbd>Ctrl</kbd>+<kbd>Click</kbd> or <kbd>Middle click</kbd> to open the note in a new tab.
|
||||
* <kbd>Ctrl</kbd>+<kbd>Right click</kbd> to open the note in <a class="reference-link" href="../../Navigation/Quick%20edit.md">Quick edit</a>.
|
||||
* Navigation within the tree:
|
||||
* <kbd>Up</kbd> and <kbd>Down</kbd> to navigate between notes.
|
||||
* <kbd>Left</kbd> to collapse a note, or <kbd>Right</kbd> to expand it.
|
||||
* Clipboard management:
|
||||
* <kbd>Ctrl</kbd>+<kbd>C</kbd> to copy a note.
|
||||
* <kbd>Ctrl</kbd>+<kbd>X</kbd> to cut a note.
|
||||
* <kbd>Ctrl</kbd>+<kbd>V</kbd> to paste it somewhere.
|
||||
* For <a class="reference-link" href="Multiple%20selection.md">Multiple selection</a>:
|
||||
* <kbd>Alt</kbd>+<kbd>Click</kbd>to add a single note to the current selection.
|
||||
* <kbd>Shift</kbd>+<kbd>Click</kbd>to select a range of notes, starting from the current note (the highlighted one) to the one that is being clicked.
|
||||
## Navigation within the tree
|
||||
|
||||
* <kbd><span>↑</span></kbd> and <kbd><span>↑</span></kbd> to navigate between notes.
|
||||
* <kbd><span>←</span></kbd> to collapse a note with children, or <kbd><span>→</span></kbd> to expand it.
|
||||
* <kbd><span>←</span></kbd> on a note with no children to navigate to its parent.
|
||||
|
||||
## Opening notes
|
||||
|
||||
* <kbd>Click</kbd> to open the note in the current tab.
|
||||
* <kbd>Ctrl</kbd>+<kbd>Click</kbd> or <kbd>Middle click</kbd> to open the note in a new tab.
|
||||
* <kbd>Ctrl</kbd>+<kbd>Right click</kbd> to open the note in <a class="reference-link" href="../../Navigation/Quick%20edit.md">Quick edit</a>.
|
||||
|
||||
## Clipboard management
|
||||
|
||||
* <kbd>Ctrl</kbd>+<kbd>C</kbd> to copy one or more notes based on selection (see <a class="reference-link" href="../../Notes/Cloning%20Notes.md">Cloning Notes</a>).
|
||||
* <kbd>Ctrl</kbd>+<kbd>X</kbd> to cut one or more notes (for moving them).
|
||||
* <kbd>Ctrl</kbd>+<kbd>V</kbd> to paste them somewhere (which results in a copy or move based on the shortcut used).
|
||||
|
||||
## Moving notes
|
||||
|
||||
* <kbd>Ctrl</kbd> + <kbd><span>↑</span></kbd> , <kbd>Ctrl</kbd> + <kbd><span>↓</span></kbd> - move note up/down in the note list.
|
||||
* <kbd>Ctrl</kbd> + <kbd><span>←</span></kbd> - move note up in the note tree.
|
||||
* <kbd>Ctrl</kbd>+<kbd><span>→</span></kbd> - move note down in the note tree.
|
||||
* <kbd>Del</kbd> - deletes note and optionally its subtree (asked in the dialog).
|
||||
|
||||
## Multiple selection
|
||||
|
||||
See <a class="reference-link" href="Multiple%20selection.md">Multiple selection</a> for more information about how selection works.
|
||||
|
||||
* <kbd>Alt</kbd>+<kbd>Click</kbd> – add a single note to the current selection.
|
||||
* <kbd>Shift</kbd>+<kbd>Click</kbd> – select a range of notes, starting from the current note (the highlighted one) to the one that is being clicked.
|
||||
* <kbd>Shift</kbd>+<kbd><span>↑</span></kbd>, <kbd>Shift</kbd>+<kbd><span>↓</span></kbd> – multi-select not above/below.
|
||||
* <kbd>Ctrl</kbd>+<kbd>A</kbd> – select all notes in the current level
|
||||
@ -84,7 +84,7 @@
|
||||
"url": "https://github.com/TriliumNext/Trilium/issues"
|
||||
},
|
||||
"homepage": "https://triliumnotes.org",
|
||||
"packageManager": "pnpm@10.23.0",
|
||||
"packageManager": "pnpm@10.24.0",
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@ckeditor/ckeditor5-mention": "patches/@ckeditor__ckeditor5-mention.patch",
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import "ckeditor5";
|
||||
import { type CreateNoteAction } from "@triliumnext/commons"
|
||||
|
||||
declare global {
|
||||
interface Component {
|
||||
@ -7,7 +8,8 @@ declare global {
|
||||
|
||||
interface EditorComponent extends Component {
|
||||
loadReferenceLinkTitle($el: JQuery<HTMLElement>, href: string): Promise<void>;
|
||||
createNoteForReferenceLink(title: string): Promise<string>;
|
||||
// Must Return Note Path
|
||||
createNoteFromCkEditor(title: string, parentNotePath: string | undefined, action: CreateNoteAction): Promise<string>;
|
||||
loadIncludedNote(noteId: string, $el: JQuery<HTMLElement>): void;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Command, Mention, Plugin, ModelRange, type ModelSelectable } from "ckeditor5";
|
||||
import { CreateNoteAction } from "@triliumnext/commons"
|
||||
|
||||
/**
|
||||
* Overrides the actions taken by the Mentions plugin (triggered by `@` in the text editor, or `~` & `#` in the attribute editor):
|
||||
@ -9,11 +10,11 @@ import { Command, Mention, Plugin, ModelRange, type ModelSelectable } from "cked
|
||||
*/
|
||||
export default class MentionCustomization extends Plugin {
|
||||
|
||||
static get requires() {
|
||||
static get requires() {
|
||||
return [ Mention ];
|
||||
}
|
||||
|
||||
public static get pluginName() {
|
||||
public static get pluginName() {
|
||||
return "MentionCustomization" as const;
|
||||
}
|
||||
|
||||
@ -25,20 +26,21 @@ export default class MentionCustomization extends Plugin {
|
||||
}
|
||||
|
||||
interface MentionOpts {
|
||||
mention: string | {
|
||||
id: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
marker: string;
|
||||
text?: string;
|
||||
range?: ModelRange;
|
||||
mention: string | {
|
||||
id: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
marker: string;
|
||||
text?: string;
|
||||
range?: ModelRange;
|
||||
}
|
||||
|
||||
interface MentionAttribute {
|
||||
id: string;
|
||||
action?: "create-note";
|
||||
noteTitle: string;
|
||||
notePath: string;
|
||||
id: string;
|
||||
action?: CreateNoteAction;
|
||||
noteTitle: string;
|
||||
notePath: string;
|
||||
parentNoteId?: string;
|
||||
}
|
||||
|
||||
class CustomMentionCommand extends Command {
|
||||
@ -56,14 +58,27 @@ class CustomMentionCommand extends Command {
|
||||
model.insertContent( writer.createText( mention.id, {} ), range );
|
||||
});
|
||||
}
|
||||
else if (mention.action === 'create-note') {
|
||||
const editorEl = this.editor.editing.view.getDomRoot();
|
||||
const component = glob.getComponentByEl<EditorComponent>(editorEl);
|
||||
else if (
|
||||
mention.action === CreateNoteAction.CreateNote ||
|
||||
mention.action === CreateNoteAction.CreateChildNote ||
|
||||
mention.action === CreateNoteAction.CreateAndLinkNote ||
|
||||
mention.action === CreateNoteAction.CreateAndLinkChildNote
|
||||
) {
|
||||
const editorEl = this.editor.editing.view.getDomRoot();
|
||||
const component = glob.getComponentByEl<EditorComponent>(editorEl);
|
||||
|
||||
component.createNoteForReferenceLink(mention.noteTitle).then(notePath => {
|
||||
this.insertReference(range, notePath);
|
||||
});
|
||||
}
|
||||
// use parentNoteId as fallback when notePath is missing
|
||||
const parentNotePath = mention.notePath || mention.parentNoteId;
|
||||
|
||||
component
|
||||
.createNoteFromCkEditor(mention.noteTitle, parentNotePath, mention.action)
|
||||
.then(notePath => {
|
||||
if (notePath) {
|
||||
this.insertReference(range, notePath);
|
||||
}
|
||||
})
|
||||
.catch(err => console.error("Error creating note from CKEditor mention:", err));
|
||||
}
|
||||
else {
|
||||
this.insertReference(range, mention.notePath);
|
||||
}
|
||||
|
||||
@ -2,9 +2,14 @@
|
||||
* https://github.com/TriliumNext/Trilium/issues/1002
|
||||
*/
|
||||
|
||||
import { Command, ModelDocumentSelection, ModelElement, ModelNode, Plugin, ModelRange } from 'ckeditor5';
|
||||
export default class MoveBlockUpDownPlugin extends Plugin {
|
||||
import { Command, ModelDocumentSelection, ModelElement, ModelNode, Plugin, ModelRange, _isMac, Editor } from 'ckeditor5';
|
||||
|
||||
const keyMap = {
|
||||
ArrowUp: 'moveBlockUp',
|
||||
ArrowDown: 'moveBlockDown'
|
||||
};
|
||||
|
||||
export default class MoveBlockUpDownPlugin extends Plugin {
|
||||
init() {
|
||||
const editor = this.editor;
|
||||
|
||||
@ -21,17 +26,14 @@ export default class MoveBlockUpDownPlugin extends Plugin {
|
||||
const domRoot = editor.editing.view.getDomRoot();
|
||||
if (!domRoot) return;
|
||||
|
||||
const isMac = _isMac(navigator.userAgent.toLowerCase());
|
||||
const handleKeydown = (e: KeyboardEvent) => {
|
||||
const keyMap = {
|
||||
ArrowUp: 'moveBlockUp',
|
||||
ArrowDown: 'moveBlockDown'
|
||||
};
|
||||
|
||||
const command = keyMap[e.key];
|
||||
const isCtrl = e.ctrlKey || e.metaKey;
|
||||
const hasModifier = (isCtrl || e.altKey) && !(isCtrl && e.altKey);
|
||||
if (!command) return;
|
||||
const isOnlyMeta = (!e.ctrlKey && !e.altKey && e.metaKey);
|
||||
const isOnlyAlt = (!e.ctrlKey && e.altKey && !e.metaKey);
|
||||
|
||||
if (command && hasModifier) {
|
||||
if ((!isMac && isOnlyMeta) || isOnlyAlt) {
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
editor.execute(command);
|
||||
@ -100,8 +102,7 @@ abstract class MoveBlockUpDownCommand extends Command {
|
||||
}
|
||||
writer.setSelection(range);
|
||||
this.editor.editing.view.focus();
|
||||
|
||||
this.scrollToSelection();
|
||||
scrollToSelection(this.editor);
|
||||
});
|
||||
}
|
||||
|
||||
@ -129,13 +130,6 @@ abstract class MoveBlockUpDownCommand extends Command {
|
||||
// Deduplicate adjacent duplicates (e.g., nested selections resolving to same block)
|
||||
return resolved.filter((blk, idx) => idx === 0 || blk !== resolved[idx - 1]);
|
||||
}
|
||||
|
||||
scrollToSelection() {
|
||||
// Ensure scroll happens in sync with DOM updates
|
||||
requestAnimationFrame(() => {
|
||||
this.editor.editing.view.scrollToTheSelection();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
class MoveBlockUpCommand extends MoveBlockUpDownCommand {
|
||||
@ -162,3 +156,10 @@ class MoveBlockDownCommand extends MoveBlockUpDownCommand {
|
||||
return "after" as const;
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToSelection(editor: Editor) {
|
||||
// Ensure scroll happens in sync with DOM updates
|
||||
requestAnimationFrame(() => {
|
||||
editor.editing.view.scrollToTheSelection();
|
||||
});
|
||||
};
|
||||
|
||||
@ -10,4 +10,5 @@ export * from "./lib/server_api.js";
|
||||
export * from "./lib/shared_constants.js";
|
||||
export * from "./lib/ws_api.js";
|
||||
export * from "./lib/attribute_names.js";
|
||||
export * from "./lib/create_note_actions.js";
|
||||
export * from "./lib/utils.js";
|
||||
|
||||
6
packages/commons/src/lib/create_note_actions.ts
Normal file
6
packages/commons/src/lib/create_note_actions.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export enum CreateNoteAction {
|
||||
CreateNote = "create-note",
|
||||
CreateChildNote = "create-child-note",
|
||||
CreateAndLinkNote = "create-and-link-note",
|
||||
CreateAndLinkChildNote = "create-and-link-child-note"
|
||||
}
|
||||
122
pnpm-lock.yaml
generated
122
pnpm-lock.yaml
generated
@ -90,7 +90,7 @@ importers:
|
||||
version: 7.0.1(eslint@9.39.1(jiti@2.6.1))
|
||||
happy-dom:
|
||||
specifier: ~20.0.0
|
||||
version: 20.0.10
|
||||
version: 20.0.11
|
||||
http-server:
|
||||
specifier: 14.1.1
|
||||
version: 14.1.1
|
||||
@ -129,7 +129,7 @@ importers:
|
||||
version: 4.5.4(@types/node@24.10.1)(rollup@4.52.0)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
|
||||
vitest:
|
||||
specifier: 4.0.14
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
|
||||
apps/build-docs:
|
||||
devDependencies:
|
||||
@ -339,8 +339,8 @@ importers:
|
||||
specifier: 13.0.1
|
||||
version: 13.0.1(webpack@5.101.3(esbuild@0.27.0))
|
||||
happy-dom:
|
||||
specifier: 20.0.10
|
||||
version: 20.0.10
|
||||
specifier: 20.0.11
|
||||
version: 20.0.11
|
||||
script-loader:
|
||||
specifier: 0.7.2
|
||||
version: 0.7.2
|
||||
@ -367,7 +367,7 @@ importers:
|
||||
dependencies:
|
||||
'@electron/remote':
|
||||
specifier: 2.1.3
|
||||
version: 2.1.3(electron@38.7.1)
|
||||
version: 2.1.3(electron@38.7.2)
|
||||
better-sqlite3:
|
||||
specifier: 12.4.6
|
||||
version: 12.4.6
|
||||
@ -424,8 +424,8 @@ importers:
|
||||
specifier: 13.0.1
|
||||
version: 13.0.1(webpack@5.101.3(esbuild@0.27.0))
|
||||
electron:
|
||||
specifier: 38.7.1
|
||||
version: 38.7.1
|
||||
specifier: 38.7.2
|
||||
version: 38.7.2
|
||||
prebuild-install:
|
||||
specifier: 7.1.3
|
||||
version: 7.1.3
|
||||
@ -480,8 +480,8 @@ importers:
|
||||
specifier: 13.0.1
|
||||
version: 13.0.1(webpack@5.101.3(esbuild@0.27.0))
|
||||
electron:
|
||||
specifier: 38.7.1
|
||||
version: 38.7.1
|
||||
specifier: 38.7.2
|
||||
version: 38.7.2
|
||||
fs-extra:
|
||||
specifier: 11.3.2
|
||||
version: 11.3.2
|
||||
@ -506,7 +506,7 @@ importers:
|
||||
version: 7.1.1
|
||||
'@electron/remote':
|
||||
specifier: 2.1.3
|
||||
version: 2.1.3(electron@38.7.1)
|
||||
version: 2.1.3(electron@38.7.2)
|
||||
'@preact/preset-vite':
|
||||
specifier: 2.10.2
|
||||
version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
|
||||
@ -649,8 +649,8 @@ importers:
|
||||
specifier: 3.1.10
|
||||
version: 3.1.10
|
||||
electron:
|
||||
specifier: 38.7.1
|
||||
version: 38.7.1
|
||||
specifier: 38.7.2
|
||||
version: 38.7.2
|
||||
electron-debug:
|
||||
specifier: 4.1.0
|
||||
version: 4.1.0
|
||||
@ -840,7 +840,7 @@ importers:
|
||||
version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
vitest:
|
||||
specifier: 4.0.14
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
|
||||
packages/ckeditor5:
|
||||
dependencies:
|
||||
@ -931,7 +931,7 @@ importers:
|
||||
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
|
||||
vitest:
|
||||
specifier: 4.0.14
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
webdriverio:
|
||||
specifier: 9.20.1
|
||||
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
@ -991,7 +991,7 @@ importers:
|
||||
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
|
||||
vitest:
|
||||
specifier: 4.0.14
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
webdriverio:
|
||||
specifier: 9.20.1
|
||||
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
@ -1051,7 +1051,7 @@ importers:
|
||||
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
|
||||
vitest:
|
||||
specifier: 4.0.14
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
webdriverio:
|
||||
specifier: 9.20.1
|
||||
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
@ -1118,7 +1118,7 @@ importers:
|
||||
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
|
||||
vitest:
|
||||
specifier: 4.0.14
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
webdriverio:
|
||||
specifier: 9.20.1
|
||||
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
@ -1185,7 +1185,7 @@ importers:
|
||||
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
|
||||
vitest:
|
||||
specifier: 4.0.14
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
webdriverio:
|
||||
specifier: 9.20.1
|
||||
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
@ -2336,11 +2336,11 @@ packages:
|
||||
engines: {node: '>=14.14'}
|
||||
hasBin: true
|
||||
|
||||
'@emnapi/core@1.7.0':
|
||||
resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==}
|
||||
'@emnapi/core@1.7.1':
|
||||
resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==}
|
||||
|
||||
'@emnapi/runtime@1.7.0':
|
||||
resolution: {integrity: sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==}
|
||||
'@emnapi/runtime@1.7.1':
|
||||
resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==}
|
||||
|
||||
'@emnapi/wasi-threads@1.1.0':
|
||||
resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==}
|
||||
@ -5448,6 +5448,9 @@ packages:
|
||||
'@types/node@20.19.24':
|
||||
resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==}
|
||||
|
||||
'@types/node@20.19.25':
|
||||
resolution: {integrity: sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==}
|
||||
|
||||
'@types/node@22.15.21':
|
||||
resolution: {integrity: sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==}
|
||||
|
||||
@ -5463,6 +5466,9 @@ packages:
|
||||
'@types/node@22.18.8':
|
||||
resolution: {integrity: sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==}
|
||||
|
||||
'@types/node@22.19.1':
|
||||
resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==}
|
||||
|
||||
'@types/node@24.10.1':
|
||||
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
|
||||
|
||||
@ -7242,6 +7248,9 @@ packages:
|
||||
csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
|
||||
csstype@3.2.3:
|
||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||
|
||||
custom-event@1.0.1:
|
||||
resolution: {integrity: sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==}
|
||||
|
||||
@ -7827,8 +7836,8 @@ packages:
|
||||
resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
electron@38.7.1:
|
||||
resolution: {integrity: sha512-mdFVpL80nZvIvajtl1Xz+2Q/a9tFGVnPO0YW/N+MqQUyZG8D9r3wrWoaEVBXTc1jI+Vkg77Eqqwh5FLiaYRI+A==}
|
||||
electron@38.7.2:
|
||||
resolution: {integrity: sha512-BcjR0IHqp3uv4ytVQwW2/9zAWo17Rjwrydn6RS+g+vqhpcPTzmBHDCHKaEcqheSl/7zzKPgFZdvT21BoSfrxRQ==}
|
||||
engines: {node: '>= 12.20.55'}
|
||||
hasBin: true
|
||||
|
||||
@ -8807,8 +8816,8 @@ packages:
|
||||
engines: {node: '>=0.4.7'}
|
||||
hasBin: true
|
||||
|
||||
happy-dom@20.0.10:
|
||||
resolution: {integrity: sha512-6umCCHcjQrhP5oXhrHQQvLB0bwb1UzHAHdsXy+FjtKoYjUhmNZsQL8NivwM1vDvNEChJabVrUYxUnp/ZdYmy2g==}
|
||||
happy-dom@20.0.11:
|
||||
resolution: {integrity: sha512-QsCdAUHAmiDeKeaNojb1OHOPF7NjcWPBR7obdu3NwH2a/oyQaLg5d0aaCy/9My6CdPChYF07dvz5chaXBGaD4g==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
has-bigints@1.1.0:
|
||||
@ -15769,6 +15778,8 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-core': 47.2.0
|
||||
'@ckeditor/ckeditor5-utils': 47.2.0
|
||||
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-code-block@47.2.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)':
|
||||
dependencies:
|
||||
@ -16029,6 +16040,8 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-utils': 47.2.0
|
||||
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
||||
es-toolkit: 1.39.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-editor-multi-root@47.2.0':
|
||||
dependencies:
|
||||
@ -16051,6 +16064,8 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-table': 47.2.0
|
||||
'@ckeditor/ckeditor5-utils': 47.2.0
|
||||
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-emoji@47.2.0':
|
||||
dependencies:
|
||||
@ -16076,8 +16091,6 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-core': 47.2.0
|
||||
'@ckeditor/ckeditor5-engine': 47.2.0
|
||||
'@ckeditor/ckeditor5-utils': 47.2.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-essentials@47.2.0':
|
||||
dependencies:
|
||||
@ -16537,6 +16550,8 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-ui': 47.2.0
|
||||
'@ckeditor/ckeditor5-utils': 47.2.0
|
||||
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-restricted-editing@47.2.0':
|
||||
dependencies:
|
||||
@ -17381,9 +17396,9 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@electron/remote@2.1.3(electron@38.7.1)':
|
||||
'@electron/remote@2.1.3(electron@38.7.2)':
|
||||
dependencies:
|
||||
electron: 38.7.1
|
||||
electron: 38.7.2
|
||||
|
||||
'@electron/universal@2.0.2':
|
||||
dependencies:
|
||||
@ -17407,13 +17422,13 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@emnapi/core@1.7.0':
|
||||
'@emnapi/core@1.7.1':
|
||||
dependencies:
|
||||
'@emnapi/wasi-threads': 1.1.0
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@emnapi/runtime@1.7.0':
|
||||
'@emnapi/runtime@1.7.1':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
@ -18122,7 +18137,7 @@ snapshots:
|
||||
'@inquirer/figures': 1.0.13
|
||||
'@inquirer/type': 2.0.0
|
||||
'@types/mute-stream': 0.0.4
|
||||
'@types/node': 22.18.13
|
||||
'@types/node': 22.19.1
|
||||
'@types/wrap-ansi': 3.0.0
|
||||
ansi-escapes: 4.3.2
|
||||
cli-width: 4.1.0
|
||||
@ -18700,8 +18715,8 @@ snapshots:
|
||||
|
||||
'@napi-rs/wasm-runtime@1.0.7':
|
||||
dependencies:
|
||||
'@emnapi/core': 1.7.0
|
||||
'@emnapi/runtime': 1.7.0
|
||||
'@emnapi/core': 1.7.1
|
||||
'@emnapi/runtime': 1.7.1
|
||||
'@tybys/wasm-util': 0.10.1
|
||||
optional: true
|
||||
|
||||
@ -20706,7 +20721,7 @@ snapshots:
|
||||
|
||||
'@types/mute-stream@0.0.4':
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/node-forge@1.3.14':
|
||||
dependencies:
|
||||
@ -20718,6 +20733,10 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@types/node@20.19.25':
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@types/node@22.15.21':
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
@ -20738,6 +20757,10 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@types/node@22.19.1':
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@types/node@24.10.1':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
@ -20761,7 +20784,7 @@ snapshots:
|
||||
|
||||
'@types/react@19.1.7':
|
||||
dependencies:
|
||||
csstype: 3.1.3
|
||||
csstype: 3.2.3
|
||||
optional: true
|
||||
|
||||
'@types/readdir-glob@1.1.5':
|
||||
@ -20887,7 +20910,7 @@ snapshots:
|
||||
|
||||
'@types/yauzl@2.10.3':
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.18.13
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)':
|
||||
@ -21117,7 +21140,7 @@ snapshots:
|
||||
'@vitest/browser-webdriverio@4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))':
|
||||
dependencies:
|
||||
'@vitest/browser': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
webdriverio: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
@ -21134,7 +21157,7 @@ snapshots:
|
||||
pngjs: 7.0.0
|
||||
sirv: 3.0.2
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
@ -21153,7 +21176,7 @@ snapshots:
|
||||
magicast: 0.5.1
|
||||
obug: 2.1.1
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -21170,7 +21193,7 @@ snapshots:
|
||||
obug: 2.1.1
|
||||
std-env: 3.10.0
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
optionalDependencies:
|
||||
'@vitest/browser': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)
|
||||
transitivePeerDependencies:
|
||||
@ -21220,7 +21243,7 @@ snapshots:
|
||||
sirv: 3.0.2
|
||||
tinyglobby: 0.2.15
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||
|
||||
'@vitest/utils@4.0.14':
|
||||
dependencies:
|
||||
@ -23086,6 +23109,9 @@ snapshots:
|
||||
|
||||
csstype@3.1.3: {}
|
||||
|
||||
csstype@3.2.3:
|
||||
optional: true
|
||||
|
||||
custom-event@1.0.1: {}
|
||||
|
||||
cytoscape-cose-bilkent@4.1.0(cytoscape@3.31.2):
|
||||
@ -23747,7 +23773,7 @@ snapshots:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
electron@38.7.1:
|
||||
electron@38.7.2:
|
||||
dependencies:
|
||||
'@electron/get': 2.0.3
|
||||
'@types/node': 22.18.13
|
||||
@ -25186,9 +25212,9 @@ snapshots:
|
||||
optionalDependencies:
|
||||
uglify-js: 3.19.3
|
||||
|
||||
happy-dom@20.0.10:
|
||||
happy-dom@20.0.11:
|
||||
dependencies:
|
||||
'@types/node': 20.19.24
|
||||
'@types/node': 20.19.25
|
||||
'@types/whatwg-mimetype': 3.0.2
|
||||
whatwg-mimetype: 3.0.0
|
||||
|
||||
@ -31767,7 +31793,7 @@ snapshots:
|
||||
tsx: 4.20.6
|
||||
yaml: 2.8.1
|
||||
|
||||
vitest@4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1):
|
||||
vitest@4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1):
|
||||
dependencies:
|
||||
'@vitest/expect': 4.0.14
|
||||
'@vitest/mocker': 4.0.14(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
|
||||
@ -31794,7 +31820,7 @@ snapshots:
|
||||
'@types/node': 24.10.1
|
||||
'@vitest/browser-webdriverio': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||
'@vitest/ui': 4.0.14(vitest@4.0.14)
|
||||
happy-dom: 20.0.10
|
||||
happy-dom: 20.0.11
|
||||
jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user