diff --git a/apps/client/src/components/app_context.ts b/apps/client/src/components/app_context.ts index 443014572..161846dde 100644 --- a/apps/client/src/components/app_context.ts +++ b/apps/client/src/components/app_context.ts @@ -261,7 +261,6 @@ export type CommandMappings = { // Geomap deleteFromMap: { noteId: string }; - openGeoLocation: { noteId: string; event: JQuery.MouseDownEvent }; toggleZenMode: CommandData; diff --git a/apps/client/src/components/note_context.ts b/apps/client/src/components/note_context.ts index 020817073..75c66b1bc 100644 --- a/apps/client/src/components/note_context.ts +++ b/apps/client/src/components/note_context.ts @@ -326,7 +326,7 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> } // Some book types must always display a note list, even if no children. - if (["calendar", "table"].includes(note.getLabelValue("viewType") ?? "")) { + if (["calendar", "table", "geoMap"].includes(note.getLabelValue("viewType") ?? "")) { return true; } diff --git a/apps/client/src/entities/fnote.ts b/apps/client/src/entities/fnote.ts index fd35c09b8..b5d575ed9 100644 --- a/apps/client/src/entities/fnote.ts +++ b/apps/client/src/entities/fnote.ts @@ -27,7 +27,6 @@ const NOTE_TYPE_ICONS = { doc: "bx bxs-file-doc", contentWidget: "bx bxs-widget", mindMap: "bx bx-sitemap", - geoMap: "bx bx-map-alt", aiChat: "bx bx-bot" }; @@ -36,7 +35,7 @@ const NOTE_TYPE_ICONS = { * end user. Those types should be used only for checking against, they are * not for direct use. */ -export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap" | "geoMap" | "aiChat"; +export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap" | "aiChat"; export interface NotePathRecord { isArchived: boolean; diff --git a/apps/client/src/services/link.ts b/apps/client/src/services/link.ts index 41533647c..a16f0bccf 100644 --- a/apps/client/src/services/link.ts +++ b/apps/client/src/services/link.ts @@ -277,13 +277,21 @@ function goToLink(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent) { return goToLinkExt(evt, hrefLink, $link); } -function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent, hrefLink: string | undefined, $link?: JQuery | null) { +/** + * Handles navigation to a link, which can be an internal note path (e.g., `#root/1234`) or an external URL (e.g., `https://example.com`). + * + * @param evt the event that triggered the link navigation, or `null` if the link was clicked programmatically. Used to determine if the link should be opened in a new tab/window, based on the button presses. + * @param hrefLink the link to navigate to, which can be a note path (e.g., `#root/1234`) or an external URL with any supported protocol (e.g., `https://example.com`). + * @param $link the jQuery element of the link that was clicked, used to determine if the link is an anchor link (e.g., `#fn1` or `#fnref1`) and to handle it accordingly. + * @returns `true` if the link was handled (i.e., the element was found and scrolled to), or a falsy value otherwise. + */ +function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent | null, hrefLink: string | undefined, $link?: JQuery | null) { if (hrefLink?.startsWith("data:")) { return true; } - evt.preventDefault(); - evt.stopPropagation(); + evt?.preventDefault(); + evt?.stopPropagation(); if (hrefLink && hrefLink.startsWith("#") && !hrefLink.startsWith("#root/") && $link) { if (handleAnchor(hrefLink, $link)) { @@ -293,14 +301,14 @@ function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent const { notePath, viewScope } = parseNavigationStateFromUrl(hrefLink); - const ctrlKey = utils.isCtrlKey(evt); - const shiftKey = evt.shiftKey; - const isLeftClick = "which" in evt && evt.which === 1; - const isMiddleClick = "which" in evt && evt.which === 2; + const ctrlKey = evt && utils.isCtrlKey(evt); + const shiftKey = evt?.shiftKey; + const isLeftClick = !evt || ("which" in evt && evt.which === 1); + const isMiddleClick = evt && "which" in evt && evt.which === 2; const targetIsBlank = ($link?.attr("target") === "_blank"); const openInNewTab = (isLeftClick && ctrlKey) || isMiddleClick || targetIsBlank; const activate = (isLeftClick && ctrlKey && shiftKey) || (isMiddleClick && shiftKey); - const openInNewWindow = isLeftClick && evt.shiftKey && !ctrlKey; + const openInNewWindow = isLeftClick && evt?.shiftKey && !ctrlKey; if (notePath) { if (openInNewWindow) { @@ -311,7 +319,7 @@ function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent viewScope }); } else if (isLeftClick) { - const ntxId = $(evt.target as any) + const ntxId = $(evt?.target as any) .closest("[data-ntx-id]") .attr("data-ntx-id"); diff --git a/apps/client/src/services/note_list_renderer.ts b/apps/client/src/services/note_list_renderer.ts index 3219d8d92..122ba9745 100644 --- a/apps/client/src/services/note_list_renderer.ts +++ b/apps/client/src/services/note_list_renderer.ts @@ -1,11 +1,12 @@ import type FNote from "../entities/fnote.js"; import CalendarView from "../widgets/view_widgets/calendar_view.js"; +import GeoView from "../widgets/view_widgets/geo_view/index.js"; import ListOrGridView from "../widgets/view_widgets/list_or_grid_view.js"; import TableView from "../widgets/view_widgets/table_view/index.js"; import type { ViewModeArgs } from "../widgets/view_widgets/view_mode.js"; import type ViewMode from "../widgets/view_widgets/view_mode.js"; -export type ViewTypeOptions = "list" | "grid" | "calendar" | "table"; +export type ViewTypeOptions = "list" | "grid" | "calendar" | "table" | "geoMap"; export default class NoteListRenderer { @@ -26,6 +27,9 @@ export default class NoteListRenderer { case "table": this.viewMode = new TableView(args); break; + case "geoMap": + this.viewMode = new GeoView(args); + break; default: this.viewMode = null; } @@ -34,7 +38,7 @@ export default class NoteListRenderer { #getViewType(parentNote: FNote): ViewTypeOptions { const viewType = parentNote.getLabelValue("viewType"); - if (!["list", "grid", "calendar", "table"].includes(viewType || "")) { + if (!["list", "grid", "calendar", "table", "geoMap"].includes(viewType || "")) { // when not explicitly set, decide based on the note type return parentNote.type === "search" ? "list" : "grid"; } else { diff --git a/apps/client/src/services/note_types.ts b/apps/client/src/services/note_types.ts index d35e7df8b..9f566f487 100644 --- a/apps/client/src/services/note_types.ts +++ b/apps/client/src/services/note_types.ts @@ -35,7 +35,6 @@ export const NOTE_TYPES: NoteTypeMapping[] = [ { type: "mermaid", mime: "text/mermaid", title: t("note_types.mermaid-diagram"), icon: "bx-selection" }, // Map notes - { type: "geoMap", mime: "application/json", title: t("note_types.geo-map"), icon: "bx-map-alt", isBeta: true }, { type: "mindMap", mime: "application/json", title: t("note_types.mind-map"), icon: "bx-sitemap" }, { type: "noteMap", mime: "", title: t("note_types.note-map"), icon: "bxs-network-chart", static: true }, { type: "relationMap", mime: "application/json", title: t("note_types.relation-map"), icon: "bxs-network-chart" }, @@ -61,7 +60,7 @@ export const NOTE_TYPES: NoteTypeMapping[] = [ const NEW_TEMPLATE_MAX_AGE = 3; /** The length of a day in milliseconds. */ -const DAY_LENGTH = 1000 * 60 * 60 * 24; +const DAY_LENGTH = 1000 * 60 * 60 * 24; /** The menu item badge used to mark new note types and templates */ const NEW_BADGE: MenuItemBadge = { diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index 1f992175c..00cb9f227 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -761,7 +761,8 @@ "book_properties": "Book Properties", "invalid_view_type": "Invalid view type '{{type}}'", "calendar": "Calendar", - "table": "Table" + "table": "Table", + "geo-map": "Geo Map" }, "edited_notes": { "no_edited_notes_found": "No edited notes on this day yet...", @@ -1859,7 +1860,8 @@ }, "geo-map-context": { "open-location": "Open location", - "remove-from-map": "Remove from map" + "remove-from-map": "Remove from map", + "add-note": "Add a marker at this location" }, "help-button": { "title": "Open the relevant help page" diff --git a/apps/client/src/widgets/buttons/note_actions.ts b/apps/client/src/widgets/buttons/note_actions.ts index 6989d8152..9bef36f3a 100644 --- a/apps/client/src/widgets/buttons/note_actions.ts +++ b/apps/client/src/widgets/buttons/note_actions.ts @@ -189,7 +189,7 @@ export default class NoteActionsWidget extends NoteContextAwareWidget { this.toggleDisabled(this.$findInTextButton, ["text", "code", "book", "mindMap"].includes(note.type)); this.toggleDisabled(this.$showAttachmentsButton, !isInOptions); - this.toggleDisabled(this.$showSourceButton, ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "geoMap"].includes(note.type)); + this.toggleDisabled(this.$showSourceButton, ["text", "code", "relationMap", "mermaid", "canvas", "mindMap"].includes(note.type)); const canPrint = ["text", "code"].includes(note.type); this.toggleDisabled(this.$printActiveNoteButton, canPrint); diff --git a/apps/client/src/widgets/floating_buttons/geo_map_button.ts b/apps/client/src/widgets/floating_buttons/geo_map_button.ts index 32b45d66c..7e59eeaf2 100644 --- a/apps/client/src/widgets/floating_buttons/geo_map_button.ts +++ b/apps/client/src/widgets/floating_buttons/geo_map_button.ts @@ -23,7 +23,9 @@ const TPL = /*html*/`\ export default class GeoMapButtons extends NoteContextAwareWidget { isEnabled() { - return super.isEnabled() && this.note?.type === "geoMap"; + return super.isEnabled() + && this.note?.getLabelValue("viewType") === "geoMap" + && !this.note.hasLabel("readOnly"); } doRender() { diff --git a/apps/client/src/widgets/floating_buttons/help_button.ts b/apps/client/src/widgets/floating_buttons/help_button.ts index f0403bfd7..31b031c9d 100644 --- a/apps/client/src/widgets/floating_buttons/help_button.ts +++ b/apps/client/src/widgets/floating_buttons/help_button.ts @@ -17,7 +17,6 @@ export const byNoteType: Record, string | null> = { contentWidget: null, doc: null, file: null, - geoMap: "81SGnPGMk7Xc", image: null, launcher: null, mermaid: null, @@ -35,7 +34,8 @@ export const byBookType: Record = { list: null, grid: null, calendar: "xWbu3jpNWapp", - table: "2FvYrpmOXm29" + table: "2FvYrpmOXm29", + geoMap: "81SGnPGMk7Xc" }; export default class ContextualHelpButton extends NoteContextAwareWidget { diff --git a/apps/client/src/widgets/floating_buttons/toggle_read_only_button.ts b/apps/client/src/widgets/floating_buttons/toggle_read_only_button.ts index f436c820c..571e99017 100644 --- a/apps/client/src/widgets/floating_buttons/toggle_read_only_button.ts +++ b/apps/client/src/widgets/floating_buttons/toggle_read_only_button.ts @@ -39,10 +39,20 @@ export default class ToggleReadOnlyButton extends OnClickButtonWidget { } isEnabled() { - return super.isEnabled() - && this.note?.type === "mermaid" - && this.note?.isContentAvailable() - && this.noteContext?.viewScope?.viewMode === "default"; + if (!super.isEnabled()) { + return false; + } + + if (!this?.note?.isContentAvailable()) { + return false; + } + + if (this.noteContext?.viewScope?.viewMode !== "default") { + return false; + } + + return this.note.type === "mermaid" || + (this.note.getLabelValue("viewType") === "geoMap"); } } diff --git a/apps/client/src/widgets/geo_map.ts b/apps/client/src/widgets/geo_map.ts deleted file mode 100644 index 14df22e3b..000000000 --- a/apps/client/src/widgets/geo_map.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { Map } from "leaflet"; -import L from "leaflet"; -import "leaflet/dist/leaflet.css"; -import NoteContextAwareWidget from "./note_context_aware_widget.js"; - -const TPL = /*html*/`\ -
- - -
-
`; - -export type Leaflet = typeof L; -export type InitCallback = (L: Leaflet) => void; - -export default class GeoMapWidget extends NoteContextAwareWidget { - - map?: Map; - $container!: JQuery; - private initCallback?: InitCallback; - - constructor(widgetMode: "type", initCallback?: InitCallback) { - super(); - this.initCallback = initCallback; - } - - doRender() { - this.$widget = $(TPL); - - this.$container = this.$widget.find(".geo-map-container"); - - const map = L.map(this.$container[0], { - worldCopyJump: true - }); - - this.map = map; - if (this.initCallback) { - this.initCallback(L); - } - - L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { - attribution: '© OpenStreetMap contributors', - detectRetina: true - }).addTo(map); - } -} diff --git a/apps/client/src/widgets/note_detail.ts b/apps/client/src/widgets/note_detail.ts index 3b232134a..334bea5fb 100644 --- a/apps/client/src/widgets/note_detail.ts +++ b/apps/client/src/widgets/note_detail.ts @@ -28,7 +28,6 @@ import ContentWidgetTypeWidget from "./type_widgets/content_widget.js"; import AttachmentListTypeWidget from "./type_widgets/attachment_list.js"; import AttachmentDetailTypeWidget from "./type_widgets/attachment_detail.js"; import MindMapWidget from "./type_widgets/mind_map.js"; -import GeoMapTypeWidget from "./type_widgets/geo_map.js"; import utils from "../services/utils.js"; import type { NoteType } from "../entities/fnote.js"; import type TypeWidget from "./type_widgets/type_widget.js"; @@ -71,7 +70,6 @@ const typeWidgetClasses = { attachmentDetail: AttachmentDetailTypeWidget, attachmentList: AttachmentListTypeWidget, mindMap: MindMapWidget, - geoMap: GeoMapTypeWidget, aiChat: AiChatTypeWidget, // Split type editors @@ -197,7 +195,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget { // https://github.com/zadam/trilium/issues/2522 const isBackendNote = this.noteContext?.noteId === "_backendLog"; const isSqlNote = this.mime === "text/x-sqlite;schema=trilium"; - const isFullHeightNoteType = ["canvas", "webView", "noteMap", "mindMap", "geoMap", "mermaid"].includes(this.type ?? ""); + const isFullHeightNoteType = ["canvas", "webView", "noteMap", "mindMap", "mermaid"].includes(this.type ?? ""); const isFullHeight = (!this.noteContext?.hasNoteList() && isFullHeightNoteType && !isSqlNote) || this.noteContext?.viewScope?.viewMode === "attachments" || isBackendNote; diff --git a/apps/client/src/widgets/note_list.ts b/apps/client/src/widgets/note_list.ts index 389aa82d3..afc31a66a 100644 --- a/apps/client/src/widgets/note_list.ts +++ b/apps/client/src/widgets/note_list.ts @@ -1,7 +1,7 @@ import NoteContextAwareWidget from "./note_context_aware_widget.js"; import NoteListRenderer from "../services/note_list_renderer.js"; import type FNote from "../entities/fnote.js"; -import type { CommandListener, CommandListenerData, CommandMappings, CommandNames, EventData } from "../components/app_context.js"; +import type { CommandListener, CommandListenerData, CommandMappings, CommandNames, EventData, EventNames } from "../components/app_context.js"; import type ViewMode from "./view_widgets/view_mode.js"; import AttributeDetailWidget from "./attribute_widgets/attribute_detail.js"; import { Attribute } from "../services/attribute_parser.js"; @@ -176,4 +176,17 @@ export default class NoteListWidget extends NoteContextAwareWidget { return super.triggerCommand(name, data); } + handleEventInChildren(name: T, data: EventData): Promise | null { + super.handleEventInChildren(name, data); + + if (this.viewMode) { + const ret = this.viewMode.handleEvent(name, data); + if (ret) { + return ret; + } + } + + return null; + } + } diff --git a/apps/client/src/widgets/note_tree.ts b/apps/client/src/widgets/note_tree.ts index 46abe10a0..1a9bb5ce6 100644 --- a/apps/client/src/widgets/note_tree.ts +++ b/apps/client/src/widgets/note_tree.ts @@ -186,6 +186,15 @@ interface RefreshContext { noteIdsToReload: Set; } +/** + * The information contained within a drag event. + */ +export interface DragData { + noteId: string; + branchId: string; + title: string; +} + export default class NoteTreeWidget extends NoteContextAwareWidget { private $tree!: JQuery; private $treeActions!: JQuery; diff --git a/apps/client/src/widgets/note_wrapper.ts b/apps/client/src/widgets/note_wrapper.ts index c8474075d..2e59cfbab 100644 --- a/apps/client/src/widgets/note_wrapper.ts +++ b/apps/client/src/widgets/note_wrapper.ts @@ -64,7 +64,7 @@ export default class NoteWrapperWidget extends FlexContainer { } #isFullWidthNote(note: FNote) { - if (["image", "mermaid", "book", "render", "canvas", "webView", "mindMap", "geoMap"].includes(note.type)) { + if (["image", "mermaid", "book", "render", "canvas", "webView", "mindMap"].includes(note.type)) { return true; } diff --git a/apps/client/src/widgets/ribbon_widgets/book_properties.ts b/apps/client/src/widgets/ribbon_widgets/book_properties.ts index cd9735b20..655512f9e 100644 --- a/apps/client/src/widgets/ribbon_widgets/book_properties.ts +++ b/apps/client/src/widgets/ribbon_widgets/book_properties.ts @@ -25,6 +25,7 @@ const TPL = /*html*/` + @@ -126,7 +127,7 @@ export default class BookPropertiesWidget extends NoteContextAwareWidget { return; } - if (!["list", "grid", "calendar", "table"].includes(type)) { + if (!["list", "grid", "calendar", "table", "geoMap"].includes(type)) { throw new Error(t("book_properties.invalid_view_type", { type })); } diff --git a/apps/client/src/widgets/type_widgets/book.ts b/apps/client/src/widgets/type_widgets/book.ts index 66d476464..cc8323e1f 100644 --- a/apps/client/src/widgets/type_widgets/book.ts +++ b/apps/client/src/widgets/type_widgets/book.ts @@ -47,6 +47,7 @@ export default class BookTypeWidget extends TypeWidget { switch (this.note?.getAttributeValue("label", "viewType")) { case "calendar": case "table": + case "geoMap": return false; default: return true; diff --git a/apps/client/src/widgets/type_widgets/geo_map.ts b/apps/client/src/widgets/type_widgets/geo_map.ts deleted file mode 100644 index 7f2b3e52a..000000000 --- a/apps/client/src/widgets/type_widgets/geo_map.ts +++ /dev/null @@ -1,447 +0,0 @@ -import { GPX, Marker, type LatLng, type LeafletMouseEvent } from "leaflet"; -import type FNote from "../../entities/fnote.js"; -import GeoMapWidget, { type InitCallback, type Leaflet } from "../geo_map.js"; -import TypeWidget from "./type_widget.js"; -import server from "../../services/server.js"; -import toastService from "../../services/toast.js"; -import dialogService from "../../services/dialog.js"; -import type { CommandListenerData, EventData } from "../../components/app_context.js"; -import { t } from "../../services/i18n.js"; -import attributes from "../../services/attributes.js"; -import openContextMenu from "./geo_map_context_menu.js"; -import link from "../../services/link.js"; -import note_tooltip from "../../services/note_tooltip.js"; -import appContext from "../../components/app_context.js"; - -import markerIcon from "leaflet/dist/images/marker-icon.png"; -import markerIconShadow from "leaflet/dist/images/marker-shadow.png"; -import { hasTouchBar } from "../../services/utils.js"; - -const TPL = /*html*/`\ -
- -
`; - -const LOCATION_ATTRIBUTE = "geolocation"; -const CHILD_NOTE_ICON = "bx bx-pin"; -const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659]; -const DEFAULT_ZOOM = 2; - -interface MapData { - view?: { - center?: LatLng | [number, number]; - zoom?: number; - }; -} - -// TODO: Deduplicate -interface CreateChildResponse { - note: { - noteId: string; - }; -} - -enum State { - Normal, - NewNote -} - -export default class GeoMapTypeWidget extends TypeWidget { - - private geoMapWidget: GeoMapWidget; - private _state: State; - private L!: Leaflet; - private currentMarkerData: Record; - private currentTrackData: Record; - private gpxLoaded?: boolean; - private ignoreNextZoomEvent?: boolean; - - static getType() { - return "geoMap"; - } - - constructor() { - super(); - - this.geoMapWidget = new GeoMapWidget("type", (L: Leaflet) => this.#onMapInitialized(L)); - this.currentMarkerData = {}; - this.currentTrackData = {}; - this._state = State.Normal; - - this.child(this.geoMapWidget); - } - - doRender() { - super.doRender(); - - this.$widget = $(TPL); - this.$widget.append(this.geoMapWidget.render()); - } - - async #onMapInitialized(L: Leaflet) { - this.L = L; - const map = this.geoMapWidget.map; - if (!map) { - throw new Error(t("geo-map.unable-to-load-map")); - } - - this.#restoreViewportAndZoom(); - - // Restore markers. - await this.#reloadMarkers(); - - // This fixes an issue with the map appearing cut off at the beginning, due to the container not being properly attached - setTimeout(() => { - map.invalidateSize(); - }, 100); - - const updateFn = () => this.spacedUpdate.scheduleUpdate(); - map.on("moveend", updateFn); - map.on("zoomend", updateFn); - map.on("click", (e) => this.#onMapClicked(e)); - - if (hasTouchBar) { - map.on("zoom", () => { - if (!this.ignoreNextZoomEvent) { - this.triggerCommand("refreshTouchBar"); - } - - this.ignoreNextZoomEvent = false; - }); - } - } - - async #restoreViewportAndZoom() { - const map = this.geoMapWidget.map; - if (!map || !this.note) { - return; - } - const blob = await this.note.getBlob(); - - let parsedContent: MapData = {}; - if (blob && blob.content) { - parsedContent = JSON.parse(blob.content); - } - - // Restore viewport position & zoom - const center = parsedContent.view?.center ?? DEFAULT_COORDINATES; - const zoom = parsedContent.view?.zoom ?? DEFAULT_ZOOM; - map.setView(center, zoom); - } - - async #reloadMarkers() { - if (!this.note) { - return; - } - - // Delete all existing markers - for (const marker of Object.values(this.currentMarkerData)) { - marker.remove(); - } - - // Delete all existing tracks - for (const track of Object.values(this.currentTrackData)) { - track.remove(); - } - - // Add the new markers. - this.currentMarkerData = {}; - const childNotes = await this.note.getChildNotes(); - for (const childNote of childNotes) { - if (childNote.mime === "application/gpx+xml") { - this.#processNoteWithGpxTrack(childNote); - continue; - } - - const latLng = childNote.getAttributeValue("label", LOCATION_ATTRIBUTE); - if (latLng) { - this.#processNoteWithMarker(childNote, latLng); - } - } - } - - async #processNoteWithGpxTrack(note: FNote) { - if (!this.L || !this.geoMapWidget.map) { - return; - } - - if (!this.gpxLoaded) { - await import("leaflet-gpx"); - this.gpxLoaded = true; - } - - const xmlResponse = await server.get(`notes/${note.noteId}/open`, undefined, true); - let stringResponse: string; - if (xmlResponse instanceof Uint8Array) { - stringResponse = new TextDecoder().decode(xmlResponse); - } else { - stringResponse = xmlResponse; - } - - const track = new this.L.GPX(stringResponse, { - markers: { - startIcon: this.#buildIcon(note.getIcon(), note.getColorClass(), note.title), - endIcon: this.#buildIcon("bxs-flag-checkered"), - wptIcons: { - "": this.#buildIcon("bx bx-pin") - } - }, - polyline_options: { - color: note.getLabelValue("color") ?? "blue" - } - }); - track.addTo(this.geoMapWidget.map); - this.currentTrackData[note.noteId] = track; - } - - #processNoteWithMarker(note: FNote, latLng: string) { - const map = this.geoMapWidget.map; - if (!map) { - return; - } - - const [lat, lng] = latLng.split(",", 2).map((el) => parseFloat(el)); - const L = this.L; - const icon = this.#buildIcon(note.getIcon(), note.getColorClass(), note.title); - - const marker = L.marker(L.latLng(lat, lng), { - icon, - draggable: true, - autoPan: true, - autoPanSpeed: 5 - }) - .addTo(map) - .on("moveend", (e) => { - this.moveMarker(note.noteId, (e.target as Marker).getLatLng()); - }); - marker.on("mousedown", ({ originalEvent }) => { - // Middle click to open in new tab - if (originalEvent.button === 1) { - const hoistedNoteId = this.hoistedNoteId; - //@ts-ignore, fix once tab manager is ported. - appContext.tabManager.openInNewTab(note.noteId, hoistedNoteId); - return true; - } - }); - marker.on("contextmenu", (e) => { - openContextMenu(note.noteId, e.originalEvent); - }); - - const el = marker.getElement(); - if (el) { - const $el = $(el); - $el.attr("data-href", `#${note.noteId}`); - note_tooltip.setupElementTooltip($($el)); - } - - this.currentMarkerData[note.noteId] = marker; - } - - #buildIcon(bxIconClass: string, colorClass?: string, title?: string) { - return this.L.divIcon({ - html: /*html*/`\ - - - - ${title ?? ""}`, - iconSize: [25, 41], - iconAnchor: [12, 41] - }); - } - - #changeState(newState: State) { - this._state = newState; - this.geoMapWidget.$container.toggleClass("placing-note", newState === State.NewNote); - if (hasTouchBar) { - this.triggerCommand("refreshTouchBar"); - } - } - - async #onMapClicked(e: LeafletMouseEvent) { - if (this._state !== State.NewNote) { - return; - } - - toastService.closePersistent("geo-new-note"); - const title = await dialogService.prompt({ message: t("relation_map.enter_title_of_new_note"), defaultValue: t("relation_map.default_new_note_title") }); - - if (title?.trim()) { - const { note } = await server.post(`notes/${this.noteId}/children?target=into`, { - title, - content: "", - type: "text" - }); - attributes.setLabel(note.noteId, "iconClass", CHILD_NOTE_ICON); - this.moveMarker(note.noteId, e.latlng); - } - - this.#changeState(State.Normal); - } - - async moveMarker(noteId: string, latLng: LatLng | null) { - const value = latLng ? [latLng.lat, latLng.lng].join(",") : ""; - await attributes.setLabel(noteId, LOCATION_ATTRIBUTE, value); - } - - getData(): any { - const map = this.geoMapWidget.map; - if (!map) { - return; - } - - const data: MapData = { - view: { - center: map.getBounds().getCenter(), - zoom: map.getZoom() - } - }; - - return { - content: JSON.stringify(data) - }; - } - - async geoMapCreateChildNoteEvent({ ntxId }: EventData<"geoMapCreateChildNote">) { - if (!this.isNoteContext(ntxId)) { - return; - } - - toastService.showPersistent({ - icon: "plus", - id: "geo-new-note", - title: "New note", - message: t("geo-map.create-child-note-instruction") - }); - - this.#changeState(State.NewNote); - - const globalKeyListener: (this: Window, ev: KeyboardEvent) => any = (e) => { - if (e.key !== "Escape") { - return; - } - - this.#changeState(State.Normal); - - window.removeEventListener("keydown", globalKeyListener); - toastService.closePersistent("geo-new-note"); - }; - window.addEventListener("keydown", globalKeyListener); - } - - async doRefresh(note: FNote) { - await this.geoMapWidget.refresh(); - this.#restoreViewportAndZoom(); - await this.#reloadMarkers(); - } - - entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { - // If any of the children branches are altered. - if (loadResults.getBranchRows().find((branch) => branch.parentNoteId === this.noteId)) { - this.#reloadMarkers(); - return; - } - - // If any of note has its location attribute changed. - // TODO: Should probably filter by parent here as well. - const attributeRows = loadResults.getAttributeRows(); - if (attributeRows.find((at) => [LOCATION_ATTRIBUTE, "color"].includes(at.name ?? ""))) { - this.#reloadMarkers(); - } - } - - openGeoLocationEvent({ noteId, event }: EventData<"openGeoLocation">) { - const marker = this.currentMarkerData[noteId]; - if (!marker) { - return; - } - - const latLng = this.currentMarkerData[noteId].getLatLng(); - const url = `geo:${latLng.lat},${latLng.lng}`; - link.goToLinkExt(event, url); - } - - deleteFromMapEvent({ noteId }: EventData<"deleteFromMap">) { - this.moveMarker(noteId, null); - } - - buildTouchBarCommand({ TouchBar }: CommandListenerData<"buildTouchBar">) { - const map = this.geoMapWidget.map; - const that = this; - if (!map) { - return; - } - - return [ - new TouchBar.TouchBarSlider({ - label: "Zoom", - value: map.getZoom(), - minValue: map.getMinZoom(), - maxValue: map.getMaxZoom(), - change(newValue) { - that.ignoreNextZoomEvent = true; - map.setZoom(newValue); - }, - }), - new TouchBar.TouchBarButton({ - label: "New geo note", - click: () => this.triggerCommand("geoMapCreateChildNote", { ntxId: this.ntxId }), - enabled: (this._state === State.Normal) - }) - ]; - } - -} diff --git a/apps/client/src/widgets/type_widgets/geo_map_context_menu.ts b/apps/client/src/widgets/type_widgets/geo_map_context_menu.ts deleted file mode 100644 index f19d655c4..000000000 --- a/apps/client/src/widgets/type_widgets/geo_map_context_menu.ts +++ /dev/null @@ -1,32 +0,0 @@ -import appContext from "../../components/app_context.js"; -import type { ContextMenuEvent } from "../../menus/context_menu.js"; -import contextMenu from "../../menus/context_menu.js"; -import linkContextMenu from "../../menus/link_context_menu.js"; -import { t } from "../../services/i18n.js"; - -export default function openContextMenu(noteId: string, e: ContextMenuEvent) { - contextMenu.show({ - x: e.pageX, - y: e.pageY, - items: [ - ...linkContextMenu.getItems(), - { title: t("geo-map-context.open-location"), command: "openGeoLocation", uiIcon: "bx bx-map-alt" }, - { title: "----" }, - { title: t("geo-map-context.remove-from-map"), command: "deleteFromMap", uiIcon: "bx bx-trash" } - ], - selectMenuItemHandler: ({ command }, e) => { - if (command === "deleteFromMap") { - appContext.triggerCommand(command, { noteId }); - return; - } - - if (command === "openGeoLocation") { - appContext.triggerCommand(command, { noteId, event: e }); - return; - } - - // Pass the events to the link context menu - linkContextMenu.handleLinkContextMenuItem(command, noteId); - } - }); -} diff --git a/apps/client/src/widgets/view_widgets/geo_view/context_menu.ts b/apps/client/src/widgets/view_widgets/geo_view/context_menu.ts new file mode 100644 index 000000000..26d91df27 --- /dev/null +++ b/apps/client/src/widgets/view_widgets/geo_view/context_menu.ts @@ -0,0 +1,85 @@ +import type { LatLng, LeafletMouseEvent } from "leaflet"; +import appContext, { type CommandMappings } from "../../../components/app_context.js"; +import contextMenu, { type MenuItem } from "../../../menus/context_menu.js"; +import linkContextMenu from "../../../menus/link_context_menu.js"; +import { t } from "../../../services/i18n.js"; +import { createNewNote } from "./editing.js"; +import { copyTextWithToast } from "../../../services/clipboard_ext.js"; +import link from "../../../services/link.js"; + +export default function openContextMenu(noteId: string, e: LeafletMouseEvent, isEditable: boolean) { + let items: MenuItem[] = [ + ...buildGeoLocationItem(e), + { title: "----" }, + ...linkContextMenu.getItems(), + ]; + + if (isEditable) { + items = [ + ...items, + { title: "----" }, + { title: t("geo-map-context.remove-from-map"), command: "deleteFromMap", uiIcon: "bx bx-trash" } + ]; + } + + contextMenu.show({ + x: e.originalEvent.pageX, + y: e.originalEvent.pageY, + items, + selectMenuItemHandler: ({ command }, e) => { + if (command === "deleteFromMap") { + appContext.triggerCommand(command, { noteId }); + return; + } + + // Pass the events to the link context menu + linkContextMenu.handleLinkContextMenuItem(command, noteId); + } + }); +} + +export function openMapContextMenu(noteId: string, e: LeafletMouseEvent, isEditable: boolean) { + let items: MenuItem[] = [ + ...buildGeoLocationItem(e) + ]; + + if (isEditable) { + items = [ + ...items, + { title: "----" }, + { + title: t("geo-map-context.add-note"), + handler: () => createNewNote(noteId, e), + uiIcon: "bx bx-plus" + } + ] + } + + contextMenu.show({ + x: e.originalEvent.pageX, + y: e.originalEvent.pageY, + items, + selectMenuItemHandler: () => { + // Nothing to do, as the commands handle themselves. + } + }); +} + +function buildGeoLocationItem(e: LeafletMouseEvent) { + function formatGeoLocation(latlng: LatLng, precision: number = 6) { + return `${latlng.lat.toFixed(precision)}, ${latlng.lng.toFixed(precision)}`; + } + + return [ + { + title: formatGeoLocation(e.latlng), + uiIcon: "bx bx-current-location", + handler: () => copyTextWithToast(formatGeoLocation(e.latlng, 15)) + }, + { + title: t("geo-map-context.open-location"), + uiIcon: "bx bx-map-alt", + handler: () => link.goToLinkExt(null, `geo:${e.latlng.lat},${e.latlng.lng}`) + } + ]; +} diff --git a/apps/client/src/widgets/view_widgets/geo_view/editing.ts b/apps/client/src/widgets/view_widgets/geo_view/editing.ts new file mode 100644 index 000000000..c9dd7368c --- /dev/null +++ b/apps/client/src/widgets/view_widgets/geo_view/editing.ts @@ -0,0 +1,80 @@ +import { LatLng, LeafletMouseEvent } from "leaflet"; +import attributes from "../../../services/attributes"; +import { LOCATION_ATTRIBUTE } from "./index.js"; +import dialog from "../../../services/dialog"; +import server from "../../../services/server"; +import { t } from "../../../services/i18n"; +import type { Map } from "leaflet"; +import type { DragData } from "../../note_tree.js"; +import froca from "../../../services/froca.js"; +import branches from "../../../services/branches.js"; + +const CHILD_NOTE_ICON = "bx bx-pin"; + +// TODO: Deduplicate +interface CreateChildResponse { + note: { + noteId: string; + }; +} + +export async function moveMarker(noteId: string, latLng: LatLng | null) { + const value = latLng ? [latLng.lat, latLng.lng].join(",") : ""; + await attributes.setLabel(noteId, LOCATION_ATTRIBUTE, value); +} + +export async function createNewNote(noteId: string, e: LeafletMouseEvent) { + const title = await dialog.prompt({ message: t("relation_map.enter_title_of_new_note"), defaultValue: t("relation_map.default_new_note_title") }); + + if (title?.trim()) { + const { note } = await server.post(`notes/${noteId}/children?target=into`, { + title, + content: "", + type: "text" + }); + attributes.setLabel(note.noteId, "iconClass", CHILD_NOTE_ICON); + moveMarker(note.noteId, e.latlng); + } +} + +export function setupDragging($container: JQuery, map: Map, mapNoteId: string) { + $container.on("dragover", (e) => { + // Allow drag. + e.preventDefault(); + }); + $container.on("drop", async (e) => { + if (!e.originalEvent) { + return; + } + + const data = e.originalEvent.dataTransfer?.getData('text'); + if (!data) { + return; + } + + try { + const parsedData = JSON.parse(data) as DragData[]; + if (!parsedData.length) { + return; + } + + const { noteId } = parsedData[0]; + + const offset = $container.offset(); + const x = e.originalEvent.clientX - (offset?.left ?? 0); + const y = e.originalEvent.clientY - (offset?.top ?? 0); + const latlng = map.containerPointToLatLng([ x, y ]); + + const note = await froca.getNote(noteId, true); + const parents = note?.getParentNoteIds(); + if (parents?.includes(mapNoteId)) { + await moveMarker(noteId, latlng); + } else { + await branches.cloneNoteToParentNote(noteId, mapNoteId); + await moveMarker(noteId, latlng); + } + } catch (e) { + console.warn(e); + } + }); +} diff --git a/apps/client/src/widgets/view_widgets/geo_view/index.ts b/apps/client/src/widgets/view_widgets/geo_view/index.ts new file mode 100644 index 000000000..41608dbc2 --- /dev/null +++ b/apps/client/src/widgets/view_widgets/geo_view/index.ts @@ -0,0 +1,331 @@ +import ViewMode, { ViewModeArgs } from "../view_mode.js"; +import L from "leaflet"; +import type { GPX, LatLng, LeafletMouseEvent, Map, Marker } from "leaflet"; +import "leaflet/dist/leaflet.css"; +import SpacedUpdate from "../../../services/spaced_update.js"; +import { t } from "../../../services/i18n.js"; +import processNoteWithMarker, { processNoteWithGpxTrack } from "./markers.js"; +import { hasTouchBar } from "../../../services/utils.js"; +import toast from "../../../services/toast.js"; +import { CommandListenerData, EventData } from "../../../components/app_context.js"; +import { createNewNote, moveMarker, setupDragging } from "./editing.js"; +import { openMapContextMenu } from "./context_menu.js"; + +const TPL = /*html*/` +
+ + +
+
`; + +interface MapData { + view?: { + center?: LatLng | [number, number]; + zoom?: number; + }; +} + +const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659]; +const DEFAULT_ZOOM = 2; +export const LOCATION_ATTRIBUTE = "geolocation"; + +enum State { + Normal, + NewNote +} + +export default class GeoView extends ViewMode { + + private $root: JQuery; + private $container!: JQuery; + private map?: Map; + private spacedUpdate: SpacedUpdate; + private _state: State; + private ignoreNextZoomEvent?: boolean; + + private currentMarkerData: Record; + private currentTrackData: Record; + + constructor(args: ViewModeArgs) { + super(args, "geoMap"); + this.$root = $(TPL); + this.$container = this.$root.find(".geo-map-container"); + this.spacedUpdate = new SpacedUpdate(() => this.onSave(), 5_000); + + this.currentMarkerData = {}; + this.currentTrackData = {}; + this._state = State.Normal; + + args.$parent.append(this.$root); + } + + async renderList() { + this.renderMap(); + return this.$root; + } + + async renderMap() { + const map = L.map(this.$container[0], { + worldCopyJump: true + }); + L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { + attribution: '© OpenStreetMap contributors', + detectRetina: true + }).addTo(map); + + this.map = map; + + this.#onMapInitialized(); + } + + async #onMapInitialized() { + const map = this.map; + if (!map) { + throw new Error(t("geo-map.unable-to-load-map")); + } + + this.#restoreViewportAndZoom(); + + const isEditable = !this.isReadOnly; + const updateFn = () => this.spacedUpdate.scheduleUpdate(); + map.on("moveend", updateFn); + map.on("zoomend", updateFn); + map.on("click", (e) => this.#onMapClicked(e)) + map.on("contextmenu", (e) => openMapContextMenu(this.parentNote.noteId, e, isEditable)); + + if (isEditable) { + setupDragging(this.$container, map, this.parentNote.noteId); + } + + this.#reloadMarkers(); + + if (hasTouchBar) { + map.on("zoom", () => { + if (!this.ignoreNextZoomEvent) { + this.triggerCommand("refreshTouchBar"); + } + + this.ignoreNextZoomEvent = false; + }); + } + } + + async #restoreViewportAndZoom() { + const map = this.map; + if (!map) { + return; + } + + const parsedContent = await this.viewStorage.restore(); + + // Restore viewport position & zoom + const center = parsedContent?.view?.center ?? DEFAULT_COORDINATES; + const zoom = parsedContent?.view?.zoom ?? DEFAULT_ZOOM; + map.setView(center, zoom); + } + + private onSave() { + const map = this.map; + let data: MapData = {}; + if (map) { + data = { + view: { + center: map.getBounds().getCenter(), + zoom: map.getZoom() + } + }; + } + + this.viewStorage.store(data); + } + + async #reloadMarkers() { + if (!this.map) { + return; + } + + // Delete all existing markers + for (const marker of Object.values(this.currentMarkerData)) { + marker.remove(); + } + + // Delete all existing tracks + for (const track of Object.values(this.currentTrackData)) { + track.remove(); + } + + // Add the new markers. + this.currentMarkerData = {}; + const notes = await this.parentNote.getChildNotes(); + const draggable = !this.isReadOnly; + for (const childNote of notes) { + if (childNote.mime === "application/gpx+xml") { + const track = await processNoteWithGpxTrack(this.map, childNote); + this.currentTrackData[childNote.noteId] = track; + continue; + } + + const latLng = childNote.getAttributeValue("label", LOCATION_ATTRIBUTE); + if (latLng) { + const marker = processNoteWithMarker(this.map, childNote, latLng, draggable); + this.currentMarkerData[childNote.noteId] = marker; + } + } + } + + get isFullHeight(): boolean { + return true; + } + + #changeState(newState: State) { + this._state = newState; + this.$container.toggleClass("placing-note", newState === State.NewNote); + if (hasTouchBar) { + this.triggerCommand("refreshTouchBar"); + } + } + + onEntitiesReloaded({ loadResults }: EventData<"entitiesReloaded">): boolean | void { + // If any of the children branches are altered. + if (loadResults.getBranchRows().find((branch) => branch.parentNoteId === this.parentNote.noteId)) { + this.#reloadMarkers(); + return; + } + + // If any of note has its location attribute changed. + // TODO: Should probably filter by parent here as well. + const attributeRows = loadResults.getAttributeRows(); + if (attributeRows.find((at) => [LOCATION_ATTRIBUTE, "color"].includes(at.name ?? ""))) { + this.#reloadMarkers(); + } + } + + async geoMapCreateChildNoteEvent({ ntxId }: EventData<"geoMapCreateChildNote">) { + toast.showPersistent({ + icon: "plus", + id: "geo-new-note", + title: "New note", + message: t("geo-map.create-child-note-instruction") + }); + + this.#changeState(State.NewNote); + + const globalKeyListener: (this: Window, ev: KeyboardEvent) => any = (e) => { + if (e.key !== "Escape") { + return; + } + + this.#changeState(State.Normal); + + window.removeEventListener("keydown", globalKeyListener); + toast.closePersistent("geo-new-note"); + }; + window.addEventListener("keydown", globalKeyListener); + } + + async #onMapClicked(e: LeafletMouseEvent) { + if (this._state !== State.NewNote) { + return; + } + + toast.closePersistent("geo-new-note"); + await createNewNote(this.parentNote.noteId, e); + this.#changeState(State.Normal); + } + + deleteFromMapEvent({ noteId }: EventData<"deleteFromMap">) { + moveMarker(noteId, null); + } + + buildTouchBarCommand({ TouchBar }: CommandListenerData<"buildTouchBar">) { + const map = this.map; + const that = this; + if (!map) { + return; + } + + return [ + new TouchBar.TouchBarSlider({ + label: "Zoom", + value: map.getZoom(), + minValue: map.getMinZoom(), + maxValue: map.getMaxZoom(), + change(newValue) { + that.ignoreNextZoomEvent = true; + map.setZoom(newValue); + }, + }), + new TouchBar.TouchBarButton({ + label: "New geo note", + click: () => this.triggerCommand("geoMapCreateChildNote"), + enabled: (this._state === State.Normal) + }) + ]; + } + +} diff --git a/apps/client/src/widgets/view_widgets/geo_view/markers.ts b/apps/client/src/widgets/view_widgets/geo_view/markers.ts new file mode 100644 index 000000000..448da11d9 --- /dev/null +++ b/apps/client/src/widgets/view_widgets/geo_view/markers.ts @@ -0,0 +1,92 @@ +import markerIcon from "leaflet/dist/images/marker-icon.png"; +import markerIconShadow from "leaflet/dist/images/marker-shadow.png"; +import { marker, latLng, divIcon, Map, type Marker } from "leaflet"; +import type FNote from "../../../entities/fnote.js"; +import openContextMenu from "./context_menu.js"; +import server from "../../../services/server.js"; +import { moveMarker } from "./editing.js"; +import appContext from "../../../components/app_context.js"; +import L from "leaflet"; + +let gpxLoaded = false; + +export default function processNoteWithMarker(map: Map, note: FNote, location: string, isEditable: boolean) { + const [lat, lng] = location.split(",", 2).map((el) => parseFloat(el)); + const icon = buildIcon(note.getIcon(), note.getColorClass(), note.title, note.noteId); + + const newMarker = marker(latLng(lat, lng), { + icon, + draggable: isEditable, + autoPan: true, + autoPanSpeed: 5 + }).addTo(map); + + if (isEditable) { + newMarker.on("moveend", (e) => { + moveMarker(note.noteId, (e.target as Marker).getLatLng()); + }); + } + + newMarker.on("mousedown", ({ originalEvent }) => { + // Middle click to open in new tab + if (originalEvent.button === 1) { + const hoistedNoteId = appContext.tabManager.getActiveContext()?.hoistedNoteId; + //@ts-ignore, fix once tab manager is ported. + appContext.tabManager.openInNewTab(note.noteId, hoistedNoteId); + return true; + } + }); + newMarker.on("contextmenu", (e) => { + openContextMenu(note.noteId, e, isEditable); + }); + + return newMarker; +} + +export async function processNoteWithGpxTrack(map: Map, note: FNote) { + if (!gpxLoaded) { + const GPX = await import("leaflet-gpx"); + gpxLoaded = true; + } + + const xmlResponse = await server.get(`notes/${note.noteId}/open`, undefined, true); + let stringResponse: string; + if (xmlResponse instanceof Uint8Array) { + stringResponse = new TextDecoder().decode(xmlResponse); + } else { + stringResponse = xmlResponse; + } + + const track = new L.GPX(stringResponse, { + markers: { + startIcon: buildIcon(note.getIcon(), note.getColorClass(), note.title), + endIcon: buildIcon("bxs-flag-checkered"), + wptIcons: { + "": buildIcon("bx bx-pin") + } + }, + polyline_options: { + color: note.getLabelValue("color") ?? "blue" + } + }); + track.addTo(map); + return track; +} + +function buildIcon(bxIconClass: string, colorClass?: string, title?: string, noteIdLink?: string) { + let html = /*html*/`\ + + + + ${title ?? ""}`; + + if (noteIdLink) { + html = `
${html}
`; + } + + return divIcon({ + html, + iconSize: [25, 41], + iconAnchor: [12, 41] + }); +} diff --git a/apps/client/src/widgets/view_widgets/view_mode.ts b/apps/client/src/widgets/view_widgets/view_mode.ts index 350b84dcb..f3706da4a 100644 --- a/apps/client/src/widgets/view_widgets/view_mode.ts +++ b/apps/client/src/widgets/view_widgets/view_mode.ts @@ -44,12 +44,16 @@ export default abstract class ViewMode extends Component { return false; } + get isReadOnly() { + return this.parentNote.hasLabel("readOnly"); + } + get viewStorage() { if (this._viewStorage) { return this._viewStorage; } - this._viewStorage = new ViewModeStorage(this.parentNote, this.viewType); + this._viewStorage = new ViewModeStorage(this.parentNote, this.viewType); return this._viewStorage; } diff --git a/apps/client/src/widgets/view_widgets/view_mode_storage.ts b/apps/client/src/widgets/view_widgets/view_mode_storage.ts index 750e9d9b0..b3bf6bda2 100644 --- a/apps/client/src/widgets/view_widgets/view_mode_storage.ts +++ b/apps/client/src/widgets/view_widgets/view_mode_storage.ts @@ -26,18 +26,19 @@ export default class ViewModeStorage { } async restore() { - const existingAttachments = await this.note.getAttachmentsByRole(ATTACHMENT_ROLE); + const existingAttachments = (await this.note.getAttachmentsByRole(ATTACHMENT_ROLE)) + .filter(a => a.title === this.attachmentName); if (existingAttachments.length === 0) { return undefined; } - const attachment = existingAttachments - .find(a => a.title === this.attachmentName); - if (!attachment) { - return undefined; + if (existingAttachments.length > 1) { + // Clean up duplicates. + await Promise.all(existingAttachments.slice(1).map(async a => await server.remove(`attachments/${a.attachmentId}`))); } + const attachment = existingAttachments[0]; const attachmentData = await server.get<{ content: string } | null>(`attachments/${attachment.attachmentId}/blob`); - return JSON.parse(attachmentData?.content ?? "{}"); + return JSON.parse(attachmentData?.content ?? "{}") as T; } } diff --git a/apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json b/apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json index 019816cef..404832e1d 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json +++ b/apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json @@ -1 +1 @@ -[{"id":"_help_Otzi9La2YAUX","title":"Installation & Setup","type":"book","attributes":[{"name":"iconClass","value":"bx bx-cog","type":"label"}],"children":[{"id":"_help_poXkQfguuA0U","title":"Desktop Installation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_WOcw2SLH6tbX","title":"Server Installation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_Dgg7bR3b6K9j","title":"1. Installing the server","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_3tW6mORuTHnB","title":"Packaged version for Linux","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]},{"id":"_help_rWX5eY045zbE","title":"Using Docker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker"},{"name":"iconClass","value":"bx bxl-docker","type":"label"}]},{"id":"_help_moVgBcoxE3EK","title":"On NixOS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/On NixOS"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]},{"id":"_help_J1Bb6lVlwU5T","title":"Manually","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}]},{"id":"_help_DCmT6e7clMoP","title":"Using Kubernetes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Kubernetes"},{"name":"iconClass","value":"bx bxl-kubernetes","type":"label"}]},{"id":"_help_klCWNks3ReaQ","title":"Multiple server instances","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Multiple server instances"},{"name":"iconClass","value":"bx bxs-user-account","type":"label"}]}]},{"id":"_help_vcjrb3VVYPZI","title":"2. Reverse proxy","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_ud6MShXL4WpO","title":"Nginx","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_fDLvzOx29Pfg","title":"Apache","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_l2VkvOwUNfZj","title":"TLS Configuration","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/TLS Configuration"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_0hzsNCP31IAB","title":"Authentication","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Authentication"},{"name":"iconClass","value":"bx bx-lock-alt","type":"label"}]},{"id":"_help_7DAiwaf8Z7Rz","title":"Multi-Factor Authentication","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication"},{"name":"iconClass","value":"bx bx-stopwatch","type":"label"}]}]},{"id":"_help_cbkrhQjrkKrh","title":"Synchronization","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Synchronization"},{"name":"iconClass","value":"bx bx-sync","type":"label"}]},{"id":"_help_RDslemsQ6gCp","title":"Mobile Frontend","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Mobile Frontend"},{"name":"iconClass","value":"bx bx-mobile-alt","type":"label"}]},{"id":"_help_MtPxeAWVAzMg","title":"Web Clipper","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Web Clipper"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_n1lujUxCwipy","title":"Upgrading TriliumNext","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Upgrading TriliumNext"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_ODY7qQn5m2FT","title":"Backup","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Backup"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_tAassRL4RSQL","title":"Data directory","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Data directory"},{"name":"iconClass","value":"bx bx-folder-open","type":"label"}]}]},{"id":"_help_gh7bpGYxajRS","title":"Basic Concepts and Features","type":"book","attributes":[{"name":"iconClass","value":"bx bx-help-circle","type":"label"}],"children":[{"id":"_help_Vc8PjrjAGuOp","title":"UI Elements","type":"book","attributes":[{"name":"iconClass","value":"bx bx-window-alt","type":"label"}],"children":[{"id":"_help_x0JgW8UqGXvq","title":"Vertical and horizontal layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Vertical and horizontal layout"},{"name":"iconClass","value":"bx bxs-layout","type":"label"}]},{"id":"_help_x3i7MxGccDuM","title":"Global menu","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Global menu"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_oPVyFC7WL2Lp","title":"Note Tree","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree"},{"name":"iconClass","value":"bx bxs-tree-alt","type":"label"}],"children":[{"id":"_help_YtSN43OrfzaA","title":"Note tree contextual menu","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_yTjUdsOi4CIE","title":"Multiple selection","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Multiple selection"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]}]},{"id":"_help_BlN9DFI679QC","title":"Ribbon","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon"},{"name":"iconClass","value":"bx bx-dots-horizontal","type":"label"}]},{"id":"_help_3seOhtN8uLIY","title":"Tabs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs"},{"name":"iconClass","value":"bx bx-dock-top","type":"label"}]},{"id":"_help_xYmIYSP6wE3F","title":"Launch Bar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Launch Bar"},{"name":"iconClass","value":"bx bx-sidebar","type":"label"}]},{"id":"_help_8YBEPzcpUgxw","title":"Note buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons"},{"name":"iconClass","value":"bx bx-dots-vertical-rounded","type":"label"}]},{"id":"_help_4TIF1oA4VQRO","title":"Options","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Options"},{"name":"iconClass","value":"bx bx-cog","type":"label"}]},{"id":"_help_luNhaphA37EO","title":"Split View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View"},{"name":"iconClass","value":"bx bx-dock-right","type":"label"}]},{"id":"_help_XpOYSgsLkTJy","title":"Floating buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Floating buttons"},{"name":"iconClass","value":"bx bx-rectangle","type":"label"}]},{"id":"_help_RnaPdbciOfeq","title":"Right Sidebar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Right Sidebar"},{"name":"iconClass","value":"bx bxs-dock-right","type":"label"}]},{"id":"_help_r5JGHN99bVKn","title":"Recent Changes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Recent Changes"},{"name":"iconClass","value":"bx bx-history","type":"label"}]},{"id":"_help_ny318J39E5Z0","title":"Zoom","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom"},{"name":"iconClass","value":"bx bx-zoom-in","type":"label"}]}]},{"id":"_help_BFs8mudNFgCS","title":"Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes"},{"name":"iconClass","value":"bx bx-notepad","type":"label"}],"children":[{"id":"_help_p9kXRFAkwN4o","title":"Note Icons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note Icons"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_0vhv7lsOLy82","title":"Attachments","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Attachments"},{"name":"iconClass","value":"bx bx-paperclip","type":"label"}]},{"id":"_help_IakOLONlIfGI","title":"Cloning Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Cloning Notes"},{"name":"iconClass","value":"bx bx-duplicate","type":"label"}],"children":[{"id":"_help_TBwsyfadTA18","title":"Branch prefix","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Cloning Notes/Branch prefix"},{"name":"iconClass","value":"bx bx-rename","type":"label"}]}]},{"id":"_help_bwg0e8ewQMak","title":"Protected Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Protected Notes"},{"name":"iconClass","value":"bx bx-lock-alt","type":"label"}]},{"id":"_help_MKmLg5x6xkor","title":"Archived Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Archived Notes"},{"name":"iconClass","value":"bx bx-box","type":"label"}]},{"id":"_help_vZWERwf8U3nx","title":"Note Revisions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note Revisions"},{"name":"iconClass","value":"bx bx-history","type":"label"}]},{"id":"_help_aGlEvb9hyDhS","title":"Sorting Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Sorting Notes"},{"name":"iconClass","value":"bx bx-sort-up","type":"label"}]},{"id":"_help_NRnIZmSMc5sj","title":"Export as PDF","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Export as PDF"},{"name":"iconClass","value":"bx bxs-file-pdf","type":"label"}]},{"id":"_help_CoFPLs3dRlXc","title":"Read-Only Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes"},{"name":"iconClass","value":"bx bx-edit-alt","type":"label"}]},{"id":"_help_0ESUbbAxVnoK","title":"Note List","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}],"children":[{"id":"_help_xWbu3jpNWapp","title":"Calendar View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Calendar View"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]},{"id":"_help_2FvYrpmOXm29","title":"Table","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]}]},{"id":"_help_wArbEsdSae6g","title":"Navigation","type":"book","attributes":[{"name":"iconClass","value":"bx bx-navigation","type":"label"}],"children":[{"id":"_help_kBrnXNG3Hplm","title":"Tree Concepts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Tree Concepts"},{"name":"iconClass","value":"bx bx-pyramid","type":"label"}]},{"id":"_help_MMiBEQljMQh2","title":"Note Navigation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Note Navigation"},{"name":"iconClass","value":"bx bxs-navigation","type":"label"}]},{"id":"_help_Ms1nauBra7gq","title":"Quick search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Quick search"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]},{"id":"_help_F1r9QtzQLZqm","title":"Jump to Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Jump to Note"},{"name":"iconClass","value":"bx bx-send","type":"label"}]},{"id":"_help_eIg8jdvaoNNd","title":"Search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Search"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]},{"id":"_help_u3YFHC9tQlpm","title":"Bookmarks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks"},{"name":"iconClass","value":"bx bx-bookmarks","type":"label"}]},{"id":"_help_OR8WJ7Iz9K4U","title":"Note Hoisting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Note Hoisting"},{"name":"iconClass","value":"bx bxs-chevrons-up","type":"label"}]},{"id":"_help_9sRHySam5fXb","title":"Workspaces","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Workspaces"},{"name":"iconClass","value":"bx bx-door-open","type":"label"}]},{"id":"_help_xWtq5NUHOwql","title":"Similar Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Similar Notes"},{"name":"iconClass","value":"bx bx-bar-chart","type":"label"}]},{"id":"_help_McngOG2jbUWX","title":"Search in note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Search in note"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]}]},{"id":"_help_A9Oc6YKKc65v","title":"Keyboard Shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Keyboard Shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_Wy267RK4M69c","title":"Themes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes"},{"name":"iconClass","value":"bx bx-palette","type":"label"}],"children":[{"id":"_help_VbjZvtUek0Ln","title":"Theme Gallery","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes/Theme Gallery"},{"name":"iconClass","value":"bx bx-book-reader","type":"label"}]}]},{"id":"_help_mHbBMPDPkVV5","title":"Import & Export","type":"book","attributes":[{"name":"iconClass","value":"bx bx-import","type":"label"}],"children":[{"id":"_help_Oau6X9rCuegd","title":"Markdown","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Markdown"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}],"children":[{"id":"_help_rJ9grSgoExl9","title":"Supported syntax","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Markdown/Supported syntax"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}]}]},{"id":"_help_syuSEKf2rUGr","title":"Evernote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_GnhlmrATVqcH","title":"OneNote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/OneNote"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_rC3pL2aptaRE","title":"Zen mode","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Zen mode"},{"name":"iconClass","value":"bx bxs-yin-yang","type":"label"}]}]},{"id":"_help_s3YCWHBfmYuM","title":"Quick Start","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Quick Start"},{"name":"iconClass","value":"bx bx-run","type":"label"}]},{"id":"_help_i6dbnitykE5D","title":"FAQ","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/FAQ"},{"name":"iconClass","value":"bx bx-question-mark","type":"label"}]},{"id":"_help_KSZ04uQ2D1St","title":"Note Types","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types"},{"name":"iconClass","value":"bx bx-edit","type":"label"}],"children":[{"id":"_help_iPIMuisry3hd","title":"Text","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text"},{"name":"iconClass","value":"bx bx-note","type":"label"}],"children":[{"id":"_help_NwBbFdNZ9h7O","title":"Block quotes & admonitions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Block quotes & admonitions"},{"name":"iconClass","value":"bx bx-info-circle","type":"label"}]},{"id":"_help_oSuaNgyyKnhu","title":"Bookmarks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Bookmarks"},{"name":"iconClass","value":"bx bx-bookmark","type":"label"}]},{"id":"_help_veGu4faJErEM","title":"Content language & Right-to-left support","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Content language & Right-to-le"},{"name":"iconClass","value":"bx bx-align-right","type":"label"}]},{"id":"_help_2x0ZAX9ePtzV","title":"Cut to subnote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Cut to subnote"},{"name":"iconClass","value":"bx bx-cut","type":"label"}]},{"id":"_help_UYuUB1ZekNQU","title":"Developer-specific formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Developer-specific formatting"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}],"children":[{"id":"_help_QxEyIjRBizuC","title":"Code blocks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks"},{"name":"iconClass","value":"bx bx-code","type":"label"}]}]},{"id":"_help_AgjCISero73a","title":"Footnotes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Footnotes"},{"name":"iconClass","value":"bx bx-bracket","type":"label"}]},{"id":"_help_nRhnJkTT8cPs","title":"Formatting toolbar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Formatting toolbar"},{"name":"iconClass","value":"bx bx-text","type":"label"}]},{"id":"_help_Gr6xFaF6ioJ5","title":"General formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/General formatting"},{"name":"iconClass","value":"bx bx-bold","type":"label"}]},{"id":"_help_AxshuNRegLAv","title":"Highlights list","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Highlights list"},{"name":"iconClass","value":"bx bx-highlight","type":"label"}]},{"id":"_help_mT0HEkOsz6i1","title":"Images","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Images"},{"name":"iconClass","value":"bx bx-image-alt","type":"label"}],"children":[{"id":"_help_0Ofbk1aSuVRu","title":"Image references","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Images/Image references"},{"name":"iconClass","value":"bx bxs-file-image","type":"label"}]}]},{"id":"_help_nBAXQFj20hS1","title":"Include Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Include Note"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_CohkqWQC1iBv","title":"Insert buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Insert buttons"},{"name":"iconClass","value":"bx bx-plus","type":"label"}]},{"id":"_help_oiVPnW8QfnvS","title":"Keyboard shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Keyboard shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_QEAPj01N5f7w","title":"Links","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Links"},{"name":"iconClass","value":"bx bx-link-alt","type":"label"}]},{"id":"_help_S6Xx8QIWTV66","title":"Lists","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Lists"},{"name":"iconClass","value":"bx bx-list-ul","type":"label"}]},{"id":"_help_QrtTYPmdd1qq","title":"Markdown-like formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Markdown-like formatting"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}]},{"id":"_help_YfYAtQBcfo5V","title":"Math Equations","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Math Equations"},{"name":"iconClass","value":"bx bx-math","type":"label"}]},{"id":"_help_dEHYtoWWi8ct","title":"Other features","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Other features"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_gLt3vA97tMcp","title":"Premium features","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features"},{"name":"iconClass","value":"bx bx-star","type":"label"}],"children":[{"id":"_help_ZlN4nump6EbW","title":"Slash Commands","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Slash Commands"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_pwc194wlRzcH","title":"Text Snippets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Text Snippets"},{"name":"iconClass","value":"bx bx-align-left","type":"label"}]}]},{"id":"_help_BFvAtE74rbP6","title":"Table of contents","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Table of contents"},{"name":"iconClass","value":"bx bx-heading","type":"label"}]},{"id":"_help_NdowYOC1GFKS","title":"Tables","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Tables"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]},{"id":"_help_6f9hih2hXXZk","title":"Code","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Code"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_m523cpzocqaD","title":"Saved Search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Saved Search"},{"name":"iconClass","value":"bx bx-file-find","type":"label"}]},{"id":"_help_iRwzGnHPzonm","title":"Relation Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Relation Map"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_bdUJEHsAPYQR","title":"Note Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Note Map"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_HcABDtFCkbFN","title":"Render Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Render Note"},{"name":"iconClass","value":"bx bx-extension","type":"label"}]},{"id":"_help_GTwFsgaA0lCt","title":"Book","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Book"},{"name":"iconClass","value":"bx bx-book","type":"label"}]},{"id":"_help_s1aBHPd79XYj","title":"Mermaid Diagrams","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mermaid Diagrams"},{"name":"iconClass","value":"bx bx-selection","type":"label"}],"children":[{"id":"_help_RH6yLjjWJHof","title":"ELK layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mermaid Diagrams/ELK layout"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]}]},{"id":"_help_grjYqerjn243","title":"Canvas","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Canvas"},{"name":"iconClass","value":"bx bx-pen","type":"label"}]},{"id":"_help_1vHRoWCEjj0L","title":"Web View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Web View"},{"name":"iconClass","value":"bx bx-globe-alt","type":"label"}]},{"id":"_help_gBbsAeiuUxI5","title":"Mind Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mind Map"},{"name":"iconClass","value":"bx bx-sitemap","type":"label"}]},{"id":"_help_81SGnPGMk7Xc","title":"Geo Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Geo Map"},{"name":"iconClass","value":"bx bx-map-alt","type":"label"}]},{"id":"_help_W8vYD3Q1zjCR","title":"File","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/File"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_BgmBlOIl72jZ","title":"Troubleshooting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting"},{"name":"iconClass","value":"bx bx-bug","type":"label"}],"children":[{"id":"_help_wy8So3yZZlH9","title":"Reporting issues","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Reporting issues"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_x59R8J8KV5Bp","title":"Anonymized Database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Anonymized Database"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_qzNzp9LYQyPT","title":"Error logs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Error logs"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_vdlYGAcpXAgc","title":"Synchronization fails with 504 Gateway Timeout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Synchronization fails with 504"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_s8alTXmpFR61","title":"Refreshing the application","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Refreshing the application"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_pKK96zzmvBGf","title":"Theme development","type":"book","attributes":[{"name":"iconClass","value":"bx bx-palette","type":"label"}],"children":[{"id":"_help_7NfNr5pZpVKV","title":"Creating a custom theme","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Creating a custom theme"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_WFGzWeUK6arS","title":"Customize the Next theme","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Customize the Next theme"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_WN5z4M8ASACJ","title":"Reference","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Reference"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_AlhDUqhENtH7","title":"Custom app-wide CSS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Custom app-wide CSS"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_tC7s2alapj8V","title":"Advanced Usage","type":"book","attributes":[{"name":"iconClass","value":"bx bx-rocket","type":"label"}],"children":[{"id":"_help_zEY4DaJG4YT5","title":"Attributes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes"},{"name":"iconClass","value":"bx bx-list-check","type":"label"}],"children":[{"id":"_help_HI6GBBIduIgv","title":"Labels","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Labels"},{"name":"iconClass","value":"bx bx-hash","type":"label"}]},{"id":"_help_Cq5X6iKQop6R","title":"Relations","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Relations"},{"name":"iconClass","value":"bx bx-transfer","type":"label"}]},{"id":"_help_bwZpz2ajCEwO","title":"Attribute Inheritance","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Attribute Inheritance"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_OFXdgB2nNk1F","title":"Promoted Attributes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]},{"id":"_help_KC1HB96bqqHX","title":"Templates","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Templates"},{"name":"iconClass","value":"bx bx-copy","type":"label"}]},{"id":"_help_BCkXAVs63Ttv","title":"Note Map (Link map, Tree map)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note Map (Link map, Tree map)"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_R9pX4DGra2Vt","title":"Sharing","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing"},{"name":"iconClass","value":"bx bx-share-alt","type":"label"}],"children":[{"id":"_help_Qjt68inQ2bRj","title":"Serving directly the content of a note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing/Serving directly the content o"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_5668rwcirq1t","title":"Advanced Showcases","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_l0tKav7yLHGF","title":"Day Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Day Notes"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]},{"id":"_help_R7abl2fc6Mxi","title":"Weight Tracker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Weight Tracker"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_xYjQUYhpbUEW","title":"Task Manager","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Task Manager"},{"name":"iconClass","value":"bx bx-calendar-check","type":"label"}]}]},{"id":"_help_J5Ex1ZrMbyJ6","title":"Custom Request Handler","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Custom Request Handler"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_d3fAXQ2diepH","title":"Custom Resource Providers","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Custom Resource Providers"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_pgxEVkzLl1OP","title":"ETAPI (REST API)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/ETAPI (REST API)"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_9qPsTWBorUhQ","title":"API Reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"/etapi/docs"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_47ZrP6FNuoG8","title":"Default Note Title","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Default Note Title"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_wX4HbRucYSDD","title":"Database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database"},{"name":"iconClass","value":"bx bx-data","type":"label"}],"children":[{"id":"_help_oyIAJ9PvvwHX","title":"Manually altering the database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Manually altering the database"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_YKWqdJhzi2VY","title":"SQL Console","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Manually altering the database/SQL Console"},{"name":"iconClass","value":"bx bx-data","type":"label"}]}]},{"id":"_help_6tZeKvSHEUiB","title":"Demo Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Demo Notes"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_Gzjqa934BdH4","title":"Configuration (config.ini or environment variables)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or e"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_c5xB8m4g2IY6","title":"Trilium instance","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or environment variables)/Trilium instance"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_LWtBjFej3wX3","title":"Cross-Origin Resource Sharing (CORS)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or environment variables)/Cross-Origin Resource Sharing "},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_ivYnonVFBxbQ","title":"Bulk Actions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Bulk Actions"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_4FahAwuGTAwC","title":"Note source","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note source"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_1YeN2MzFUluU","title":"Technologies used","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used"},{"name":"iconClass","value":"bx bxs-component","type":"label"}],"children":[{"id":"_help_MI26XDLSAlCD","title":"CKEditor","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/CKEditor"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_N4IDkixaDG9C","title":"MindElixir","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/MindElixir"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_H0mM1lTxF9JI","title":"Excalidraw","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/Excalidraw"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_MQHyy2dIFgxS","title":"Leaflet","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/Leaflet"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_m1lbrzyKDaRB","title":"Note ID","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note ID"},{"name":"iconClass","value":"bx bx-hash","type":"label"}]},{"id":"_help_0vTSyvhPTAOz","title":"Internal API","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_z8O2VG4ZZJD7","title":"API Reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"/api/docs"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_2mUhVmZK8RF3","title":"Hidden Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Hidden Notes"},{"name":"iconClass","value":"bx bx-hide","type":"label"}]},{"id":"_help_uYF7pmepw27K","title":"Metrics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Metrics"},{"name":"iconClass","value":"bx bxs-data","type":"label"}],"children":[{"id":"_help_bOP3TB56fL1V","title":"grafana-dashboard.json","type":"doc","attributes":[{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]},{"id":"_help_LMAv4Uy3Wk6J","title":"AI","type":"book","attributes":[{"name":"iconClass","value":"bx bx-bot","type":"label"}],"children":[{"id":"_help_GBBMSlVSOIGP","title":"Introduction","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/Introduction"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_WkM7gsEUyCXs","title":"AI Provider Information","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/AI Provider Information"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_7EdTxPADv95W","title":"Ollama","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_vvUCN7FDkq7G","title":"Installing Ollama","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/AI Provider Information/Ollama/Installing Ollama"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_ZavFigBX9AwP","title":"OpenAI","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/AI Provider Information/OpenAI"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_e0lkirXEiSNc","title":"Anthropic","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/AI Provider Information/Anthropic"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]},{"id":"_help_CdNpE2pqjmI6","title":"Scripting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting"},{"name":"iconClass","value":"bx bxs-file-js","type":"label"}],"children":[{"id":"_help_yIhgI5H7A2Sm","title":"Frontend Basics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_es8OU2GuguFU","title":"Examples","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_TjLYAo3JMO8X","title":"\"New Task\" launcher button","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Examples/New Task launcher button"},{"name":"iconClass","value":"bx bx-task","type":"label"}]},{"id":"_help_7kZPMD0uFwkH","title":"Downloading responses from Google Forms","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Examples/Downloading responses from Goo"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_DL92EjAaXT26","title":"Using promoted attributes to configure scripts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Examples/Using promoted attributes to c"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_GPERMystNGTB","title":"Events","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Events"},{"name":"iconClass","value":"bx bx-rss","type":"label"}]},{"id":"_help_MgibgPcfeuGz","title":"Custom Widgets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Custom Widgets"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_YNxAqkI5Kg1M","title":"Word count widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Custom Widgets/Word count widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_SynTBQiBsdYJ","title":"Widget Basics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Custom Widgets/Widget Basics"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_GLks18SNjxmC","title":"Script API","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Script API"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_Q2z6av6JZVWm","title":"Frontend API","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://triliumnext.github.io/Notes/Script%20API/interfaces/Frontend_Script_API.Api.html"},{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_habiZ3HU8Kw8","title":"FNote","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://triliumnext.github.io/Notes/Script%20API/classes/Frontend_Script_API.FNote.html"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_MEtfsqa5VwNi","title":"Backend API","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://triliumnext.github.io/Notes/Script%20API/interfaces/Backend_Script_API.Api.html"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]}] \ No newline at end of file +[{"id":"_help_Otzi9La2YAUX","title":"Installation & Setup","type":"book","attributes":[{"name":"iconClass","value":"bx bx-cog","type":"label"}],"children":[{"id":"_help_poXkQfguuA0U","title":"Desktop Installation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_WOcw2SLH6tbX","title":"Server Installation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_Dgg7bR3b6K9j","title":"1. Installing the server","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_3tW6mORuTHnB","title":"Packaged version for Linux","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]},{"id":"_help_rWX5eY045zbE","title":"Using Docker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker"},{"name":"iconClass","value":"bx bxl-docker","type":"label"}]},{"id":"_help_moVgBcoxE3EK","title":"On NixOS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/On NixOS"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]},{"id":"_help_J1Bb6lVlwU5T","title":"Manually","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}]},{"id":"_help_DCmT6e7clMoP","title":"Using Kubernetes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Kubernetes"},{"name":"iconClass","value":"bx bxl-kubernetes","type":"label"}]},{"id":"_help_klCWNks3ReaQ","title":"Multiple server instances","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Multiple server instances"},{"name":"iconClass","value":"bx bxs-user-account","type":"label"}]}]},{"id":"_help_vcjrb3VVYPZI","title":"2. Reverse proxy","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_ud6MShXL4WpO","title":"Nginx","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_fDLvzOx29Pfg","title":"Apache","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_l2VkvOwUNfZj","title":"TLS Configuration","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/TLS Configuration"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_0hzsNCP31IAB","title":"Authentication","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Authentication"},{"name":"iconClass","value":"bx bx-lock-alt","type":"label"}]},{"id":"_help_7DAiwaf8Z7Rz","title":"Multi-Factor Authentication","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication"},{"name":"iconClass","value":"bx bx-stopwatch","type":"label"}]}]},{"id":"_help_cbkrhQjrkKrh","title":"Synchronization","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Synchronization"},{"name":"iconClass","value":"bx bx-sync","type":"label"}]},{"id":"_help_RDslemsQ6gCp","title":"Mobile Frontend","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Mobile Frontend"},{"name":"iconClass","value":"bx bx-mobile-alt","type":"label"}]},{"id":"_help_MtPxeAWVAzMg","title":"Web Clipper","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Web Clipper"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_n1lujUxCwipy","title":"Upgrading TriliumNext","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Upgrading TriliumNext"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_ODY7qQn5m2FT","title":"Backup","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Backup"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_tAassRL4RSQL","title":"Data directory","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Data directory"},{"name":"iconClass","value":"bx bx-folder-open","type":"label"}]}]},{"id":"_help_gh7bpGYxajRS","title":"Basic Concepts and Features","type":"book","attributes":[{"name":"iconClass","value":"bx bx-help-circle","type":"label"}],"children":[{"id":"_help_Vc8PjrjAGuOp","title":"UI Elements","type":"book","attributes":[{"name":"iconClass","value":"bx bx-window-alt","type":"label"}],"children":[{"id":"_help_x0JgW8UqGXvq","title":"Vertical and horizontal layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Vertical and horizontal layout"},{"name":"iconClass","value":"bx bxs-layout","type":"label"}]},{"id":"_help_x3i7MxGccDuM","title":"Global menu","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Global menu"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_oPVyFC7WL2Lp","title":"Note Tree","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree"},{"name":"iconClass","value":"bx bxs-tree-alt","type":"label"}],"children":[{"id":"_help_YtSN43OrfzaA","title":"Note tree contextual menu","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_yTjUdsOi4CIE","title":"Multiple selection","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Multiple selection"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]}]},{"id":"_help_BlN9DFI679QC","title":"Ribbon","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon"},{"name":"iconClass","value":"bx bx-dots-horizontal","type":"label"}]},{"id":"_help_3seOhtN8uLIY","title":"Tabs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs"},{"name":"iconClass","value":"bx bx-dock-top","type":"label"}]},{"id":"_help_xYmIYSP6wE3F","title":"Launch Bar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Launch Bar"},{"name":"iconClass","value":"bx bx-sidebar","type":"label"}]},{"id":"_help_8YBEPzcpUgxw","title":"Note buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons"},{"name":"iconClass","value":"bx bx-dots-vertical-rounded","type":"label"}]},{"id":"_help_4TIF1oA4VQRO","title":"Options","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Options"},{"name":"iconClass","value":"bx bx-cog","type":"label"}]},{"id":"_help_luNhaphA37EO","title":"Split View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View"},{"name":"iconClass","value":"bx bx-dock-right","type":"label"}]},{"id":"_help_XpOYSgsLkTJy","title":"Floating buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Floating buttons"},{"name":"iconClass","value":"bx bx-rectangle","type":"label"}]},{"id":"_help_RnaPdbciOfeq","title":"Right Sidebar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Right Sidebar"},{"name":"iconClass","value":"bx bxs-dock-right","type":"label"}]},{"id":"_help_r5JGHN99bVKn","title":"Recent Changes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Recent Changes"},{"name":"iconClass","value":"bx bx-history","type":"label"}]},{"id":"_help_ny318J39E5Z0","title":"Zoom","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom"},{"name":"iconClass","value":"bx bx-zoom-in","type":"label"}]}]},{"id":"_help_BFs8mudNFgCS","title":"Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes"},{"name":"iconClass","value":"bx bx-notepad","type":"label"}],"children":[{"id":"_help_p9kXRFAkwN4o","title":"Note Icons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note Icons"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_0vhv7lsOLy82","title":"Attachments","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Attachments"},{"name":"iconClass","value":"bx bx-paperclip","type":"label"}]},{"id":"_help_IakOLONlIfGI","title":"Cloning Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Cloning Notes"},{"name":"iconClass","value":"bx bx-duplicate","type":"label"}],"children":[{"id":"_help_TBwsyfadTA18","title":"Branch prefix","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Cloning Notes/Branch prefix"},{"name":"iconClass","value":"bx bx-rename","type":"label"}]}]},{"id":"_help_bwg0e8ewQMak","title":"Protected Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Protected Notes"},{"name":"iconClass","value":"bx bx-lock-alt","type":"label"}]},{"id":"_help_MKmLg5x6xkor","title":"Archived Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Archived Notes"},{"name":"iconClass","value":"bx bx-box","type":"label"}]},{"id":"_help_vZWERwf8U3nx","title":"Note Revisions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note Revisions"},{"name":"iconClass","value":"bx bx-history","type":"label"}]},{"id":"_help_aGlEvb9hyDhS","title":"Sorting Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Sorting Notes"},{"name":"iconClass","value":"bx bx-sort-up","type":"label"}]},{"id":"_help_NRnIZmSMc5sj","title":"Export as PDF","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Export as PDF"},{"name":"iconClass","value":"bx bxs-file-pdf","type":"label"}]},{"id":"_help_CoFPLs3dRlXc","title":"Read-Only Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes"},{"name":"iconClass","value":"bx bx-edit-alt","type":"label"}]},{"id":"_help_0ESUbbAxVnoK","title":"Note List","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}],"children":[{"id":"_help_xWbu3jpNWapp","title":"Calendar View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Calendar View"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]},{"id":"_help_2FvYrpmOXm29","title":"Table View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View"},{"name":"iconClass","value":"bx bx-table","type":"label"}]},{"id":"_help_81SGnPGMk7Xc","title":"Geo Map View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View"},{"name":"iconClass","value":"bx bx-map-alt","type":"label"}]}]}]},{"id":"_help_wArbEsdSae6g","title":"Navigation","type":"book","attributes":[{"name":"iconClass","value":"bx bx-navigation","type":"label"}],"children":[{"id":"_help_kBrnXNG3Hplm","title":"Tree Concepts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Tree Concepts"},{"name":"iconClass","value":"bx bx-pyramid","type":"label"}]},{"id":"_help_MMiBEQljMQh2","title":"Note Navigation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Note Navigation"},{"name":"iconClass","value":"bx bxs-navigation","type":"label"}]},{"id":"_help_Ms1nauBra7gq","title":"Quick search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Quick search"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]},{"id":"_help_F1r9QtzQLZqm","title":"Jump to Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Jump to Note"},{"name":"iconClass","value":"bx bx-send","type":"label"}]},{"id":"_help_eIg8jdvaoNNd","title":"Search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Search"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]},{"id":"_help_u3YFHC9tQlpm","title":"Bookmarks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks"},{"name":"iconClass","value":"bx bx-bookmarks","type":"label"}]},{"id":"_help_OR8WJ7Iz9K4U","title":"Note Hoisting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Note Hoisting"},{"name":"iconClass","value":"bx bxs-chevrons-up","type":"label"}]},{"id":"_help_9sRHySam5fXb","title":"Workspaces","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Workspaces"},{"name":"iconClass","value":"bx bx-door-open","type":"label"}]},{"id":"_help_xWtq5NUHOwql","title":"Similar Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Similar Notes"},{"name":"iconClass","value":"bx bx-bar-chart","type":"label"}]},{"id":"_help_McngOG2jbUWX","title":"Search in note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Search in note"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]}]},{"id":"_help_A9Oc6YKKc65v","title":"Keyboard Shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Keyboard Shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_Wy267RK4M69c","title":"Themes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes"},{"name":"iconClass","value":"bx bx-palette","type":"label"}],"children":[{"id":"_help_VbjZvtUek0Ln","title":"Theme Gallery","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes/Theme Gallery"},{"name":"iconClass","value":"bx bx-book-reader","type":"label"}]}]},{"id":"_help_mHbBMPDPkVV5","title":"Import & Export","type":"book","attributes":[{"name":"iconClass","value":"bx bx-import","type":"label"}],"children":[{"id":"_help_Oau6X9rCuegd","title":"Markdown","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Markdown"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}],"children":[{"id":"_help_rJ9grSgoExl9","title":"Supported syntax","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Markdown/Supported syntax"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}]}]},{"id":"_help_syuSEKf2rUGr","title":"Evernote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_GnhlmrATVqcH","title":"OneNote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/OneNote"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_rC3pL2aptaRE","title":"Zen mode","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Zen mode"},{"name":"iconClass","value":"bx bxs-yin-yang","type":"label"}]}]},{"id":"_help_s3YCWHBfmYuM","title":"Quick Start","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Quick Start"},{"name":"iconClass","value":"bx bx-run","type":"label"}]},{"id":"_help_i6dbnitykE5D","title":"FAQ","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/FAQ"},{"name":"iconClass","value":"bx bx-question-mark","type":"label"}]},{"id":"_help_KSZ04uQ2D1St","title":"Note Types","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types"},{"name":"iconClass","value":"bx bx-edit","type":"label"}],"children":[{"id":"_help_iPIMuisry3hd","title":"Text","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text"},{"name":"iconClass","value":"bx bx-note","type":"label"}],"children":[{"id":"_help_NwBbFdNZ9h7O","title":"Block quotes & admonitions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Block quotes & admonitions"},{"name":"iconClass","value":"bx bx-info-circle","type":"label"}]},{"id":"_help_oSuaNgyyKnhu","title":"Bookmarks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Bookmarks"},{"name":"iconClass","value":"bx bx-bookmark","type":"label"}]},{"id":"_help_veGu4faJErEM","title":"Content language & Right-to-left support","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Content language & Right-to-le"},{"name":"iconClass","value":"bx bx-align-right","type":"label"}]},{"id":"_help_2x0ZAX9ePtzV","title":"Cut to subnote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Cut to subnote"},{"name":"iconClass","value":"bx bx-cut","type":"label"}]},{"id":"_help_UYuUB1ZekNQU","title":"Developer-specific formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Developer-specific formatting"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}],"children":[{"id":"_help_QxEyIjRBizuC","title":"Code blocks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks"},{"name":"iconClass","value":"bx bx-code","type":"label"}]}]},{"id":"_help_AgjCISero73a","title":"Footnotes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Footnotes"},{"name":"iconClass","value":"bx bx-bracket","type":"label"}]},{"id":"_help_nRhnJkTT8cPs","title":"Formatting toolbar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Formatting toolbar"},{"name":"iconClass","value":"bx bx-text","type":"label"}]},{"id":"_help_Gr6xFaF6ioJ5","title":"General formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/General formatting"},{"name":"iconClass","value":"bx bx-bold","type":"label"}]},{"id":"_help_AxshuNRegLAv","title":"Highlights list","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Highlights list"},{"name":"iconClass","value":"bx bx-highlight","type":"label"}]},{"id":"_help_mT0HEkOsz6i1","title":"Images","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Images"},{"name":"iconClass","value":"bx bx-image-alt","type":"label"}],"children":[{"id":"_help_0Ofbk1aSuVRu","title":"Image references","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Images/Image references"},{"name":"iconClass","value":"bx bxs-file-image","type":"label"}]}]},{"id":"_help_nBAXQFj20hS1","title":"Include Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Include Note"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_CohkqWQC1iBv","title":"Insert buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Insert buttons"},{"name":"iconClass","value":"bx bx-plus","type":"label"}]},{"id":"_help_oiVPnW8QfnvS","title":"Keyboard shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Keyboard shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_QEAPj01N5f7w","title":"Links","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Links"},{"name":"iconClass","value":"bx bx-link-alt","type":"label"}]},{"id":"_help_S6Xx8QIWTV66","title":"Lists","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Lists"},{"name":"iconClass","value":"bx bx-list-ul","type":"label"}]},{"id":"_help_QrtTYPmdd1qq","title":"Markdown-like formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Markdown-like formatting"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}]},{"id":"_help_YfYAtQBcfo5V","title":"Math Equations","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Math Equations"},{"name":"iconClass","value":"bx bx-math","type":"label"}]},{"id":"_help_dEHYtoWWi8ct","title":"Other features","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Other features"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_gLt3vA97tMcp","title":"Premium features","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features"},{"name":"iconClass","value":"bx bx-star","type":"label"}],"children":[{"id":"_help_ZlN4nump6EbW","title":"Slash Commands","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Slash Commands"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_pwc194wlRzcH","title":"Text Snippets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Text Snippets"},{"name":"iconClass","value":"bx bx-align-left","type":"label"}]}]},{"id":"_help_BFvAtE74rbP6","title":"Table of contents","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Table of contents"},{"name":"iconClass","value":"bx bx-heading","type":"label"}]},{"id":"_help_NdowYOC1GFKS","title":"Tables","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Tables"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]},{"id":"_help_6f9hih2hXXZk","title":"Code","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Code"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_m523cpzocqaD","title":"Saved Search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Saved Search"},{"name":"iconClass","value":"bx bx-file-find","type":"label"}]},{"id":"_help_iRwzGnHPzonm","title":"Relation Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Relation Map"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_bdUJEHsAPYQR","title":"Note Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Note Map"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_HcABDtFCkbFN","title":"Render Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Render Note"},{"name":"iconClass","value":"bx bx-extension","type":"label"}]},{"id":"_help_GTwFsgaA0lCt","title":"Book","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Book"},{"name":"iconClass","value":"bx bx-book","type":"label"}]},{"id":"_help_s1aBHPd79XYj","title":"Mermaid Diagrams","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mermaid Diagrams"},{"name":"iconClass","value":"bx bx-selection","type":"label"}],"children":[{"id":"_help_RH6yLjjWJHof","title":"ELK layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mermaid Diagrams/ELK layout"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]}]},{"id":"_help_grjYqerjn243","title":"Canvas","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Canvas"},{"name":"iconClass","value":"bx bx-pen","type":"label"}]},{"id":"_help_1vHRoWCEjj0L","title":"Web View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Web View"},{"name":"iconClass","value":"bx bx-globe-alt","type":"label"}]},{"id":"_help_gBbsAeiuUxI5","title":"Mind Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mind Map"},{"name":"iconClass","value":"bx bx-sitemap","type":"label"}]},{"id":"_help_W8vYD3Q1zjCR","title":"File","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/File"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_BgmBlOIl72jZ","title":"Troubleshooting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting"},{"name":"iconClass","value":"bx bx-bug","type":"label"}],"children":[{"id":"_help_wy8So3yZZlH9","title":"Reporting issues","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Reporting issues"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_x59R8J8KV5Bp","title":"Anonymized Database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Anonymized Database"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_qzNzp9LYQyPT","title":"Error logs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Error logs"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_vdlYGAcpXAgc","title":"Synchronization fails with 504 Gateway Timeout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Synchronization fails with 504"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_s8alTXmpFR61","title":"Refreshing the application","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Refreshing the application"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_pKK96zzmvBGf","title":"Theme development","type":"book","attributes":[{"name":"iconClass","value":"bx bx-palette","type":"label"}],"children":[{"id":"_help_7NfNr5pZpVKV","title":"Creating a custom theme","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Creating a custom theme"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_WFGzWeUK6arS","title":"Customize the Next theme","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Customize the Next theme"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_WN5z4M8ASACJ","title":"Reference","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Reference"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_AlhDUqhENtH7","title":"Custom app-wide CSS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Custom app-wide CSS"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_tC7s2alapj8V","title":"Advanced Usage","type":"book","attributes":[{"name":"iconClass","value":"bx bx-rocket","type":"label"}],"children":[{"id":"_help_zEY4DaJG4YT5","title":"Attributes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes"},{"name":"iconClass","value":"bx bx-list-check","type":"label"}],"children":[{"id":"_help_HI6GBBIduIgv","title":"Labels","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Labels"},{"name":"iconClass","value":"bx bx-hash","type":"label"}]},{"id":"_help_Cq5X6iKQop6R","title":"Relations","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Relations"},{"name":"iconClass","value":"bx bx-transfer","type":"label"}]},{"id":"_help_bwZpz2ajCEwO","title":"Attribute Inheritance","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Attribute Inheritance"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_OFXdgB2nNk1F","title":"Promoted Attributes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]},{"id":"_help_KC1HB96bqqHX","title":"Templates","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Templates"},{"name":"iconClass","value":"bx bx-copy","type":"label"}]},{"id":"_help_BCkXAVs63Ttv","title":"Note Map (Link map, Tree map)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note Map (Link map, Tree map)"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_R9pX4DGra2Vt","title":"Sharing","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing"},{"name":"iconClass","value":"bx bx-share-alt","type":"label"}],"children":[{"id":"_help_Qjt68inQ2bRj","title":"Serving directly the content of a note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing/Serving directly the content o"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_5668rwcirq1t","title":"Advanced Showcases","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_l0tKav7yLHGF","title":"Day Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Day Notes"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]},{"id":"_help_R7abl2fc6Mxi","title":"Weight Tracker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Weight Tracker"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_xYjQUYhpbUEW","title":"Task Manager","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Task Manager"},{"name":"iconClass","value":"bx bx-calendar-check","type":"label"}]}]},{"id":"_help_J5Ex1ZrMbyJ6","title":"Custom Request Handler","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Custom Request Handler"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_d3fAXQ2diepH","title":"Custom Resource Providers","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Custom Resource Providers"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_pgxEVkzLl1OP","title":"ETAPI (REST API)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/ETAPI (REST API)"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_9qPsTWBorUhQ","title":"API Reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"/etapi/docs"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_47ZrP6FNuoG8","title":"Default Note Title","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Default Note Title"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_wX4HbRucYSDD","title":"Database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database"},{"name":"iconClass","value":"bx bx-data","type":"label"}],"children":[{"id":"_help_oyIAJ9PvvwHX","title":"Manually altering the database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Manually altering the database"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_YKWqdJhzi2VY","title":"SQL Console","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Manually altering the database/SQL Console"},{"name":"iconClass","value":"bx bx-data","type":"label"}]}]},{"id":"_help_6tZeKvSHEUiB","title":"Demo Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Demo Notes"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_Gzjqa934BdH4","title":"Configuration (config.ini or environment variables)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or e"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_c5xB8m4g2IY6","title":"Trilium instance","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or environment variables)/Trilium instance"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_LWtBjFej3wX3","title":"Cross-Origin Resource Sharing (CORS)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or environment variables)/Cross-Origin Resource Sharing "},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_ivYnonVFBxbQ","title":"Bulk Actions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Bulk Actions"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_4FahAwuGTAwC","title":"Note source","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note source"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_1YeN2MzFUluU","title":"Technologies used","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used"},{"name":"iconClass","value":"bx bxs-component","type":"label"}],"children":[{"id":"_help_MI26XDLSAlCD","title":"CKEditor","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/CKEditor"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_N4IDkixaDG9C","title":"MindElixir","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/MindElixir"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_H0mM1lTxF9JI","title":"Excalidraw","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/Excalidraw"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_MQHyy2dIFgxS","title":"Leaflet","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/Leaflet"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_m1lbrzyKDaRB","title":"Note ID","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note ID"},{"name":"iconClass","value":"bx bx-hash","type":"label"}]},{"id":"_help_0vTSyvhPTAOz","title":"Internal API","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_z8O2VG4ZZJD7","title":"API Reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"/api/docs"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_2mUhVmZK8RF3","title":"Hidden Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Hidden Notes"},{"name":"iconClass","value":"bx bx-hide","type":"label"}]},{"id":"_help_uYF7pmepw27K","title":"Metrics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Metrics"},{"name":"iconClass","value":"bx bxs-data","type":"label"}],"children":[{"id":"_help_bOP3TB56fL1V","title":"grafana-dashboard.json","type":"doc","attributes":[{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]},{"id":"_help_LMAv4Uy3Wk6J","title":"AI","type":"book","attributes":[{"name":"iconClass","value":"bx bx-bot","type":"label"}],"children":[{"id":"_help_GBBMSlVSOIGP","title":"Introduction","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/Introduction"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_WkM7gsEUyCXs","title":"AI Provider Information","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/AI Provider Information"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_7EdTxPADv95W","title":"Ollama","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_vvUCN7FDkq7G","title":"Installing Ollama","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/AI Provider Information/Ollama/Installing Ollama"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_ZavFigBX9AwP","title":"OpenAI","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/AI Provider Information/OpenAI"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_e0lkirXEiSNc","title":"Anthropic","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI/AI Provider Information/Anthropic"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]},{"id":"_help_CdNpE2pqjmI6","title":"Scripting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting"},{"name":"iconClass","value":"bx bxs-file-js","type":"label"}],"children":[{"id":"_help_yIhgI5H7A2Sm","title":"Frontend Basics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_es8OU2GuguFU","title":"Examples","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_TjLYAo3JMO8X","title":"\"New Task\" launcher button","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Examples/New Task launcher button"},{"name":"iconClass","value":"bx bx-task","type":"label"}]},{"id":"_help_7kZPMD0uFwkH","title":"Downloading responses from Google Forms","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Examples/Downloading responses from Goo"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_DL92EjAaXT26","title":"Using promoted attributes to configure scripts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Examples/Using promoted attributes to c"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_GPERMystNGTB","title":"Events","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Events"},{"name":"iconClass","value":"bx bx-rss","type":"label"}]},{"id":"_help_MgibgPcfeuGz","title":"Custom Widgets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Custom Widgets"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_YNxAqkI5Kg1M","title":"Word count widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Custom Widgets/Word count widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_SynTBQiBsdYJ","title":"Widget Basics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Custom Widgets/Widget Basics"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_GLks18SNjxmC","title":"Script API","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Script API"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"children":[{"id":"_help_Q2z6av6JZVWm","title":"Frontend API","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://triliumnext.github.io/Notes/Script%20API/interfaces/Frontend_Script_API.Api.html"},{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_habiZ3HU8Kw8","title":"FNote","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://triliumnext.github.io/Notes/Script%20API/classes/Frontend_Script_API.FNote.html"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_MEtfsqa5VwNi","title":"Backend API","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://triliumnext.github.io/Notes/Script%20API/interfaces/Backend_Script_API.Api.html"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]}] \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/11_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/10_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/11_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/10_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/12_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/11_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/12_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/11_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/13_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/12_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/13_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/12_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/14_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/13_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/14_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/13_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/15_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/14_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/15_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/14_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/15_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/15_Geo Map View_image.png new file mode 100644 index 000000000..72dbb9861 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/15_Geo Map View_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/16_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/16_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/16_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/16_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/17_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/17_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/17_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/17_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/18_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/18_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/18_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/18_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/1_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/1_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/1_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/1_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/2_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/2_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/2_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/2_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/3_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/3_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/3_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/3_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/4_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/4_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/4_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/4_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/5_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/5_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/5_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/5_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/6_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/6_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/6_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/6_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/8_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/7_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/8_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/7_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/9_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/8_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/9_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/8_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/10_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/9_Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/10_Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/9_Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Geo Map.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View.html similarity index 68% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Geo Map.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View.html index b85d13a7c..0838f4a46 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Geo Map.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View.html @@ -1,5 +1,11 @@ +
-

This note type displays the children notes on a geographical map, based @@ -19,9 +25,9 @@ 1 -

- +
+
Right click on any note on the note tree and select Insert child noteGeo Map (beta). @@ -30,7 +36,7 @@ 2
-
@@ -39,7 +45,6 @@
-

Repositioning the map

  • Click and drag the map in order to move across the map.
  • @@ -49,6 +54,7 @@

    The position on the map and the zoom are saved inside the map note and restored when visiting again the note.

    Adding a marker using the map

    +

    Adding a new note using the plus button

    @@ -63,18 +69,18 @@ + ) in the top-right of the map. @@ -94,7 +100,7 @@
    1 To create a marker, first navigate to the desired point on the map. Then press the - button in the Floating buttons (top-right) + button in the Floating buttons (top-right) area. 

    If the button is not visible, make sure the button section is visible by pressing the chevron button ( - ) in the top-right of the map.
     
    2 - Once pressed, the map will enter in the insert mode, as illustrated by @@ -86,7 +92,7 @@
    3 - Enter the name of the marker/note to be created.
    4 - Once confirmed, the marker will show up on the map and it will also be @@ -103,11 +109,34 @@
    - +

    Adding a new note using the contextual menu

    +
      +
    1. Right click anywhere on the map, where to place the newly created marker + (and corresponding note).
    2. +
    3. Select Add a marker at this location.
    4. +
    5. Enter the name of the newly created note.
    6. +
    7. The map should be updated with the new marker.
    8. +
    +

    Adding an existing note on note from the note tree

    +
      +
    1. Select the desired note in the Note Tree.
    2. +
    3. Hold the mouse on the note and drag it to the map to the desired location.
    4. +
    5. The map should be updated with the new marker.
    6. +
    +

    This works for:

    +
      +
    • Notes that are not part of the geo map, case in which a clone will + be created.
    • +
    • Notes that are a child of the geo map but not yet positioned on the map.
    • +
    • Notes that are a child of the geo map and also positioned, case in which + the marker will be relocated to the new position.
    • +

    How the location of the markers is stored

    The location of a marker is stored in the #geolocation attribute of the child notes:

    - +

    + +

    This value can be added manually if needed. The value of the attribute is made up of the latitude and longitude separated by a comma.

    Repositioning markers

    @@ -129,18 +158,40 @@
  • Middle-clicking the marker will open the note in a new tab.
  • Right-clicking the marker will open a contextual menu allowing:
      -
    • Opening the note in a new tab, split or window.
    • -
    • Opening the location using an external application (if the operating system - supports it).
    • -
    • Removing the marker from the map, which will remove the #geolocation attribute - of the note. To add it back again, the coordinates have to be manually - added back in.
    • +
    •  
+

Contextual menu

+

It's possible to press the right mouse button to display a contextual + menu.

+
    +
  1. If right-clicking an empty section of the map (not on a marker), it allows + to: +
      +
    1. Displays the latitude and longitude. Clicking this option will copy them + to the clipboard.
    2. +
    3. Open the location using an external application (if the operating system + supports it).
    4. +
    5. Adding a new marker at that location.
    6. +
    +
  2. +
  3. If right-clicking on a marker, it allows to: +
      +
    1. Displays the latitude and longitude. Clicking this option will copy them + to the clipboard.
    2. +
    3. Open the location using an external application (if the operating system + supports it).
    4. +
    5. Open the note in a new tab, split or window.
    6. +
    7. Remove the marker from the map, which will remove the #geolocation attribute + of the note. To add it back again, the coordinates have to be manually + added back in.
    8. +
    +
  4. +

Icon and color of the markers

- image

The markers will have the same icon as the note.

@@ -171,7 +222,7 @@ 1
-
@@ -188,7 +239,7 @@ 2
-
@@ -198,7 +249,7 @@ 3
-
@@ -210,7 +261,6 @@ -

Adding from OpenStreetMap

Similarly to the Google Maps approach:

@@ -231,7 +281,7 @@ 1 - Go to any location on openstreetmap.org and right click to bring up the @@ -240,7 +290,7 @@ 2 - The address will be visible in the top-left of the screen, in the place @@ -251,7 +301,7 @@ 3 - Simply paste the value inside the text box into the #geolocation attribute @@ -260,7 +310,6 @@
-

Adding GPS tracks (.gpx)

Trilium has basic support for displaying GPS tracks on the geo map.

1
-
@@ -294,7 +343,7 @@ class="table" style="width:100%;"> 2
-
@@ -305,7 +354,7 @@ class="table" style="width:100%;"> 3
-
@@ -324,13 +373,23 @@ class="table" style="width:100%;">

If the GPX contains waypoints, they will also be displayed. If they have a name, it is displayed when hovering over it with the mouse.

+

Read-only mode

+

When a map is in read-only all editing features will be disabled such + as:

+
    +
  • The add button in the Floating buttons.
  • +
  • Dragging markers.
  • +
  • Editing from the contextual menu (removing locations or adding new items).
  • +
+

To enable read-only mode simply press the Lock icon from the  + Floating buttons. To disable it, press the button again.

Troubleshooting

-
- -

Grid-like artifacts on the map

+

Grid-like artifacts on the map

This occurs if the application is not at 100% zoom which causes the pixels of the map to not render correctly due to fractional scaling. The only possible solution is to set the UI zoom at 100% (default keyboard shortcut diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Geo Map_image.jpg b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View_image.jpg similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Geo Map_image.jpg rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View_image.jpg diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Geo Map_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View.html similarity index 70% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View.html index 10d663aa8..72185c793 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View.html @@ -1,25 +1,25 @@

-

The table view displays information in a grid, where the rows are individual - notes and the columns are Promoted Attributes. + notes and the columns are Promoted Attributes. In addition, values are editable.

Interaction

Creating a new table

-

Right click the Note Tree and +

Right click the Note Tree and select Insert child note and look for the Table item.

Adding columns

-

Each column is a promoted attribute that +

Each column is a promoted attribute that is defined on the Book note. Ideally, the promoted attributes need to be inheritable in order to show up in the child notes.

-

To create a new column, simply press Add new column at the bottom +

To create a new column, simply press Add new column at the bottom of the table.

There are also a few predefined columns:

  • The current item number, identified by the # symbol. This simply counts the note and is affected by sorting.
  • -
  • Note ID, +
  • Note ID, representing the unique ID used internally by Trilium
  • The title of the note.
@@ -28,9 +28,7 @@

To create a new note, press Add new row at the bottom of the table. By default it will try to edit the title of the newly created note.

Alternatively, the note can be created from theNote Tree or - scripting.

+ href="#root/_help_oPVyFC7WL2Lp">Note Tree or scripting.

Editing data

Simply click on a cell within a row to change its value. The change will not only reflect in the table, but also as an attribute of the corresponding @@ -58,7 +56,7 @@

Reordering rows

Notes can be dragged around to change their order. This will also change - the order of the note in the Note Tree.

+ the order of the note in the Note Tree.

Currently, it's possible to reorder notes even if sorting is used, but the result might be inconsistent.

Limitations

@@ -67,7 +65,7 @@
  1. As mentioned previously, the columns of the table are defined as  Promoted Attributes. + class="reference-link" href="#root/_help_OFXdgB2nNk1F">Promoted Attributes.
    1. But only the promoted attributes that are defined at the level of the Book note are actually taken into consideration.
    2. @@ -77,22 +75,23 @@
    3. Hierarchy is not yet supported, so the table will only show the items that are direct children of the Book note.
    4. Multiple labels and relations are not supported. If a Promoted Attributes is - defined with a Multi value specificity, they will be ignored.
    5. + href="#root/_help_OFXdgB2nNk1F">Promoted Attributes is defined + with a Multi value specificity, they will be ignored.

    Use in search

    -

    The table view can be used in a Saved Search by +

    The table view can be used in a Saved Search by adding the #viewType=table attribute.

    Unlike when used in a book, saved searches are not limited to the sub-hierarchy of a note and allows for advanced queries thanks to the power of the  Search.

    + class="reference-link" href="#root/_help_eIg8jdvaoNNd">Search.

    However, there are also some limitations:

    • It's not possible to reorder notes.
    • It's not possible to add a new row.

    Columns are supported, by being defined as Promoted Attributes to - the Saved Search note.

    + href="#root/_help_OFXdgB2nNk1F">Promoted Attributes to the  + Saved Search note.

    Editing is also supported.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.html index f07452571..fc684b364 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.html @@ -54,4 +54,7 @@ hide the Mermaid source code and display the diagram preview in full-size. In this case, the read-only mode can be easily toggled on or off via a dedicated button in the Floating buttons area.
  2. +
  3. Geo Map View will + disallow all interaction that would otherwise change the map (dragging + notes, adding new items).
  4. \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/7_Geo Map_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/7_Geo Map_image.png deleted file mode 100644 index 00c5e8cc3..000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/7_Geo Map_image.png and /dev/null differ diff --git a/apps/server/src/migrations/0233__migrate_geo_map_to_collection.ts b/apps/server/src/migrations/0233__migrate_geo_map_to_collection.ts new file mode 100644 index 000000000..bd692a736 --- /dev/null +++ b/apps/server/src/migrations/0233__migrate_geo_map_to_collection.ts @@ -0,0 +1,46 @@ +import becca from "../becca/becca"; +import becca_loader from "../becca/becca_loader"; +import cls from "../services/cls.js"; +import hidden_subtree from "../services/hidden_subtree"; + +export default () => { + cls.init(() => { + becca_loader.load(); + + // Ensure the geomap template is generated. + hidden_subtree.checkHiddenSubtree(true); + + for (const note of Object.values(becca.notes)) { + if (note.type as string !== "geoMap") { + continue; + } + + console.log(`Migrating note '${note.noteId}' from geoMap to book type...`); + + note.type = "book"; + note.mime = ""; + note.save(); + + const content = note.getContent(); + if (content) { + const title = "geoMap.json"; + const existingAttachment = note.getAttachmentsByRole("viewConfig") + .filter(a => a.title === title)[0]; + if (existingAttachment) { + existingAttachment.setContent(content); + } else { + note.saveAttachment({ + role: "viewConfig", + title, + mime: "application/json", + content, + position: 0 + }); + } + + } + note.setContent(""); + note.setRelation("template", "_template_geo_map"); + } + }); +}; diff --git a/apps/server/src/migrations/migrations.ts b/apps/server/src/migrations/migrations.ts index 4743d9286..2757b4c25 100644 --- a/apps/server/src/migrations/migrations.ts +++ b/apps/server/src/migrations/migrations.ts @@ -6,6 +6,11 @@ // Migrations should be kept in descending order, so the latest migration is first. const MIGRATIONS: (SqlMigration | JsMigration)[] = [ + // Migrate geo map to collection + { + version: 233, + module: async () => import("./0233__migrate_geo_map_to_collection.js") + }, // Remove embedding tables since LLM embedding functionality has been removed { version: 232, diff --git a/apps/server/src/services/app_info.ts b/apps/server/src/services/app_info.ts index b3da2ac0e..0def56253 100644 --- a/apps/server/src/services/app_info.ts +++ b/apps/server/src/services/app_info.ts @@ -3,7 +3,7 @@ import build from "./build.js"; import packageJson from "../../package.json" with { type: "json" }; import dataDir from "./data_dir.js"; -const APP_DB_VERSION = 232; +const APP_DB_VERSION = 233; const SYNC_VERSION = 36; const CLIPPER_PROTOCOL_VERSION = "1.0"; diff --git a/apps/server/src/services/handlers.ts b/apps/server/src/services/handlers.ts index 9d64b8303..52e50cbf3 100644 --- a/apps/server/src/services/handlers.ts +++ b/apps/server/src/services/handlers.ts @@ -102,7 +102,7 @@ eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) => const content = note.getContent(); if ( - ["text", "code", "mermaid", "canvas", "relationMap", "mindMap", "geoMap"].includes(note.type) && + ["text", "code", "mermaid", "canvas", "relationMap", "mindMap"].includes(note.type) && typeof content === "string" && // if the note has already content we're not going to overwrite it with template's one (!content || content.trim().length === 0) && diff --git a/apps/server/src/services/hidden_subtree.ts b/apps/server/src/services/hidden_subtree.ts index 6ba0d965b..8b6c7e9fb 100644 --- a/apps/server/src/services/hidden_subtree.ts +++ b/apps/server/src/services/hidden_subtree.ts @@ -380,7 +380,7 @@ function checkHiddenSubtreeRecursively(parentNoteId: string, item: HiddenSubtree type: attr.type, name: attr.name, value: attr.value, - isInheritable: false + isInheritable: attr.isInheritable }).save(); } else if (attr.name === "docName" || (existingAttribute.noteId.startsWith("_help") && attr.name === "iconClass")) { if (existingAttribute.value !== attr.value) { diff --git a/apps/server/src/services/hidden_subtree_templates.ts b/apps/server/src/services/hidden_subtree_templates.ts index 62c841898..cfe61922c 100644 --- a/apps/server/src/services/hidden_subtree_templates.ts +++ b/apps/server/src/services/hidden_subtree_templates.ts @@ -43,6 +43,33 @@ export default function buildHiddenSubtreeTemplates() { value: "table" } ] + }, + { + id: "_template_geo_map", + type: "book", + title: "Geo Map", + icon: "bx bx-map-alt", + attributes: [ + { + name: "template", + type: "label" + }, + { + name: "viewType", + type: "label", + value: "geoMap" + }, + { + name: "hidePromotedAttributes", + type: "label" + }, + { + name: "label:geolocation", + type: "label", + value: "promoted,alias=Geolocation,single,text", + isInheritable: true + } + ] } ] }; diff --git a/apps/server/src/services/import/samples/geomap.zip b/apps/server/src/services/import/samples/geomap.zip new file mode 100644 index 000000000..6443c1997 Binary files /dev/null and b/apps/server/src/services/import/samples/geomap.zip differ diff --git a/apps/server/src/services/import/zip.spec.ts b/apps/server/src/services/import/zip.spec.ts index 4860f7b94..db2c7ba76 100644 --- a/apps/server/src/services/import/zip.spec.ts +++ b/apps/server/src/services/import/zip.spec.ts @@ -70,6 +70,19 @@ describe("processNoteContent", () => { expect(content).toContain(` { + const { importedNote } = await testImport("geomap.zip"); + expect(importedNote.type).toBe("book"); + expect(importedNote.mime).toBe(""); + expect(importedNote.getRelationValue("template")).toBe("_template_geo_map"); + + const attachment = importedNote.getAttachmentsByRole("viewConfig")[0]; + expect(attachment.title).toBe("geoMap.json"); + expect(attachment.mime).toBe("application/json"); + const content = attachment.getContent(); + expect(content).toStrictEqual(`{"view":{"center":{"lat":49.19598332223546,"lng":-2.1414576506668808},"zoom":12}}`); + }); }); function getNoteByTitlePath(parentNote: BNote, ...titlePath: string[]) { diff --git a/apps/server/src/services/import/zip.ts b/apps/server/src/services/import/zip.ts index e7da680bb..b2d83bdc6 100644 --- a/apps/server/src/services/import/zip.ts +++ b/apps/server/src/services/import/zip.ts @@ -502,6 +502,28 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo firstNote = firstNote || note; } } else { + if (detectedType as string === "geoMap") { + attributes.push({ + noteId, + type: "relation", + name: "template", + value: "_template_geo_map" + }); + + const attachment = new BAttachment({ + attachmentId: getNewAttachmentId(newEntityId()), + ownerId: noteId, + title: "geoMap.json", + role: "viewConfig", + mime: "application/json", + position: 0 + }); + + attachment.setContent(content, { forceSave: true }); + content = ""; + mime = ""; + } + ({ note } = noteService.createNewNote({ parentNoteId: parentNoteId, title: noteTitle || "", @@ -656,12 +678,15 @@ export function readZipFile(buffer: Buffer, processEntryCallback: (zipfile: yauz function resolveNoteType(type: string | undefined): NoteType { // BC for ZIPs created in Trilium 0.57 and older - if (type === "relation-map") { - return "relationMap"; - } else if (type === "note-map") { - return "noteMap"; - } else if (type === "web-view") { - return "webView"; + switch (type) { + case "relation-map": + return "relationMap"; + case "note-map": + return "noteMap"; + case "web-view": + return "webView"; + case "geoMap": + return "book"; } if (type && (ALLOWED_NOTE_TYPES as readonly string[]).includes(type)) { diff --git a/apps/server/src/services/note_types.ts b/apps/server/src/services/note_types.ts index 3b2dc8d66..2aa86d0b6 100644 --- a/apps/server/src/services/note_types.ts +++ b/apps/server/src/services/note_types.ts @@ -15,7 +15,6 @@ const noteTypes = [ { type: "doc", defaultMime: "" }, { type: "contentWidget", defaultMime: "" }, { type: "mindMap", defaultMime: "application/json" }, - { type: "geoMap", defaultMime: "application/json" }, { type: "aiChat", defaultMime: "application/json" } ]; diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json index dd69e1440..d5cf0c794 100644 --- a/docs/User Guide/!!!meta.json +++ b/docs/User Guide/!!!meta.json @@ -3177,6 +3177,27 @@ "value": "bx bx-edit-alt", "isInheritable": false, "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_optionsTextNotes", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_optionsCodeNotes", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "81SGnPGMk7Xc", + "isInheritable": false, + "position": 100 } ], "format": "markdown", @@ -3431,7 +3452,7 @@ "0ESUbbAxVnoK", "2FvYrpmOXm29" ], - "title": "Table", + "title": "Table View", "notePosition": 20, "prefix": null, "isExpanded": false, @@ -3439,30 +3460,30 @@ "mime": "text/html", "attributes": [ { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "OFXdgB2nNk1F", + "value": "m1lbrzyKDaRB", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "eIg8jdvaoNNd", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "m1lbrzyKDaRB", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 40 }, @@ -3481,15 +3502,15 @@ "position": 60 }, { - "type": "relation", - "name": "internalLink", - "value": "eIg8jdvaoNNd", + "type": "label", + "name": "iconClass", + "value": "bx bx-table", "isInheritable": false, - "position": 70 + "position": 10 } ], "format": "markdown", - "dataFileName": "Table.md", + "dataFileName": "Table View.md", "attachments": [ { "attachmentId": "vJYUG9fLQ2Pd", @@ -3497,7 +3518,232 @@ "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "Table_image.png" + "dataFileName": "Table View_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "81SGnPGMk7Xc", + "notePath": [ + "pOsGYCXsbNQG", + "gh7bpGYxajRS", + "BFs8mudNFgCS", + "0ESUbbAxVnoK", + "81SGnPGMk7Xc" + ], + "title": "Geo Map View", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "XpOYSgsLkTJy", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-map-alt", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IakOLONlIfGI", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "KSZ04uQ2D1St", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "0ESUbbAxVnoK", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Geo Map View.md", + "attachments": [ + { + "attachmentId": "1f07O0Z25ZRr", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Geo Map View_image.png" + }, + { + "attachmentId": "3oh61qhNLu7D", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Geo Map View_image.png" + }, + { + "attachmentId": "aCSNn9QlgHFi", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "2_Geo Map View_image.png" + }, + { + "attachmentId": "aCuXZY7WV4li", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "3_Geo Map View_image.png" + }, + { + "attachmentId": "agH6yREFgsoU", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "4_Geo Map View_image.png" + }, + { + "attachmentId": "AHyDUM6R5HeG", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "5_Geo Map View_image.png" + }, + { + "attachmentId": "CcjWLhE3KKfv", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "6_Geo Map View_image.png" + }, + { + "attachmentId": "fQy8R1vxKhwN", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "7_Geo Map View_image.png" + }, + { + "attachmentId": "gJ4Yz80jxcbn", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "8_Geo Map View_image.png" + }, + { + "attachmentId": "I39BinT2gsN9", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "9_Geo Map View_image.png" + }, + { + "attachmentId": "IeXU8SLZU7Oz", + "title": "image.jpg", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "Geo Map View_image.jpg" + }, + { + "attachmentId": "Mb9kRm63MxjE", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "10_Geo Map View_image.png" + }, + { + "attachmentId": "Mx2xwNIk76ZS", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "11_Geo Map View_image.png" + }, + { + "attachmentId": "oaahbsMRbqd2", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "12_Geo Map View_image.png" + }, + { + "attachmentId": "pGf1p74KKGU4", + "title": "image.png", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "13_Geo Map View_image.png" + }, + { + "attachmentId": "tfa1TRUatWEh", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "14_Geo Map View_image.png" + }, + { + "attachmentId": "tuNZ7Uk9WfX1", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "15_Geo Map View_image.png" + }, + { + "attachmentId": "x6yBLIsY2LSv", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "16_Geo Map View_image.png" + }, + { + "attachmentId": "yJMyBRYA3Kwi", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "17_Geo Map View_image.png" + }, + { + "attachmentId": "ZvTlu9WMd37z", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "18_Geo Map View_image.png" } ] } @@ -7937,201 +8183,6 @@ } ] }, - { - "isClone": false, - "noteId": "81SGnPGMk7Xc", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "81SGnPGMk7Xc" - ], - "title": "Geo Map", - "notePosition": 200, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "XpOYSgsLkTJy", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-map-alt", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Geo Map.md", - "attachments": [ - { - "attachmentId": "1f07O0Z25ZRr", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Geo Map_image.png" - }, - { - "attachmentId": "3oh61qhNLu7D", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Geo Map_image.png" - }, - { - "attachmentId": "aCSNn9QlgHFi", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_Geo Map_image.png" - }, - { - "attachmentId": "aCuXZY7WV4li", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "3_Geo Map_image.png" - }, - { - "attachmentId": "agH6yREFgsoU", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "4_Geo Map_image.png" - }, - { - "attachmentId": "AHyDUM6R5HeG", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "5_Geo Map_image.png" - }, - { - "attachmentId": "CcjWLhE3KKfv", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "6_Geo Map_image.png" - }, - { - "attachmentId": "DapDey8gMiFc", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "7_Geo Map_image.png" - }, - { - "attachmentId": "fQy8R1vxKhwN", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "8_Geo Map_image.png" - }, - { - "attachmentId": "gJ4Yz80jxcbn", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "9_Geo Map_image.png" - }, - { - "attachmentId": "I39BinT2gsN9", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "10_Geo Map_image.png" - }, - { - "attachmentId": "IeXU8SLZU7Oz", - "title": "image.jpg", - "role": "image", - "mime": "image/jpg", - "position": 10, - "dataFileName": "Geo Map_image.jpg" - }, - { - "attachmentId": "Mb9kRm63MxjE", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "11_Geo Map_image.png" - }, - { - "attachmentId": "Mx2xwNIk76ZS", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "12_Geo Map_image.png" - }, - { - "attachmentId": "oaahbsMRbqd2", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "13_Geo Map_image.png" - }, - { - "attachmentId": "pGf1p74KKGU4", - "title": "image.png", - "role": "image", - "mime": "image/jpg", - "position": 10, - "dataFileName": "14_Geo Map_image.png" - }, - { - "attachmentId": "tfa1TRUatWEh", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "15_Geo Map_image.png" - }, - { - "attachmentId": "x6yBLIsY2LSv", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "16_Geo Map_image.png" - }, - { - "attachmentId": "yJMyBRYA3Kwi", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "17_Geo Map_image.png" - }, - { - "attachmentId": "ZvTlu9WMd37z", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "18_Geo Map_image.png" - } - ] - }, { "isClone": false, "noteId": "W8vYD3Q1zjCR", diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/Labels.md b/docs/User Guide/User Guide/Advanced Usage/Attributes/Labels.md index 54233914a..8182e3876 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Attributes/Labels.md +++ b/docs/User Guide/User Guide/Advanced Usage/Attributes/Labels.md @@ -39,4 +39,4 @@ This is a list of labels that Trilium natively supports. > [!TIP] > Some labels presented here end with a `*`. That means that there are multiple labels with the same prefix, consult the specific page linked in the description of that label for more information. -
    LabelDescription
    disableVersioningDisables automatic creation of Note Revisions for a particular note. Useful for e.g. large, but unimportant notes - e.g. large JS libraries used for scripting.
    versioningLimitLimits the maximum number of Note Revisions for a particular note, overriding the global settings.
    calendarRootMarks the note which should be used as root for Day Notes. Only one should be marked as such.
    archivedHides notes from default search results and dialogs. Archived notes can optionally be hidden in the Note Tree.
    excludeFromExportExcludes this note and its children when exporting.
    run, runOnInstance, runAtHourSee Events.
    disableInclusionScripts with this label won't be included into parent script execution.
    sorted

    Keeps child notes sorted by title alphabetically.

    When given a value, it will sort by the value of another label instead. If one of the child notes doesn't have the specified label, the title will be used for them instead.

    sortDirection

    If sorted is applied, specifies the direction of the sort:

    • ASC, ascending (default)
    • DESC, descending
    sortFoldersFirstIf sorted is applied, folders (notes with children) will be sorted as a group at the top, and the rest will be sorted.
    topIf sorted is applied to the parent note, keeps given note on top in its parent.
    hidePromotedAttributesHide Promoted Attributes on this note. Generally useful when defining inherited attributes, but the parent note doesn't need them.
    readOnlyMarks a note to be always be read-only, if it's a supported note (text, code, mermaid).
    autoReadOnlyDisabledDisables automatic read-only mode for the given note.
    appCssMarks CSS notes which are loaded into the Trilium application and can thus be used to modify Trilium's looks. See Custom app-wide CSS for more info.
    appThemeMarks CSS notes which are full Trilium themes and are thus available in Trilium options. See Theme development for more information.
    appThemeBaseSet to next, next-light, or next-dark to use the corresponding TriliumNext theme (auto, light or dark) as the base for a custom theme, instead of the legacy one. See Customize the Next theme for more information.
    cssClassValue of this label is then added as CSS class to the node representing given note in the Note Tree. This can be useful for advanced theming. Can be used in template notes.
    iconClassvalue of this label is added as a CSS class to the icon on the tree which can help visually distinguish the notes in the tree. Example might be bx bx-home - icons are taken from boxicons. Can be used in template notes.
    pageSizeSpecifies the number of items per page in Note List.
    customRequestHandlerSee Custom Request Handler.
    customResourceProviderSee Custom Resource Providers.
    widgetMarks this note as a custom widget which will be added to the Trilium component tree. See Custom Widgets for more information.
    searchHomeNew search notes will be created as children of this note (see Saved Search).
    workspace and related attributesSee Workspaces.
    inboxdefault inbox location for new notes - when you create a note using new note button in the sidebar, notes will be created as child notes in the note marked as with #inbox label.
    sqlConsoleHomeDefault location of SQL Console notes
    bookmarkedIndicates this note is a bookmark.
    bookmarkFolderNote with this label will appear in bookmarks as folder (allowing access to its children). See Bookmarks for more information.
    share*See the attribute reference in Sharing.
    displayRelations, hideRelationsComma delimited names of relations which should be displayed/hidden in a Relation Map (both the note type and the Note Map (Link map, Tree map) general functionality).
    titleTemplate

    Default title of notes created as children of this note. This value is evaluated as a JavaScript string and thus can be enriched with dynamic content via the injected now and parentNote variables.

    Examples:

    • \({parentNote.getLabel('authorName')}'s literary works
    • Log for \){now.format('YYYY-MM-DD HH:mm:ss')}
    • to mirror the parent's template.

    See Default Note Title for more info.

    templateThis note will appear in the selection of available template when creating new note. See Templates for more information.
    tocControls the display of the Table of contents for a given note. #toc or #toc=show to always display the table of contents, #toc=false to always hide it.
    colordefines color of the note in note tree, links etc. Use any valid CSS color value like 'red' or #a13d5f
    keyboardShortcutDefines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect.
    keepCurrentHoistingOpening this link won't change hoisting even if the note is not displayable in the current hoisted subtree.
    executeButtonTitle of the button which will execute the current code note
    executeDescriptionLonger description of the current code note displayed together with the execute button
    excludeFromNoteMapNotes with this label will be hidden from the Note Map.
    newNotesOnTopNew notes will be created at the top of the parent note, not on the bottom.
    hideHighlightWidgetHides the Highlights list widget
    hideChildrenOverviewHides the Note List for that particular note.
    printLandscapeWhen exporting to PDF, changes the orientation of the page to landscape instead of portrait.
    printPageSizeWhen exporting to PDF, changes the size of the page. Supported values: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.
    geolocationIndicates the latitude and longitude of a note, to be displayed in a Geo Map.
    calendar:*Defines specific options for the Calendar View.
    viewTypeSets the view of child notes (e.g. grid or list). See Note List for more information.
    \ No newline at end of file +
    LabelDescription
    disableVersioningDisables automatic creation of Note Revisions for a particular note. Useful for e.g. large, but unimportant notes - e.g. large JS libraries used for scripting.
    versioningLimitLimits the maximum number of Note Revisions for a particular note, overriding the global settings.
    calendarRootMarks the note which should be used as root for Day Notes. Only one should be marked as such.
    archivedHides notes from default search results and dialogs. Archived notes can optionally be hidden in the Note Tree.
    excludeFromExportExcludes this note and its children when exporting.
    run, runOnInstance, runAtHourSee Events.
    disableInclusionScripts with this label won't be included into parent script execution.
    sorted

    Keeps child notes sorted by title alphabetically.

    When given a value, it will sort by the value of another label instead. If one of the child notes doesn't have the specified label, the title will be used for them instead.

    sortDirection

    If sorted is applied, specifies the direction of the sort:

    • ASC, ascending (default)
    • DESC, descending
    sortFoldersFirstIf sorted is applied, folders (notes with children) will be sorted as a group at the top, and the rest will be sorted.
    topIf sorted is applied to the parent note, keeps given note on top in its parent.
    hidePromotedAttributesHide Promoted Attributes on this note. Generally useful when defining inherited attributes, but the parent note doesn't need them.
    readOnlyMarks a note to be always be read-only, if it's a supported note (text, code, mermaid).
    autoReadOnlyDisabledDisables automatic read-only mode for the given note.
    appCssMarks CSS notes which are loaded into the Trilium application and can thus be used to modify Trilium's looks. See Custom app-wide CSS for more info.
    appThemeMarks CSS notes which are full Trilium themes and are thus available in Trilium options. See Theme development for more information.
    appThemeBaseSet to next, next-light, or next-dark to use the corresponding TriliumNext theme (auto, light or dark) as the base for a custom theme, instead of the legacy one. See Customize the Next theme for more information.
    cssClassValue of this label is then added as CSS class to the node representing given note in the Note Tree. This can be useful for advanced theming. Can be used in template notes.
    iconClassvalue of this label is added as a CSS class to the icon on the tree which can help visually distinguish the notes in the tree. Example might be bx bx-home - icons are taken from boxicons. Can be used in template notes.
    pageSizeSpecifies the number of items per page in Note List.
    customRequestHandlerSee Custom Request Handler.
    customResourceProviderSee Custom Resource Providers.
    widgetMarks this note as a custom widget which will be added to the Trilium component tree. See Custom Widgets for more information.
    searchHomeNew search notes will be created as children of this note (see Saved Search).
    workspace and related attributesSee Workspaces.
    inboxdefault inbox location for new notes - when you create a note using new note button in the sidebar, notes will be created as child notes in the note marked as with #inbox label.
    sqlConsoleHomeDefault location of SQL Console notes
    bookmarkedIndicates this note is a bookmark.
    bookmarkFolderNote with this label will appear in bookmarks as folder (allowing access to its children). See Bookmarks for more information.
    share*See the attribute reference in Sharing.
    displayRelations, hideRelationsComma delimited names of relations which should be displayed/hidden in a Relation Map (both the note type and the Note Map (Link map, Tree map) general functionality).
    titleTemplate

    Default title of notes created as children of this note. This value is evaluated as a JavaScript string and thus can be enriched with dynamic content via the injected now and parentNote variables.

    Examples:

    • \({parentNote.getLabel('authorName')}'s literary works
    • Log for \){now.format('YYYY-MM-DD HH:mm:ss')}
    • to mirror the parent's template.

    See Default Note Title for more info.

    templateThis note will appear in the selection of available template when creating new note. See Templates for more information.
    tocControls the display of the Table of contents for a given note. #toc or #toc=show to always display the table of contents, #toc=false to always hide it.
    colordefines color of the note in note tree, links etc. Use any valid CSS color value like 'red' or #a13d5f
    keyboardShortcutDefines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect.
    keepCurrentHoistingOpening this link won't change hoisting even if the note is not displayable in the current hoisted subtree.
    executeButtonTitle of the button which will execute the current code note
    executeDescriptionLonger description of the current code note displayed together with the execute button
    excludeFromNoteMapNotes with this label will be hidden from the Note Map.
    newNotesOnTopNew notes will be created at the top of the parent note, not on the bottom.
    hideHighlightWidgetHides the Highlights list widget
    hideChildrenOverviewHides the Note List for that particular note.
    printLandscapeWhen exporting to PDF, changes the orientation of the page to landscape instead of portrait.
    printPageSizeWhen exporting to PDF, changes the size of the page. Supported values: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.
    geolocationIndicates the latitude and longitude of a note, to be displayed in a Geo Map.
    calendar:*Defines specific options for the Calendar View.
    viewTypeSets the view of child notes (e.g. grid or list). See Note List for more information.
    \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Note source.md b/docs/User Guide/User Guide/Advanced Usage/Note source.md index 26986739e..8338f3477 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Note source.md +++ b/docs/User Guide/User Guide/Advanced Usage/Note source.md @@ -7,7 +7,7 @@ For example: *
    Text notes are represented internally as HTML, using the CKEditor representation. Note that due to the custom plugins, some HTML elements are specific to Trilium only, for example the admonitions. * Code notes are plain text and are represented internally as-is. -* Geo Map notes contain only minimal information (viewport, zoom) as a JSON. +* Geo Map notes contain only minimal information (viewport, zoom) as a JSON. * Canvas notes are represented as JSON, with Trilium's own information alongside with Excalidraw's internal JSON representation format. * Mind Map notes are represented as JSON, with the internal format of MindElixir. diff --git a/docs/User Guide/User Guide/Advanced Usage/Sharing.md b/docs/User Guide/User Guide/Advanced Usage/Sharing.md index 9e03163f4..49542c9b6 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Sharing.md +++ b/docs/User Guide/User Guide/Advanced Usage/Sharing.md @@ -16,7 +16,7 @@ Trilium allows you to share selected notes as **publicly accessible** read-only ### By note type -
     Supported featuresLimitations
    Text
    • Table of contents.
    • Syntax highlight of code blocks, provided a language is selected (does not work if “Auto-detected” is enabled).
    • Rendering for math equations.
    • Including notes is not supported.
    • Inline Mermaid diagrams are not rendered.
    Code
    • Basic support (displaying the contents of the note in a monospace font).
    • No syntax highlight.
    Saved SearchNot supported.
    Relation MapNot supported.
    Note MapNot supported.
    Render NoteNot supported.
    Book
    • The child notes are displayed in a fixed format. 
    • More advanced view types such as the calendar view are not supported.
    Mermaid Diagrams
    • The diagram is displayed as a vector image.
    • No further interaction supported.
    Canvas
    • The diagram is displayed as a vector image.
    • No further interaction supported.
    Web ViewNot supported.
    Mind MapThe diagram is displayed as a vector image.
    • No further interaction supported.
    Geo MapNot supported.
    FileBasic interaction (downloading the file).
    • No further interaction supported.
    +
     Supported featuresLimitations
    Text
    • Table of contents.
    • Syntax highlight of code blocks, provided a language is selected (does not work if “Auto-detected” is enabled).
    • Rendering for math equations.
    • Including notes is not supported.
    • Inline Mermaid diagrams are not rendered.
    Code
    • Basic support (displaying the contents of the note in a monospace font).
    • No syntax highlight.
    Saved SearchNot supported.
    Relation MapNot supported.
    Note MapNot supported.
    Render NoteNot supported.
    Book
    • The child notes are displayed in a fixed format. 
    • More advanced view types such as the calendar view are not supported.
    Mermaid Diagrams
    • The diagram is displayed as a vector image.
    • No further interaction supported.
    Canvas
    • The diagram is displayed as a vector image.
    • No further interaction supported.
    Web ViewNot supported.
    Mind MapThe diagram is displayed as a vector image.
    • No further interaction supported.
    Geo MapNot supported.
    FileBasic interaction (downloading the file).
    • No further interaction supported.
    While the sharing feature is powerful, it has some limitations: diff --git a/docs/User Guide/User Guide/Advanced Usage/Technologies used/Leaflet.md b/docs/User Guide/User Guide/Advanced Usage/Technologies used/Leaflet.md index ae773acca..bcf692d0e 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Technologies used/Leaflet.md +++ b/docs/User Guide/User Guide/Advanced Usage/Technologies used/Leaflet.md @@ -1,5 +1,5 @@ # Leaflet -Leaflet is the library behind [Geo map](../../Note%20Types/Geo%20Map.md) notes. +Leaflet is the library behind [Geo map](../../Basic%20Concepts%20and%20Features/Notes/Note%20List/Geo%20Map%20View.md) notes. ## Plugins diff --git a/docs/User Guide/User Guide/Note Types/11_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/10_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/11_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/10_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/12_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/11_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/12_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/11_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/13_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/12_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/13_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/12_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/14_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/13_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/14_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/13_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/15_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/14_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/15_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/14_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/15_Geo Map View_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/15_Geo Map View_image.png new file mode 100644 index 000000000..72dbb9861 Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/15_Geo Map View_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/16_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/16_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/16_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/16_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/17_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/17_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/17_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/17_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/18_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/18_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/18_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/18_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/1_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/1_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/1_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/1_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/2_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/2_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/2_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/2_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/3_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/3_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/3_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/3_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/4_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/4_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/4_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/4_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/5_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/5_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/5_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/5_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/6_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/6_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/6_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/6_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/8_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/7_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/8_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/7_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/9_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/8_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/9_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/8_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Note Types/10_Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/9_Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/10_Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/9_Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View.md new file mode 100644 index 000000000..05bf48662 --- /dev/null +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View.md @@ -0,0 +1,133 @@ +# Geo Map View +> [!IMPORTANT] +> Starting with Trilium v0.97.0, the geo map has been converted from a standalone [note type](../../../Note%20Types.md) to a type of view for the Note List.  + +
    + +This note type displays the children notes on a geographical map, based on an attribute. It is also possible to add new notes at a specific location using the built-in interface. + +## Creating a new geo map + +
       
    1
    Right click on any note on the note tree and select Insert child noteGeo Map (beta).
    2
    By default the map will be empty and will show the entire world.
    + +## Repositioning the map + +* Click and drag the map in order to move across the map. +* Use the mouse wheel, two-finger gesture on a touchpad or the +/- buttons on the top-left to adjust the zoom. + +The position on the map and the zoom are saved inside the map note and restored when visiting again the note. + +## Adding a marker using the map + +### Adding a new note using the plus button + +
       
    1To create a marker, first navigate to the desired point on the map. Then press the button in the Floating buttons (top-right) area. 

    If the button is not visible, make sure the button section is visible by pressing the chevron button () in the top-right of the map.
     
    2Once pressed, the map will enter in the insert mode, as illustrated by the notification.    

    Simply click the point on the map where to place the marker, or the Escape key to cancel.
    3Enter the name of the marker/note to be created.
    4Once confirmed, the marker will show up on the map and it will also be displayed as a child note of the map.
    + +### Adding a new note using the contextual menu + +1. Right click anywhere on the map, where to place the newly created marker (and corresponding note). +2. Select _Add a marker at this location_. +3. Enter the name of the newly created note. +4. The map should be updated with the new marker. + +### Adding an existing note on note from the note tree + +1. Select the desired note in the Note Tree. +2. Hold the mouse on the note and drag it to the map to the desired location. +3. The map should be updated with the new marker. + +This works for: + +* Notes that are not part of the geo map, case in which a [clone](../Cloning%20Notes.md) will be created. +* Notes that are a child of the geo map but not yet positioned on the map. +* Notes that are a child of the geo map and also positioned, case in which the marker will be relocated to the new position. + +## How the location of the markers is stored + +The location of a marker is stored in the `#geolocation` attribute of the child notes: + + + +This value can be added manually if needed. The value of the attribute is made up of the latitude and longitude separated by a comma. + +## Repositioning markers + +It's possible to reposition existing markers by simply drag and dropping them to the new destination. + +As soon as the mouse is released, the new position is saved. + +If moved by mistake, there is currently no way to undo the change. If the mouse was not yet released, it's possible to force a refresh of the page (Ctrl+R ) to cancel it. + +## Interaction with the markers + +* Hovering over a marker will display the content of the note it belongs to. + * Clicking on the note title in the tooltip will navigate to the note in the current view. +* Middle-clicking the marker will open the note in a new tab. +* Right-clicking the marker will open a contextual menu allowing: + +## Contextual menu + +It's possible to press the right mouse button to display a contextual menu. + +1. If right-clicking an empty section of the map (not on a marker), it allows to: + 1. Displays the latitude and longitude. Clicking this option will copy them to the clipboard. + 2. Open the location using an external application (if the operating system supports it). + 3. Adding a new marker at that location. +2. If right-clicking on a marker, it allows to: + 1. Displays the latitude and longitude. Clicking this option will copy them to the clipboard. + 2. Open the location using an external application (if the operating system supports it). + 3. Open the note in a new tab, split or window. + 4. Remove the marker from the map, which will remove the `#geolocation` attribute of the note. To add it back again, the coordinates have to be manually added back in. + +## Icon and color of the markers + +
    image
    + +The markers will have the same icon as the note. + +It's possible to add a custom color to a marker by assigning them a `#color` attribute such as `#color=green`. + +## Adding the coordinates manually + +In a nutshell, create a child note and set the `#geolocation` attribute to the coordinates. + +The value of the attribute is made up of the latitude and longitude separated by a comma. + +### Adding from Google Maps + +
       
    1
    Go to Google Maps on the web and look for a desired location, right click on it and a context menu will show up.    

    Simply click on the first item displaying the coordinates and they will be copied to clipboard.    

    Then paste the value inside the text box into the #geolocation attribute of a child note of the map (don't forget to surround the value with a " character).
    2
    In Trilium, create a child note under the map.
    3
    And then go to Owned Attributes and type #geolocation=", then paste from the clipboard as-is and then add the ending " character. Press Enter to confirm and the map should now be updated to contain the new note.
    + +### Adding from OpenStreetMap + +Similarly to the Google Maps approach: + +
       
    1Go to any location on openstreetmap.org and right click to bring up the context menu. Select the “Show address” item.
    2The address will be visible in the top-left of the screen, in the place of the search bar.    

    Select the coordinates and copy them into the clipboard.
    3Simply paste the value inside the text box into the #geolocation attribute of a child note of the map and then it should be displayed on the map.
    + +## Adding GPS tracks (.gpx) + +Trilium has basic support for displaying GPS tracks on the geo map. + +
       
    1
    To add a track, simply drag & drop a .gpx file inside the geo map in the note tree.
    2
    In order for the file to be recognized as a GPS track, it needs to show up as application/gpx+xml in the File type field.
    3
    When going back to the map, the track should now be visible.    

    The start and end points of the track are indicated by the two blue markers.
    + +> [!NOTE] +> The starting point of the track will be displayed as a marker, with the name of the note underneath. The start marker will also respect the icon and the `color` of the note. The end marker is displayed with a distinct icon. +> +> If the GPX contains waypoints, they will also be displayed. If they have a name, it is displayed when hovering over it with the mouse. + +## Read-only mode + +When a map is in read-only all editing features will be disabled such as: + +* The add button in the Floating buttons. +* Dragging markers. +* Editing from the contextual menu (removing locations or adding new items). + +To enable read-only mode simply press the _Lock_ icon from the Floating buttons. To disable it, press the button again. + +## Troubleshooting + +
    + +### Grid-like artifacts on the map + +This occurs if the application is not at 100% zoom which causes the pixels of the map to not render correctly due to fractional scaling. The only possible solution is to set the UI zoom at 100% (default keyboard shortcut is Ctrl+0). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Geo Map_image.jpg b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View_image.jpg similarity index 100% rename from docs/User Guide/User Guide/Note Types/Geo Map_image.jpg rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View_image.jpg diff --git a/docs/User Guide/User Guide/Note Types/Geo Map_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Geo Map_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Geo Map View_image.png diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View.md similarity index 98% rename from docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table.md rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View.md index 26e33353a..3a0dc0e8f 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View.md @@ -1,5 +1,5 @@ -# Table -
    +# Table View +
    The table view displays information in a grid, where the rows are individual notes and the columns are Promoted Attributes. In addition, values are editable. diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View_image.png similarity index 100% rename from docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table_image.png rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List/Table View_image.png diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.md index 7811c5d6c..38ab3f584 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.md @@ -39,4 +39,5 @@ When pressed, the note will become editable but will become read-only again afte Some note types have a special behavior based on whether the read-only mode is enabled: -* Mermaid Diagrams will hide the Mermaid source code and display the diagram preview in full-size. In this case, the read-only mode can be easily toggled on or off via a dedicated button in the Floating buttons area. \ No newline at end of file +* Mermaid Diagrams will hide the Mermaid source code and display the diagram preview in full-size. In this case, the read-only mode can be easily toggled on or off via a dedicated button in the Floating buttons area. +* Geo Map View will disallow all interaction that would otherwise change the map (dragging notes, adding new items). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types.md b/docs/User Guide/User Guide/Note Types.md index 71e510a11..c5870964c 100644 --- a/docs/User Guide/User Guide/Note Types.md +++ b/docs/User Guide/User Guide/Note Types.md @@ -25,4 +25,4 @@ It is possible to change the type of a note after it has been created via the _B The following note types are supported by Trilium: -
    Note TypeDescription
    TextThe default note type, which allows for rich text formatting, images, admonitions and right-to-left support.
    CodeUses a mono-space font and can be used to store larger chunks of code or plain text than a text note, and has better syntax highlighting.
    Saved SearchStores the information about a search (the search text, criteria, etc.) for later use. Can be used for quick filtering of a large amount of notes, for example. The search can easily be triggered.
    Relation MapAllows easy creation of notes and relations between them. Can be used for mainly relational data such as a family tree.
    Note MapDisplays the relationships between the notes, whether via relations or their hierarchical structure.
    Render NoteUsed in Scripting, it displays the HTML content of another note. This allows displaying any kind of content, provided there is a script behind it to generate it.
    Book

    Displays the children of the note either as a grid, a list, or for a more specialized case: a calendar.

    Generally useful for easy reading of short notes.

    Mermaid DiagramsDisplays diagrams such as bar charts, flow charts, state diagrams, etc. Requires a bit of technical knowledge since the diagrams are written in a specialized format.
    CanvasAllows easy drawing of sketches, diagrams, handwritten content. Uses the same technology behind excalidraw.com.
    Web ViewDisplays the content of an external web page, similar to a browser.
    Mind MapEasy for brainstorming ideas, by placing them in a hierarchical layout.
    Geo MapDisplays the children of the note as a geographical map, one use-case would be to plan vacations. It even has basic support for tracks. Notes can also be created from it.
    FileRepresents an uploaded file such as PDFs, images, video or audio files.
    \ No newline at end of file +
    Note TypeDescription
    TextThe default note type, which allows for rich text formatting, images, admonitions and right-to-left support.
    CodeUses a mono-space font and can be used to store larger chunks of code or plain text than a text note, and has better syntax highlighting.
    Saved SearchStores the information about a search (the search text, criteria, etc.) for later use. Can be used for quick filtering of a large amount of notes, for example. The search can easily be triggered.
    Relation MapAllows easy creation of notes and relations between them. Can be used for mainly relational data such as a family tree.
    Note MapDisplays the relationships between the notes, whether via relations or their hierarchical structure.
    Render NoteUsed in Scripting, it displays the HTML content of another note. This allows displaying any kind of content, provided there is a script behind it to generate it.
    Book

    Displays the children of the note either as a grid, a list, or for a more specialized case: a calendar.

    Generally useful for easy reading of short notes.

    Mermaid DiagramsDisplays diagrams such as bar charts, flow charts, state diagrams, etc. Requires a bit of technical knowledge since the diagrams are written in a specialized format.
    CanvasAllows easy drawing of sketches, diagrams, handwritten content. Uses the same technology behind excalidraw.com.
    Web ViewDisplays the content of an external web page, similar to a browser.
    Mind MapEasy for brainstorming ideas, by placing them in a hierarchical layout.
    Geo MapDisplays the children of the note as a geographical map, one use-case would be to plan vacations. It even has basic support for tracks. Notes can also be created from it.
    FileRepresents an uploaded file such as PDFs, images, video or audio files.
    \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/7_Geo Map_image.png b/docs/User Guide/User Guide/Note Types/7_Geo Map_image.png deleted file mode 100644 index 00c5e8cc3..000000000 Binary files a/docs/User Guide/User Guide/Note Types/7_Geo Map_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Note Types/Geo Map.md b/docs/User Guide/User Guide/Note Types/Geo Map.md deleted file mode 100644 index 78237cad3..000000000 --- a/docs/User Guide/User Guide/Note Types/Geo Map.md +++ /dev/null @@ -1,88 +0,0 @@ -# Geo Map -
    - -This note type displays the children notes on a geographical map, based on an attribute. It is also possible to add new notes at a specific location using the built-in interface. - -## Creating a new geo map - -
       
    1
    Right click on any note on the note tree and select Insert child noteGeo Map (beta).
    2
    By default the map will be empty and will show the entire world.
    - -## Repositioning the map - -* Click and drag the map in order to move across the map. -* Use the mouse wheel, two-finger gesture on a touchpad or the +/- buttons on the top-left to adjust the zoom. - -The position on the map and the zoom are saved inside the map note and restored when visiting again the note. - -## Adding a marker using the map - -
       
    1To create a marker, first navigate to the desired point on the map. Then press the button in the Floating buttons (top-right) area. 

    If the button is not visible, make sure the button section is visible by pressing the chevron button () in the top-right of the map.
     
    2Once pressed, the map will enter in the insert mode, as illustrated by the notification.    

    Simply click the point on the map where to place the marker, or the Escape key to cancel.
    3Enter the name of the marker/note to be created.
    4Once confirmed, the marker will show up on the map and it will also be displayed as a child note of the map.
    - -## How the location of the markers is stored - -The location of a marker is stored in the `#geolocation` attribute of the child notes: - - - -This value can be added manually if needed. The value of the attribute is made up of the latitude and longitude separated by a comma. - -## Repositioning markers - -It's possible to reposition existing markers by simply drag and dropping them to the new destination. - -As soon as the mouse is released, the new position is saved. - -If moved by mistake, there is currently no way to undo the change. If the mouse was not yet released, it's possible to force a refresh of the page (Ctrl+R ) to cancel it. - -## Interaction with the markers - -* Hovering over a marker will display the content of the note it belongs to. - * Clicking on the note title in the tooltip will navigate to the note in the current view. -* Middle-clicking the marker will open the note in a new tab. -* Right-clicking the marker will open a contextual menu allowing: - * Opening the note in a new tab, split or window. - * Opening the location using an external application (if the operating system supports it). - * Removing the marker from the map, which will remove the `#geolocation` attribute of the note. To add it back again, the coordinates have to be manually added back in. - -## Icon and color of the markers - -
    image
    - -The markers will have the same icon as the note. - -It's possible to add a custom color to a marker by assigning them a `#color` attribute such as `#color=green`. - -## Adding the coordinates manually - -In a nutshell, create a child note and set the `#geolocation` attribute to the coordinates. - -The value of the attribute is made up of the latitude and longitude separated by a comma. - -### Adding from Google Maps - -
       
    1
    Go to Google Maps on the web and look for a desired location, right click on it and a context menu will show up.    

    Simply click on the first item displaying the coordinates and they will be copied to clipboard.    

    Then paste the value inside the text box into the #geolocation attribute of a child note of the map (don't forget to surround the value with a " character).
    2
    In Trilium, create a child note under the map.
    3
    And then go to Owned Attributes and type #geolocation=", then paste from the clipboard as-is and then add the ending " character. Press Enter to confirm and the map should now be updated to contain the new note.
    - -### Adding from OpenStreetMap - -Similarly to the Google Maps approach: - -
       
    1Go to any location on openstreetmap.org and right click to bring up the context menu. Select the “Show address” item.
    2The address will be visible in the top-left of the screen, in the place of the search bar.    

    Select the coordinates and copy them into the clipboard.
    3Simply paste the value inside the text box into the #geolocation attribute of a child note of the map and then it should be displayed on the map.
    - -## Adding GPS tracks (.gpx) - -Trilium has basic support for displaying GPS tracks on the geo map. - -
       
    1
    To add a track, simply drag & drop a .gpx file inside the geo map in the note tree.
    2
    In order for the file to be recognized as a GPS track, it needs to show up as application/gpx+xml in the File type field.
    3
    When going back to the map, the track should now be visible.    

    The start and end points of the track are indicated by the two blue markers.
    - -> [!NOTE] -> The starting point of the track will be displayed as a marker, with the name of the note underneath. The start marker will also respect the icon and the `color` of the note. The end marker is displayed with a distinct icon. -> -> If the GPX contains waypoints, they will also be displayed. If they have a name, it is displayed when hovering over it with the mouse. - -## Troubleshooting - -
    - -### Grid-like artifacts on the map - -This occurs if the application is not at 100% zoom which causes the pixels of the map to not render correctly due to fractional scaling. The only possible solution is to set the UI zoom at 100% (default keyboard shortcut is Ctrl+0). \ No newline at end of file diff --git a/packages/commons/src/lib/hidden_subtree.ts b/packages/commons/src/lib/hidden_subtree.ts index af860aba8..8440fdeb3 100644 --- a/packages/commons/src/lib/hidden_subtree.ts +++ b/packages/commons/src/lib/hidden_subtree.ts @@ -1,6 +1,4 @@ -import type { AttributeType } from "./rows.js"; - -type LauncherNoteType = "launcher" | "search" | "doc" | "noteMap" | "contentWidget" | "book" | "file" | "image" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "webView" | "code" | "mindMap" | "geoMap"; +type LauncherNoteType = "launcher" | "search" | "doc" | "noteMap" | "contentWidget" | "book" | "file" | "image" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "webView" | "code" | "mindMap"; enum Command { jumpToNote, diff --git a/packages/commons/src/lib/rows.ts b/packages/commons/src/lib/rows.ts index a407d8001..d45b1eb16 100644 --- a/packages/commons/src/lib/rows.ts +++ b/packages/commons/src/lib/rows.ts @@ -119,8 +119,7 @@ export const ALLOWED_NOTE_TYPES = [ "book", "webView", "code", - "mindMap", - "geoMap" + "mindMap" ] as const; export type NoteType = (typeof ALLOWED_NOTE_TYPES)[number]; diff --git a/scripts/generate-openapi.ts b/scripts/generate-openapi.ts index 0a5d6a861..d2a074e66 100644 --- a/scripts/generate-openapi.ts +++ b/scripts/generate-openapi.ts @@ -158,7 +158,7 @@ console.log("Saved to", outputPath); * type: * type: string * example: "text" - * enum: ["text", "code", "render", "file", "image", "search", "relationMap", "book", "noteMap", "mermaid", "canvas", "webView", "launcher", "doc", "contentWidget", "mindMap", "geoMap"] + * enum: ["text", "code", "render", "file", "image", "search", "relationMap", "book", "noteMap", "mermaid", "canvas", "webView", "launcher", "doc", "contentWidget", "mindMap"] * description: "[Reference list](https://github.com/TriliumNext/Trilium/blob/v0.91.6/src/services/note_types.ts)" * mime: * type: string