mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-28 18:42:28 +08:00
Merge branch 'develop' into feat_friendly-numbers-note-revision
This commit is contained in:
commit
c2e4def523
25
.github/workflows/main-docker.yml
vendored
25
.github/workflows/main-docker.yml
vendored
@ -100,7 +100,20 @@ jobs:
|
||||
|
||||
build:
|
||||
name: Build Docker images
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- dockerfile: Dockerfile.alpine
|
||||
platform: linux/amd64
|
||||
image: ubuntu-latest
|
||||
- dockerfile: Dockerfile
|
||||
platform: linux/arm64
|
||||
image: ubuntu-24.04-arm
|
||||
- dockerfile: Dockerfile
|
||||
platform: linux/arm/v7
|
||||
image: ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.image }}
|
||||
needs:
|
||||
- test_docker
|
||||
permissions:
|
||||
@ -108,16 +121,6 @@ jobs:
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- dockerfile: Dockerfile.alpine
|
||||
platform: linux/amd64
|
||||
- dockerfile: Dockerfile
|
||||
platform: linux/arm64
|
||||
- dockerfile: Dockerfile
|
||||
platform: linux/arm/v7
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
|
833
package-lock.json
generated
833
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@ -49,7 +49,7 @@
|
||||
"build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
|
||||
"build:prepare-dist": "npm run build:webpack && rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
|
||||
|
||||
"test": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest",
|
||||
"test": "cross-env TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest",
|
||||
"test:coverage": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest --coverage",
|
||||
"test:playwright": "playwright test",
|
||||
|
||||
@ -167,14 +167,14 @@
|
||||
"yauzl": "3.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "7.6.1",
|
||||
"@electron-forge/maker-deb": "7.6.1",
|
||||
"@electron-forge/maker-dmg": "7.6.1",
|
||||
"@electron-forge/maker-flatpak": "7.6.1",
|
||||
"@electron-forge/maker-rpm": "7.6.1",
|
||||
"@electron-forge/maker-squirrel": "7.6.1",
|
||||
"@electron-forge/maker-zip": "7.6.1",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.6.1",
|
||||
"@electron-forge/cli": "7.7.0",
|
||||
"@electron-forge/maker-deb": "7.7.0",
|
||||
"@electron-forge/maker-dmg": "7.7.0",
|
||||
"@electron-forge/maker-flatpak": "7.7.0",
|
||||
"@electron-forge/maker-rpm": "7.7.0",
|
||||
"@electron-forge/maker-squirrel": "7.7.0",
|
||||
"@electron-forge/maker-zip": "7.7.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.7.0",
|
||||
"@electron/rebuild": "3.7.1",
|
||||
"@playwright/test": "1.50.1",
|
||||
"@types/archiver": "6.0.3",
|
||||
@ -212,7 +212,7 @@
|
||||
"@types/ws": "8.5.14",
|
||||
"@types/xml2js": "0.4.14",
|
||||
"@types/yargs": "17.0.33",
|
||||
"@vitest/coverage-v8": "3.0.5",
|
||||
"@vitest/coverage-v8": "3.0.6",
|
||||
"cross-env": "7.0.3",
|
||||
"electron": "34.2.0",
|
||||
"esm": "3.2.25",
|
||||
@ -224,10 +224,10 @@
|
||||
"rimraf": "6.0.1",
|
||||
"swagger-jsdoc": "6.2.8",
|
||||
"tslib": "2.8.1",
|
||||
"tsx": "4.19.2",
|
||||
"tsx": "4.19.3",
|
||||
"typedoc": "0.27.7",
|
||||
"typescript": "5.7.3",
|
||||
"vitest": "3.0.5",
|
||||
"vitest": "3.0.6",
|
||||
"webpack": "5.98.0",
|
||||
"webpack-cli": "6.0.1",
|
||||
"webpack-dev-middleware": "7.4.2"
|
||||
|
@ -4,6 +4,8 @@ import { t } from "../../services/i18n.js";
|
||||
import type { EventData } from "../../components/app_context.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
|
||||
const TEXT_MAX_NUM_CHARS = 5000;
|
||||
|
||||
const TPL = `
|
||||
<div class="note-detail-file note-detail-printable">
|
||||
<style>
|
||||
@ -29,6 +31,10 @@ const TPL = `
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="file-preview-too-big alert alert-info hidden-ext">
|
||||
${t("file.too_big", { maxNumChars: TEXT_MAX_NUM_CHARS })}
|
||||
</div>
|
||||
|
||||
<pre class="file-preview-content"></pre>
|
||||
|
||||
<div class="file-preview-not-available alert alert-info">
|
||||
@ -46,6 +52,7 @@ export default class FileTypeWidget extends TypeWidget {
|
||||
|
||||
private $previewContent!: JQuery<HTMLElement>;
|
||||
private $previewNotAvailable!: JQuery<HTMLElement>;
|
||||
private $previewTooBig!: JQuery<HTMLElement>;
|
||||
private $pdfPreview!: JQuery<HTMLElement>;
|
||||
private $videoPreview!: JQuery<HTMLElement>;
|
||||
private $audioPreview!: JQuery<HTMLElement>;
|
||||
@ -58,6 +65,7 @@ export default class FileTypeWidget extends TypeWidget {
|
||||
this.$widget = $(TPL);
|
||||
this.$previewContent = this.$widget.find(".file-preview-content");
|
||||
this.$previewNotAvailable = this.$widget.find(".file-preview-not-available");
|
||||
this.$previewTooBig = this.$widget.find(".file-preview-too-big");
|
||||
this.$pdfPreview = this.$widget.find(".pdf-preview");
|
||||
this.$videoPreview = this.$widget.find(".video-preview");
|
||||
this.$audioPreview = this.$widget.find(".audio-preview");
|
||||
@ -73,12 +81,17 @@ export default class FileTypeWidget extends TypeWidget {
|
||||
this.$previewContent.empty().hide();
|
||||
this.$pdfPreview.attr("src", "").empty().hide();
|
||||
this.$previewNotAvailable.hide();
|
||||
this.$previewTooBig.addClass("hidden-ext");
|
||||
this.$videoPreview.hide();
|
||||
this.$audioPreview.hide();
|
||||
|
||||
if (blob?.content) {
|
||||
this.$previewContent.show().scrollTop(0);
|
||||
this.$previewContent.text(blob.content);
|
||||
const trimmedContent = blob.content.substring(0, TEXT_MAX_NUM_CHARS);
|
||||
if (trimmedContent.length !== blob.content.length) {
|
||||
this.$previewTooBig.removeClass("hidden-ext");
|
||||
}
|
||||
this.$previewContent.text(trimmedContent);
|
||||
} else if (note.mime === "application/pdf") {
|
||||
this.$pdfPreview.show().attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open`));
|
||||
} else if (note.mime.startsWith("video/")) {
|
||||
|
@ -222,7 +222,7 @@ export default class GeoMapTypeWidget extends TypeWidget {
|
||||
|
||||
const [ lat, lng ] = latLng.split(",", 2).map((el) => parseFloat(el));
|
||||
const L = this.L;
|
||||
const icon = this.#buildIcon(note.getIcon(), note.title);
|
||||
const icon = this.#buildIcon(note.getIcon(), note.getColorClass(), note.title);
|
||||
|
||||
const marker = L.marker(L.latLng(lat, lng), {
|
||||
icon,
|
||||
@ -257,12 +257,12 @@ export default class GeoMapTypeWidget extends TypeWidget {
|
||||
this.currentMarkerData[note.noteId] = marker;
|
||||
}
|
||||
|
||||
#buildIcon(bxIconClass: string, title: string) {
|
||||
#buildIcon(bxIconClass: string, colorClass: string, title: string) {
|
||||
return this.L.divIcon({
|
||||
html: `\
|
||||
<img class="icon" src="${asset_path}/node_modules/leaflet/dist/images/marker-icon.png" />
|
||||
<img class="icon-shadow" src="${asset_path}/node_modules/leaflet/dist/images/marker-shadow.png" />
|
||||
<span class="bx ${bxIconClass}"></span>
|
||||
<span class="bx ${bxIconClass} ${colorClass}"></span>
|
||||
<span class="title-label">${title}</span>`,
|
||||
iconSize: [ 25, 41 ],
|
||||
iconAnchor: [ 12, 41 ]
|
||||
@ -361,7 +361,7 @@ export default class GeoMapTypeWidget extends TypeWidget {
|
||||
// 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) => at.name === LOCATION_ATTRIBUTE)) {
|
||||
if (attributeRows.find((at) => [ LOCATION_ATTRIBUTE, "color" ].includes(at.name ?? ""))) {
|
||||
this.#reloadMarkers();
|
||||
}
|
||||
}
|
||||
|
@ -988,7 +988,7 @@
|
||||
"web_view": {
|
||||
"web_view": "网页视图",
|
||||
"embed_websites": "网页视图类型的笔记允许您将网站嵌入到 Trilium 中。",
|
||||
"create_label": "首先,请创建一个带有您要嵌入的 URL 地址的标签,例如 #webViewSrc=\"https://www.bing.com\"",
|
||||
"create_label": "首先,请创建一个带有您要嵌入的 URL 地址的标签,例如 #webViewSrc=\"https://www.bing.com\""
|
||||
},
|
||||
"backend_log": {
|
||||
"refresh": "刷新"
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"about": {
|
||||
"title": "Über TriliumNext Notes",
|
||||
"close": "Schließen",
|
||||
"homepage": "Startseite:",
|
||||
"app_version": "App-Version:",
|
||||
"db_version": "DB-Version:",
|
||||
@ -52,10 +53,15 @@
|
||||
"chosen_actions": "Ausgewählte Aktionen",
|
||||
"execute_bulk_actions": "Massenaktionen ausführen",
|
||||
"bulk_actions_executed": "Massenaktionen wurden erfolgreich ausgeführt.",
|
||||
"none_yet": "Noch keine ... Füge eine Aktion hinzu, indem du oben auf eine der verfügbaren Aktionen klicken."
|
||||
"none_yet": "Noch keine ... Füge eine Aktion hinzu, indem du oben auf eine der verfügbaren Aktionen klicken.",
|
||||
"labels": "Labels",
|
||||
"relations": "Beziehungen",
|
||||
"notes": "Notizen",
|
||||
"other": "Andere"
|
||||
},
|
||||
"clone_to": {
|
||||
"clone_notes_to": "Notizen klonen nach...",
|
||||
"close":"Schließen",
|
||||
"help_on_links": "Hilfe zu Links",
|
||||
"notes_to_clone": "Notizen zum Klonen",
|
||||
"target_parent_note": "Ziel-Übergeordnetenotiz",
|
||||
@ -68,6 +74,7 @@
|
||||
},
|
||||
"confirm": {
|
||||
"confirmation": "Bestätigung",
|
||||
"close":"Schließen",
|
||||
"cancel": "Abbrechen",
|
||||
"ok": "OK",
|
||||
"are_you_sure_remove_note": "Bist du sicher, dass du \"{{title}}\" von der Beziehungskarte entfernen möchten? ",
|
||||
@ -76,6 +83,7 @@
|
||||
},
|
||||
"delete_notes": {
|
||||
"delete_notes_preview": "Vorschau der Notizen löschen",
|
||||
"close": "Schließen",
|
||||
"delete_all_clones_description": "auch alle Klone löschen (kann bei letzte Änderungen rückgängig gemacht werden)",
|
||||
"erase_notes_description": "Beim normalen (vorläufigen) Löschen werden die Notizen nur als gelöscht markiert und sie können innerhalb eines bestimmten Zeitraums (im Dialogfeld „Letzte Änderungen“) wiederhergestellt werden. Wenn du diese Option aktivierst, werden die Notizen sofort gelöscht und es ist nicht möglich, die Notizen wiederherzustellen.",
|
||||
"erase_notes_warning": "Notizen dauerhaft löschen (kann nicht rückgängig gemacht werden), einschließlich aller Klone. Dadurch wird ein Neuladen der Anwendung erzwungen.",
|
||||
@ -83,12 +91,15 @@
|
||||
"no_note_to_delete": "Es werden keine Notizen gelöscht (nur Klone).",
|
||||
"broken_relations_to_be_deleted": "Folgende Beziehungen werden gelöst und gelöscht (<span class=\"broke-relations-count\"></span>)",
|
||||
"cancel": "Abbrechen",
|
||||
"ok": "OK"
|
||||
"ok": "OK",
|
||||
"deleted_relation_text": "Notiz {{- note}} (soll gelöscht werden) wird von Beziehung {{- relation}} ausgehend von {{- source}} referenziert."
|
||||
|
||||
},
|
||||
"export": {
|
||||
"export_note_title": "Notiz exportieren",
|
||||
"close": "Schließen",
|
||||
"export_type_subtree": "Diese Notiz und alle ihre Unternotizen",
|
||||
"format_html": "HTML - empfohlen, da dadurch alle Formatierungen erhalten bleiben",
|
||||
"format_html_zip": "HTML im ZIP-Archiv – dies wird empfohlen, da dadurch die gesamte Formatierung erhalten bleibt.",
|
||||
"format_markdown": "Markdown – dadurch bleiben die meisten Formatierungen erhalten.",
|
||||
"format_opml": "OPML – Outliner-Austauschformat nur für Text. Formatierungen, Bilder und Dateien sind nicht enthalten.",
|
||||
@ -99,7 +110,8 @@
|
||||
"choose_export_type": "Bitte wähle zuerst den Exporttypen aus",
|
||||
"export_status": "Exportstatus",
|
||||
"export_in_progress": "Export läuft: {{progressCount}}",
|
||||
"export_finished_successfully": "Der Export wurde erfolgreich abgeschlossen."
|
||||
"export_finished_successfully": "Der Export wurde erfolgreich abgeschlossen.",
|
||||
"format_pdf": "PDF - für Ausdrucke oder Teilen."
|
||||
},
|
||||
"help": {
|
||||
"fullDocumentation": "Hilfe (gesamte Dokumentation ist <a class=\"external\" href=\"https://triliumnext.github.io/Docs/\">online</a> verfügbar)",
|
||||
@ -171,10 +183,20 @@
|
||||
"codeImportedAsCode": "Importiere erkannte Codedateien (z. B. <code>.json</code>) als Codenotizen, wenn die Metadaten unklar sind",
|
||||
"replaceUnderscoresWithSpaces": "Ersetze Unterstriche in importierten Notiznamen durch Leerzeichen",
|
||||
"import": "Import",
|
||||
"failed": "Import fehlgeschlagen: {{message}}."
|
||||
"failed": "Import fehlgeschlagen: {{message}}.",
|
||||
"html_import_tags": {
|
||||
"title": "HTML Tag Import",
|
||||
"description": "Festlegen, welche HTML tags beim Import von Notizen beibehalten werden sollen. Tags, die nicht in dieser Liste stehen, werden beim Import entfernt. Einige tags (wie bspw. 'script') werden aus Sicherheitsgründen immer entfernt.",
|
||||
"placeholder": "HTML tags eintragen, pro Zeile nur einer pro Zeile",
|
||||
"reset_button": "Zur Standardliste zurücksetzen"
|
||||
},
|
||||
"import-status": "Importstatus",
|
||||
"in-progress": "Import läuft: {{progress}}",
|
||||
"successful": "Import erfolgreich abgeschlossen."
|
||||
},
|
||||
"include_note": {
|
||||
"dialog_title": "Notiz beifügen",
|
||||
"close": "Schließen",
|
||||
"label_note": "Notiz",
|
||||
"placeholder_search": "Suche nach einer Notiz anhand ihres Namens",
|
||||
"box_size_prompt": "Kartongröße des beigelegten Zettels:",
|
||||
@ -190,16 +212,19 @@
|
||||
},
|
||||
"jump_to_note": {
|
||||
"search_placeholder": "Suche nach einer Notiz anhand ihres Namens",
|
||||
"close": "Schließen",
|
||||
"search_button": "Suche im Volltext: <kbd>Strg+Eingabetaste</kbd>"
|
||||
},
|
||||
"markdown_import": {
|
||||
"dialog_title": "Markdown-Import",
|
||||
"close": "Schließen",
|
||||
"modal_body_text": "Aufgrund der Browser-Sandbox ist es nicht möglich, die Zwischenablage direkt aus JavaScript zu lesen. Bitte füge den zu importierenden Markdown in den Textbereich unten ein und klicke auf die Schaltfläche „Importieren“.",
|
||||
"import_button": "Importieren Strg+Eingabe",
|
||||
"import_success": "Markdown-Inhalt wurde in das Dokument importiert."
|
||||
},
|
||||
"move_to": {
|
||||
"dialog_title": "Notizen verschieben nach ...",
|
||||
"close": "Schließen",
|
||||
"notes_to_move": "Notizen zum Verschieben",
|
||||
"target_parent_note": "Ziel-Elternnotiz",
|
||||
"search_placeholder": "Suche nach einer Notiz anhand ihres Namens",
|
||||
@ -209,16 +234,19 @@
|
||||
},
|
||||
"note_type_chooser": {
|
||||
"modal_title": "Wähle den Notiztyp aus",
|
||||
"close": "Schließen",
|
||||
"modal_body": "Wähle den Notiztyp / die Vorlage der neuen Notiz:",
|
||||
"templates": "Vorlagen:"
|
||||
},
|
||||
"password_not_set": {
|
||||
"title": "Das Passwort ist nicht festgelegt",
|
||||
"close": "Schließen",
|
||||
"body1": "Geschützte Notizen werden mit einem Benutzerpasswort verschlüsselt, es wurde jedoch noch kein Passwort festgelegt.",
|
||||
"body2": "Um Notizen verschlüsseln zu können, klicke <a class=\"open-password-options-button\" href=\"javascript:\">hier</a> um das Optionsmenu zu öffnen und ein Passwort zu setzen."
|
||||
},
|
||||
"prompt": {
|
||||
"title": "Prompt",
|
||||
"close": "Schließen",
|
||||
"ok": "OK <kbd>Eingabe</kbd>",
|
||||
"defaultTitle": "Prompt"
|
||||
},
|
||||
@ -232,6 +260,7 @@
|
||||
"recent_changes": {
|
||||
"title": "Aktuelle Änderungen",
|
||||
"erase_notes_button": "Jetzt gelöschte Notizen löschen",
|
||||
"close": "Schließen",
|
||||
"deleted_notes_message": "Gelöschte Notizen wurden gelöscht.",
|
||||
"no_changes_message": "Noch keine Änderungen...",
|
||||
"undelete_link": "Wiederherstellen",
|
||||
@ -242,6 +271,7 @@
|
||||
"delete_all_revisions": "Lösche alle Revisionen dieser Notiz",
|
||||
"delete_all_button": "Alle Revisionen löschen",
|
||||
"help_title": "Hilfe zu Notizrevisionen",
|
||||
"close": "Schließen",
|
||||
"revision_last_edited": "Diese Revision wurde zuletzt am {{date}} bearbeitet",
|
||||
"confirm_delete_all": "Möchtest du alle Revisionen dieser Notiz löschen? Durch diese Aktion werden der Titel und der Inhalt der Revision gelöscht, die Metadaten der Revision bleiben jedoch erhalten.",
|
||||
"no_revisions": "Für diese Notiz gibt es noch keine Revisionen...",
|
||||
@ -249,9 +279,9 @@
|
||||
"confirm_restore": "Möchtest du diese Revision wiederherstellen? Dadurch werden der aktuelle Titel und Inhalt der Notiz mit dieser Revision überschrieben.",
|
||||
"delete_button": "Lösche diese Revision",
|
||||
"confirm_delete": "Möchtest du diese Revision löschen? Durch diese Aktion werden der Titel und der Inhalt der Revision gelöscht, die Metadaten der Revision bleiben jedoch erhalten.",
|
||||
"revisions_deleted": "Hinweisrevisionen wurden gelöscht.",
|
||||
"revisions_deleted": "Notizrevisionen wurden gelöscht.",
|
||||
"revision_restored": "Die Notizrevision wurde wiederhergestellt.",
|
||||
"revision_deleted": "Hinweisrevision wurde gelöscht.",
|
||||
"revision_deleted": "Notizrevision wurde gelöscht.",
|
||||
"snapshot_interval": "Notizrevisionen-Snapshot Intervall: {{seconds}}s.",
|
||||
"maximum_revisions": "Maximale Revisionen für aktuelle Notiz: {{number}}.",
|
||||
"settings": "Einstellungen für Notizrevisionen",
|
||||
@ -263,6 +293,7 @@
|
||||
},
|
||||
"sort_child_notes": {
|
||||
"sort_children_by": "Unternotizen sortieren nach...",
|
||||
"close": "Schließen",
|
||||
"sorting_criteria": "Sortierkriterien",
|
||||
"title": "Titel",
|
||||
"date_created": "Erstellungsdatum",
|
||||
@ -280,6 +311,7 @@
|
||||
},
|
||||
"upload_attachments": {
|
||||
"upload_attachments_to_note": "Lade Anhänge zur Notiz hoch",
|
||||
"close": "Schließen",
|
||||
"choose_files": "Wähle Dateien aus",
|
||||
"files_will_be_uploaded": "Dateien werden als Anhänge in hochgeladen",
|
||||
"options": "Optionen",
|
||||
@ -338,13 +370,14 @@
|
||||
"disable_inclusion": "Skripte mit dieser Bezeichnung werden nicht in die Ausführung des übergeordneten Skripts einbezogen.",
|
||||
"sorted": "Hält untergeordnete Notizen alphabetisch nach Titel sortiert",
|
||||
"sort_direction": "ASC (Standard) oder DESC",
|
||||
"sort_folders_first": "Ordner (Notizen mit Kindern) sollten oben sortiert werden",
|
||||
"sort_folders_first": "Ordner (Notizen mit Unternotizen) sollten oben sortiert werden",
|
||||
"top": "Behalte die angegebene Notiz oben in der übergeordneten Notiz (gilt nur für sortierte übergeordnete Notizen).",
|
||||
"hide_promoted_attributes": "Heraufgestufte Attribute für diese Notiz ausblenden",
|
||||
"read_only": "Der Editor befindet sich im schreibgeschützten Modus. Funktioniert nur für Text- und Codenotizen.",
|
||||
"auto_read_only_disabled": "Text-/Codenotizen können automatisch in den Lesemodus versetzt werden, wenn sie zu groß sind. Du kannst dieses Verhalten für jede einzelne Notiz deaktivieren, indem du diese Beschriftung zur Notiz hinzufügst",
|
||||
"app_css": "markiert CSS-Notizen, die in die Trilium-Anwendung geladen werden und somit zur Änderung des Aussehens von Trilium verwendet werden können.",
|
||||
"app_theme": "markiert CSS-Notizen, die vollständige Trilium-Themen sind und daher in den Trilium-Optionen verfügbar sind.",
|
||||
"app_theme_base": "markiert Notiz als \"nächste\" in der Reihe für ein Trilium-Theme als Grundlage für ein Custom-Theme. Ersetzt damit das Standard Theme.",
|
||||
"css_class": "Der Wert dieser Bezeichnung wird dann als CSS-Klasse dem Knoten hinzugefügt, der die angegebene Notiz im Baum darstellt. Dies kann für fortgeschrittene Themen nützlich sein. Kann in Vorlagennotizen verwendet werden.",
|
||||
"icon_class": "Der Wert dieser Bezeichnung wird als CSS-Klasse zum Symbol im Baum hinzugefügt, was dabei helfen kann, die Notizen im Baum visuell zu unterscheiden. Beispiel könnte bx bx-home sein – Symbole werden von Boxicons übernommen. Kann in Vorlagennotizen verwendet werden.",
|
||||
"page_size": "Anzahl der Elemente pro Seite in der Notizliste",
|
||||
@ -406,7 +439,9 @@
|
||||
"share_favicon": "Favicon-Notiz, die auf der freigegebenen Seite festgelegt werden soll. Normalerweise möchtest du es so einstellen, dass es Root teilt und es vererbbar macht. Die Favicon-Notiz muss sich ebenfalls im freigegebenen Unterbaum befinden. Erwäge die Verwendung von „share_hidden_from_tree“.",
|
||||
"is_owned_by_note": "ist Eigentum von Note",
|
||||
"other_notes_with_name": "Other notes with {{attributeType}} name \"{{attributeName}}\"",
|
||||
"and_more": "... und {{count}} mehr."
|
||||
"and_more": "... und {{count}} mehr.",
|
||||
"print_landscape": "Beim Export als PDF, wird die Seitenausrichtung Querformat anstatt Hochformat verwendet.",
|
||||
"print_page_size": "Beim Export als PDF, wird die Größe der Seite angepasst. Unterstützte Größen: <code>A0</code>, <code>A1</code>, <code>A2</code>, <code>A3</code>, <code>A4</code>, <code>A5</code>, <code>A6</code>, <code>Legal</code>, <code>Letter</code>, <code>Tabloid</code>, <code>Ledger</code>."
|
||||
},
|
||||
"attribute_editor": {
|
||||
"help_text_body1": "Um ein Label hinzuzufügen, gebe einfach z.B. ein. <code>#rock</code> oder wenn du auch einen Wert hinzufügen möchten, dann z.B. <code>#year = 2024</code>",
|
||||
@ -491,7 +526,7 @@
|
||||
"example_note": "<code>Notiz</code> – alle übereinstimmenden Notizen werden in „Notiz“ umbenannt.",
|
||||
"example_new_title": "<code>NEU: ${note.title}</code> – Übereinstimmende Notiztitel erhalten das Präfix „NEU:“",
|
||||
"example_date_prefix": "<code>${note.dateCreatedObj.format('MM-DD:')}: ${note.title}</code> – übereinstimmende Notizen werden mit dem Erstellungsmonat und -datum der Notiz vorangestellt",
|
||||
"api_docs": "Siehe API-Dokumente für <a hrefu003d'https://zadam.github.io/trilium/backend_api/Note.html'>Hinweis</a> und seinen <a hrefu003d'https://day.js.org/ docs/en/display/format'>dateCreatedObj / utcDateCreatedObj-Eigenschaften</a> für Details."
|
||||
"api_docs": "Siehe API-Dokumente für <a hrefu003d'https://zadam.github.io/trilium/backend_api/Note.html'>Notiz</a> und seinen <a hrefu003d'https://day.js.org/ docs/en/display/format'>dateCreatedObj / utcDateCreatedObj-Eigenschaften</a> für Details."
|
||||
},
|
||||
"add_relation": {
|
||||
"add_relation": "Beziehung hinzufügen",
|
||||
@ -596,7 +631,7 @@
|
||||
"zoom_in": "Hineinzoomen",
|
||||
"configure_launchbar": "Konfiguriere die Launchbar",
|
||||
"show_shared_notes_subtree": "Unterbaum „Freigegebene Notizen“ anzeigen",
|
||||
"advanced": "Fortschrittlich",
|
||||
"advanced": "Erweitert",
|
||||
"open_dev_tools": "Öffne die Entwicklungstools",
|
||||
"open_sql_console": "Öffne die SQL-Konsole",
|
||||
"open_sql_console_history": "Öffne den SQL-Konsolenverlauf",
|
||||
@ -607,7 +642,9 @@
|
||||
"show_hidden_subtree": "Versteckten Teilbaum anzeigen",
|
||||
"show_help": "Hilfe anzeigen",
|
||||
"about": "Über TriliumNext Notes",
|
||||
"logout": "Abmelden"
|
||||
"logout": "Abmelden",
|
||||
"show-cheatsheet": "Cheatsheet anzeigen",
|
||||
"toggle-zen-mode": "Zen Modus"
|
||||
},
|
||||
"sync_status": {
|
||||
"unknown": "<p>Der Synchronisations-Status wird bekannt, sobald der nächste Synchronisierungsversuch gestartet wird.</p><p>Klicke, um eine Synchronisierung jetzt auszulösen.</p>",
|
||||
@ -641,7 +678,8 @@
|
||||
"save_revision": "Revision speichern",
|
||||
"convert_into_attachment_failed": "Konvertierung der Notiz '{{title}}' fehlgeschlagen.",
|
||||
"convert_into_attachment_successful": "Notiz '{{title}}' wurde als Anhang konvertiert.",
|
||||
"convert_into_attachment_prompt": "Bist du dir sicher, dass du die Notiz '{{title}}' in ein Anhang der übergeordneten Notiz konvertieren möchtest?"
|
||||
"convert_into_attachment_prompt": "Bist du dir sicher, dass du die Notiz '{{title}}' in ein Anhang der übergeordneten Notiz konvertieren möchtest?",
|
||||
"print_pdf": "Export als PDF..."
|
||||
},
|
||||
"onclick_button": {
|
||||
"no_click_handler": "Das Schaltflächen-Widget „{{componentId}}“ hat keinen definierten Klick-Handler"
|
||||
@ -715,7 +753,8 @@
|
||||
"collapse": "Einklappen",
|
||||
"expand": "Ausklappen",
|
||||
"book_properties": "Bucheigenschaften",
|
||||
"invalid_view_type": "Ungültiger Ansichtstyp „{{type}}“"
|
||||
"invalid_view_type": "Ungültiger Ansichtstyp „{{type}}“",
|
||||
"calendar": "Kalender"
|
||||
},
|
||||
"edited_notes": {
|
||||
"no_edited_notes_found": "An diesem Tag wurden noch keine Notizen bearbeitet...",
|
||||
@ -759,15 +798,17 @@
|
||||
"note_size_info": "Die Notizgröße bietet eine grobe Schätzung des Speicherbedarfs für diese Notiz. Es berücksichtigt den Inhalt der Notiz und den Inhalt ihrer Notizrevisionen.",
|
||||
"calculate": "berechnen",
|
||||
"subtree_size": "(Teilbaumgröße: {{size}} in {{count}} Notizen)",
|
||||
"title": "Hinweisinfo"
|
||||
"title": "Notizinfo"
|
||||
},
|
||||
"note_map": {
|
||||
"open_full": "Vollständig erweitern",
|
||||
"collapse": "Auf normale Größe reduzieren",
|
||||
"title": "Hinweiskarte"
|
||||
"title": "Notizkarte",
|
||||
"fix-nodes": "Knoten fixieren",
|
||||
"link-distance": "Verbindungslänge"
|
||||
},
|
||||
"note_paths": {
|
||||
"title": "Hinweispfade",
|
||||
"title": "Notizpfade",
|
||||
"clone_button": "Notiz an neuen Speicherort klonen...",
|
||||
"intro_placed": "Diese Notiz wird in den folgenden Pfaden abgelegt:",
|
||||
"intro_not_placed": "Diese Notiz ist noch nicht im Notizbaum platziert.",
|
||||
@ -864,7 +905,7 @@
|
||||
"content_and_attachments_size": "Beachte die Inhaltsgröße einschließlich der Anhänge",
|
||||
"content_and_attachments_and_revisions_size": "Beachte die Inhaltsgröße einschließlich Anhängen und Revisionen",
|
||||
"revision_count": "Anzahl der Revisionen",
|
||||
"children_count": "Anzahl der Kindernotizen",
|
||||
"children_count": "Anzahl der Unternotizen",
|
||||
"parent_count": "Anzahl der Klone",
|
||||
"owned_label_count": "Anzahl der Etiketten",
|
||||
"owned_relation_count": "Anzahl der Beziehungen",
|
||||
@ -900,14 +941,14 @@
|
||||
},
|
||||
"attachment_detail": {
|
||||
"open_help_page": "Hilfeseite zu Anhängen öffnen",
|
||||
"owning_note": "Hinweis zum Eigentümer:",
|
||||
"owning_note": "Eigentümernotiz: ",
|
||||
"you_can_also_open": ", Du kannst auch das öffnen",
|
||||
"list_of_all_attachments": "Liste aller Anhänge",
|
||||
"attachment_deleted": "Dieser Anhang wurde gelöscht."
|
||||
},
|
||||
"attachment_list": {
|
||||
"open_help_page": "Hilfeseite zu Anhängen öffnen",
|
||||
"owning_note": "Hinweis zum Eigentümer:",
|
||||
"owning_note": "Eigentümernotiz: ",
|
||||
"upload_attachments": "Anhänge hochladen",
|
||||
"no_attachments": "Diese Notiz enthält keine Anhänge."
|
||||
},
|
||||
@ -951,7 +992,7 @@
|
||||
"specify_new_relation_name": "Gebe den neuen Beziehungsnamen an (erlaubte Zeichen: alphanumerisch, Doppelpunkt und Unterstrich):",
|
||||
"connection_exists": "Die Verbindung „{{name}}“ zwischen diesen Notizen besteht bereits.",
|
||||
"start_dragging_relations": "Beginne hier mit dem Ziehen von Beziehungen und lege sie auf einer anderen Notiz ab.",
|
||||
"note_not_found": "Hinweis {{noteId}} nicht gefunden!",
|
||||
"note_not_found": "Notiz {{noteId}} nicht gefunden!",
|
||||
"cannot_match_transform": "Transformation kann nicht übereinstimmen: {{transform}}",
|
||||
"note_already_in_diagram": "Die Notiz \"{{title}}\" ist schon im Diagram.",
|
||||
"enter_title_of_new_note": "Gebe den Titel der neuen Notiz ein",
|
||||
@ -959,12 +1000,12 @@
|
||||
"click_on_canvas_to_place_new_note": "Klicke auf den Canvas, um eine neue Notiz zu platzieren"
|
||||
},
|
||||
"render": {
|
||||
"note_detail_render_help_1": "Dieser Hilfehinweis wird angezeigt, da dieser Hinweis vom Typ „HTML rendern“ nicht über die erforderliche Beziehung verfügt, um ordnungsgemäß zu funktionieren.",
|
||||
"note_detail_render_help_1": "Diese Hilfesnotiz wird angezeigt, da diese Notiz vom Typ „HTML rendern“ nicht über die erforderliche Beziehung verfügt, um ordnungsgemäß zu funktionieren.",
|
||||
"note_detail_render_help_2": "Render-HTML-Notiztyp wird benutzt für <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/scripts.html\">scripting</a>. Kurzgesagt, du hast ein HTML-Code-Notiz (optional mit JavaScript) und diese Notiz rendert es. Damit es funktioniert, musst du eine a <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/attributes.html\">Beziehung</a> namens \"renderNote\" zeigend auf die HTML-Notiz zum rendern definieren."
|
||||
},
|
||||
"web_view": {
|
||||
"web_view": "Webansicht",
|
||||
"embed_websites": "Hinweis vom Typ Web View ermöglicht das Einbetten von Websites in Trilium.",
|
||||
"embed_websites": "Notiz vom Typ Web View ermöglicht das Einbetten von Websites in Trilium.",
|
||||
"create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\""
|
||||
},
|
||||
"backend_log": {
|
||||
@ -1024,13 +1065,22 @@
|
||||
"main_font": "Handschrift",
|
||||
"font_family": "Schriftfamilie",
|
||||
"size": "Größe",
|
||||
"note_tree_font": "Hinweisbaum-Schriftart",
|
||||
"note_detail_font": "Hinweis-Detail-Schriftart",
|
||||
"note_tree_font": "Notizbaum-Schriftart",
|
||||
"note_detail_font": "Notiz-Detail-Schriftart",
|
||||
"monospace_font": "Minivan (Code) Schriftart",
|
||||
"note_tree_and_detail_font_sizing": "Beachte, dass die Größe der Baum- und Detailschriftarten relativ zur Hauptschriftgrößeneinstellung ist.",
|
||||
"not_all_fonts_available": "Möglicherweise sind nicht alle aufgelisteten Schriftarten auf Ihrem System verfügbar.",
|
||||
"apply_font_changes": "Um Schriftartänderungen zu übernehmen, klicke auf",
|
||||
"reload_frontend": "Frontend neu laden"
|
||||
"reload_frontend": "Frontend neu laden",
|
||||
"generic-fonts": "Generische Schriftarten",
|
||||
"sans-serif-system-fonts": "Sans-serif Systemschriftarten",
|
||||
"serif-system-fonts": "Serif Systemschriftarten",
|
||||
"monospace-system-fonts": "Monospace Systemschriftarten",
|
||||
"handwriting-system-fonts": "Handschrift Systemschriftarten",
|
||||
"serif": "Serif",
|
||||
"sans-serif": "Sans Serif",
|
||||
"monospace": "Monospace",
|
||||
"system-default": "System Standard"
|
||||
},
|
||||
"max_content_width": {
|
||||
"title": "Inhaltsbreite",
|
||||
@ -1054,8 +1104,17 @@
|
||||
"title": "Thema",
|
||||
"theme_label": "Thema",
|
||||
"override_theme_fonts_label": "Theme-Schriftarten überschreiben",
|
||||
"light_theme": "Licht",
|
||||
"dark_theme": "Dunkel"
|
||||
"auto_theme": "Auto",
|
||||
"light_theme": "Hell",
|
||||
"dark_theme": "Dunkel",
|
||||
"triliumnext": "TriliumNext Beta (Systemfarbschema folgend)",
|
||||
"triliumnext-light": "TriliumNext Beta (Hell)",
|
||||
"triliumnext-dark": "TriliumNext Beta (Dunkel)",
|
||||
"layout": "Layout",
|
||||
"layout-vertical-title": "Vertikal",
|
||||
"layout-horizontal-title": "Horizontal",
|
||||
"layout-vertical-description": "Startleiste ist auf der linken Seite (standard)",
|
||||
"layout-horizontal-description": "Startleiste ist unter der Tableiste. Die Tableiste wird dadurch auf die ganze Breite erweitert."
|
||||
},
|
||||
"zoom_factor": {
|
||||
"title": "Zoomfaktor (nur Desktop-Build)",
|
||||
@ -1181,6 +1240,8 @@
|
||||
"backup_now": "Jetzt sichern",
|
||||
"backup_database_now": "Jetzt Datenbank sichern",
|
||||
"existing_backups": "Vorhandene Backups",
|
||||
"date-and-time": "Datum & Uhrzeit",
|
||||
"path": "Pfad",
|
||||
"database_backed_up_to": "Die Datenbank wurde gesichert unter {{backupFilePath}}",
|
||||
"no_backup_yet": "noch kein Backup"
|
||||
},
|
||||
@ -1188,7 +1249,7 @@
|
||||
"title": "ETAPI",
|
||||
"description": "ETAPI ist eine REST-API, die für den programmgesteuerten Zugriff auf die Trilium-Instanz ohne Benutzeroberfläche verwendet wird.",
|
||||
"see_more": "Weitere Details findest du unter",
|
||||
"wiki": "Woche",
|
||||
"wiki": "Wiki",
|
||||
"and": "und",
|
||||
"openapi_spec": "ETAPI OpenAPI-Spezifikation",
|
||||
"create_token": "Erstelle ein neues ETAPI-Token",
|
||||
@ -1354,7 +1415,9 @@
|
||||
"launcher": "Launcher",
|
||||
"doc": "Dokument",
|
||||
"widget": "Widget",
|
||||
"confirm-change": "Es is nicht empfehlenswert den Notiz-Typ zu ändern, wenn der Inhalt der Notiz nicht leer ist. Möchtest du dennoch fortfahren?"
|
||||
"confirm-change": "Es is nicht empfehlenswert den Notiz-Typ zu ändern, wenn der Inhalt der Notiz nicht leer ist. Möchtest du dennoch fortfahren?",
|
||||
"geo-map": "Geo Map",
|
||||
"beta-feature": "Beta"
|
||||
},
|
||||
"protect_note": {
|
||||
"toggle-on": "Notiz schützen",
|
||||
@ -1377,7 +1440,11 @@
|
||||
"open-help-page": "Hilfeseite öffnen",
|
||||
"find": {
|
||||
"case_sensitive": "Groß-/Kleinschreibung beachten",
|
||||
"match_words": "Wörter genau übereinstimmen"
|
||||
"match_words": "Wörter genau übereinstimmen",
|
||||
"find_placeholder": "Finde in Text...",
|
||||
"replace_placeholder": "Ersetze mit...",
|
||||
"replace": "Ersetzen",
|
||||
"replace_all": "Alle Ersetzen"
|
||||
},
|
||||
"highlights_list_2": {
|
||||
"title": "Hervorhebungs-Liste",
|
||||
@ -1402,7 +1469,11 @@
|
||||
"automatically-collapse-notes-title": "Notizen werden nach einer Inaktivitätsperiode automatisch zusammengeklappt, um den Baum zu entlasten.",
|
||||
"save-changes": "Änderungen speichern und anwenden",
|
||||
"auto-collapsing-notes-after-inactivity": "Automatisches Zusammenklappen von Notizen nach Inaktivität…",
|
||||
"saved-search-note-refreshed": "Gespeicherte Such-Notiz wurde aktualisiert."
|
||||
"saved-search-note-refreshed": "Gespeicherte Such-Notiz wurde aktualisiert.",
|
||||
"hoist-this-note-workspace": "Diese Notiz fokussieren (Arbeitsbereich)",
|
||||
"refresh-saved-search-results": "Gespeicherte Suchergebnisse aktualisieren",
|
||||
"create-child-note": "Unternotiz anlegen",
|
||||
"unhoist": "Entfokussieren"
|
||||
},
|
||||
"title_bar_buttons": {
|
||||
"window-on-top": "Dieses Fenster immer oben halten"
|
||||
@ -1433,7 +1504,9 @@
|
||||
"close_other_tabs": "Andere Tabs schließen",
|
||||
"close_right_tabs": "Tabs rechts schließen",
|
||||
"close_all_tabs": "Alle Tabs schließen",
|
||||
"reopen_last_tab": "Zuletzt geschlossenen Tab erneut öffnen",
|
||||
"move_tab_to_new_window": "Tab in neues Fenster verschieben",
|
||||
"copy_tab_to_new_window": "Tab in neues Fenster kopieren",
|
||||
"new_tab": "Neuer Tab"
|
||||
},
|
||||
"toc": {
|
||||
@ -1485,7 +1558,7 @@
|
||||
"confirm_unhoisting": "Die angeforderte Notiz ‚{{requestedNote}}‘ befindet sich außerhalb des hoisted Bereichs der Notiz ‚{{hoistedNote}}‘. Du musst sie unhoisten, um auf die Notiz zuzugreifen. Möchtest du mit dem Unhoisting fortfahren?"
|
||||
},
|
||||
"launcher_context_menu": {
|
||||
"reset_launcher_confirm": "Möchtest du „{{title}}“ wirklich zurücksetzen? Alle Daten / Einstellungen in dieser Notiz (und ihren Kindern) gehen verloren und der Launcher wird an seinen ursprünglichen Standort zurückgesetzt.",
|
||||
"reset_launcher_confirm": "Möchtest du „{{title}}“ wirklich zurücksetzen? Alle Daten / Einstellungen in dieser Notiz (und ihren Unternotizen) gehen verloren und der Launcher wird an seinen ursprünglichen Standort zurückgesetzt.",
|
||||
"add-note-launcher": "Launcher für Notiz hinzufügen",
|
||||
"add-script-launcher": "Launcher für Skript hinzufügen",
|
||||
"add-custom-widget": "Benutzerdefiniertes Widget hinzufügen",
|
||||
@ -1506,5 +1579,84 @@
|
||||
},
|
||||
"code_block": {
|
||||
"word_wrapping": "Wortumbruch"
|
||||
},
|
||||
"classic_editor_toolbar": {
|
||||
"title": "Format"
|
||||
},
|
||||
"editor": {
|
||||
"title": "Editor"
|
||||
},
|
||||
"editing": {
|
||||
"editor_type": {
|
||||
"label": "Format Toolbar",
|
||||
"floating": {
|
||||
"title": "Schwebend",
|
||||
"description": "Werkzeuge erscheinen in Cursornähe"
|
||||
},
|
||||
"fixed": {
|
||||
"title": "Fixiert",
|
||||
"description": "Werkzeuge erscheinen im \"Format\" Tab"
|
||||
},
|
||||
"multiline-toolbar": "Toolbar wenn nötig in mehreren Zeilen darstellen."
|
||||
}
|
||||
},
|
||||
"electron_context_menu": {
|
||||
"add-term-to-dictionary": "Begriff \"{{term}}\" zum Wörterbuch hinzufügen",
|
||||
"cut": "Ausschneiden",
|
||||
"copy": "Kopieren",
|
||||
"copy-link": "Link opieren",
|
||||
"paste": "Einfügen",
|
||||
"paste-as-plain-text": "Als unformatierten Text einfügen",
|
||||
"search_online": "Suche nach \"{{term}}\" mit {{searchEngine}} starten"
|
||||
},
|
||||
"image_context_menu": {
|
||||
"copy_reference_to_clipboard": "Referenz in Zwischenablage kopieren",
|
||||
"copy_image_to_clipboard": "Bild in die Zwischenablage kopieren"
|
||||
},
|
||||
"link_context_menu": {
|
||||
"open_note_in_new_tab": "Notiz in neuen Tab öffnen",
|
||||
"open_note_in_new_split": "Notiz in neuen geteilten Tab öffnen",
|
||||
"open_note_in_new_window": "Notiz in neuen Fenster öffnen"
|
||||
},
|
||||
"electron_integration": {
|
||||
"desktop-application": "Desktop Anwendung",
|
||||
"native-title-bar": "Native Anwendungsleiste",
|
||||
"native-title-bar-description": "In Windows und macOS, sorgt das Deaktivieren der nativen Anwendungsleiste für ein kompakteres Aussehen. Unter Linux, sorgt das Aktivieren der nativen Anwendungsleiste für eine bessere Integration mit anderen Teilen des Systems.",
|
||||
"background-effects": "Hintergrundeffekte aktivieren (nur Windows 11)",
|
||||
"background-effects-description": "Der Mica Effekt fügt einen unscharfen, stylischen Hintergrund in Anwendungsfenstern ein. Dieser erzeugt Tiefe und ein modernes Auftreten.",
|
||||
"restart-app-button": "Anwendung neustarten um Änderungen anzuwenden",
|
||||
"zoom-factor": "Zoomfaktor"
|
||||
},
|
||||
"note_autocomplete": {
|
||||
"search-for": "Suche nach \"{{term}}\"",
|
||||
"create-note": "Erstelle und verlinke Unternotiz \"{{term}}\"",
|
||||
"insert-external-link": "Einfügen von Externen Link zu \"{{term}}\"",
|
||||
"clear-text-field": "Textfeldinhalt löschen",
|
||||
"show-recent-notes": "Aktuelle Notizen anzeigen",
|
||||
"full-text-search": "Volltextsuche"
|
||||
},
|
||||
"note_tooltip": {
|
||||
"note-has-been-deleted": "Notiz wurde gelöscht."
|
||||
},
|
||||
"geo-map": {
|
||||
"create-child-note-title": "Neue Unternotiz anlegen und zur Karte hinzufügen",
|
||||
"create-child-note-instruction": "Auf die Karte klicken, um eine neue Notiz an der Stelle zu erstellen oder Escape drücken um abzubrechen.",
|
||||
"unable-to-load-map": "Karte konnte nicht geladen werden."
|
||||
},
|
||||
"geo-map-context": {
|
||||
"open-location": "Ort öffnen",
|
||||
"remove-from-map": "Von Karte entfernen"
|
||||
},
|
||||
"help-button": {
|
||||
"title": "Relevante Hilfeseite öffnen"
|
||||
},
|
||||
"duration": {
|
||||
"seconds": "Sekunden",
|
||||
"minutes": "Minuten",
|
||||
"hours": "Stunden",
|
||||
"days": "Tage"
|
||||
},
|
||||
"time_selector": {
|
||||
"invalid_input": "Die eingegebene Zeit ist keine valide Zahl."
|
||||
}
|
||||
}
|
||||
|
@ -966,7 +966,8 @@
|
||||
"enter_workspace": "Enter workspace {{title}}"
|
||||
},
|
||||
"file": {
|
||||
"file_preview_not_available": "File preview is not available for this file format."
|
||||
"file_preview_not_available": "File preview is not available for this file format.",
|
||||
"too_big": "The preview only shows the first {{maxNumChars}} characters of the file for performance reasons. Download the file and open it externally to be able to see the entire content."
|
||||
},
|
||||
"protected_session": {
|
||||
"enter_password_instruction": "Showing protected note requires entering your password:",
|
||||
|
@ -5,7 +5,7 @@ import log from "../../services/log.js";
|
||||
import searchService from "../../services/search/services/search.js";
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
import type { Request } from "express";
|
||||
import { changeLanguage } from "../../services/i18n.js";
|
||||
import { changeLanguage, getLocales } from "../../services/i18n.js";
|
||||
import { listSyntaxHighlightingThemes } from "../../services/code_block_theme.js";
|
||||
import type { OptionNames } from "../../services/options_interface.js";
|
||||
|
||||
@ -155,37 +155,7 @@ function getSyntaxHighlightingThemes() {
|
||||
}
|
||||
|
||||
function getSupportedLocales() {
|
||||
// TODO: Currently hardcoded, needs to read the list of available languages.
|
||||
return [
|
||||
{
|
||||
id: "en",
|
||||
name: "English"
|
||||
},
|
||||
{
|
||||
id: "de",
|
||||
name: "Deutsch"
|
||||
},
|
||||
{
|
||||
id: "es",
|
||||
name: "Español"
|
||||
},
|
||||
{
|
||||
id: "fr",
|
||||
name: "Français"
|
||||
},
|
||||
{
|
||||
id: "cn",
|
||||
name: "简体中文"
|
||||
},
|
||||
{
|
||||
id: "tw",
|
||||
name: "繁體中文"
|
||||
},
|
||||
{
|
||||
id: "ro",
|
||||
name: "Română"
|
||||
}
|
||||
];
|
||||
return getLocales();
|
||||
}
|
||||
|
||||
function isAllowed(name: string) {
|
||||
|
26
src/services/i18n.spec.ts
Normal file
26
src/services/i18n.spec.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import * as i18n from "./i18n.js";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
function checkTranslations(translationDir: string, translationFileName: string) {
|
||||
const locales = i18n.getLocales();
|
||||
|
||||
for (const locale of locales) {
|
||||
const translationPath = path.join(translationDir, locale.id, translationFileName);
|
||||
const translationFile = fs.readFileSync(translationPath, { encoding: "utf-8" });
|
||||
expect(() => {
|
||||
JSON.parse(translationFile);
|
||||
}, `JSON error while parsing locale '${locale.id}' at "${translationPath}"`).not.toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
describe("i18n", () => {
|
||||
it("frontend translations are valid JSON", () => {
|
||||
checkTranslations("src/public/translations", "translation.json");
|
||||
});
|
||||
|
||||
it("backend translations are valid JSON", () => {
|
||||
checkTranslations("translations", "server.json");
|
||||
});
|
||||
});
|
@ -20,6 +20,40 @@ export async function initializeTranslations() {
|
||||
});
|
||||
}
|
||||
|
||||
export function getLocales() {
|
||||
// TODO: Currently hardcoded, needs to read the list of available languages.
|
||||
return [
|
||||
{
|
||||
id: "en",
|
||||
name: "English"
|
||||
},
|
||||
{
|
||||
id: "de",
|
||||
name: "Deutsch"
|
||||
},
|
||||
{
|
||||
id: "es",
|
||||
name: "Español"
|
||||
},
|
||||
{
|
||||
id: "fr",
|
||||
name: "Français"
|
||||
},
|
||||
{
|
||||
id: "cn",
|
||||
name: "简体中文"
|
||||
},
|
||||
{
|
||||
id: "tw",
|
||||
name: "繁體中文"
|
||||
},
|
||||
{
|
||||
id: "ro",
|
||||
name: "Română"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function getCurrentLanguage() {
|
||||
let language;
|
||||
if (sql_init.isDbInitialized()) {
|
||||
|
@ -88,7 +88,7 @@ function getType(options: TaskData, mime: string) {
|
||||
const mimeLc = mime?.toLowerCase();
|
||||
|
||||
switch (true) {
|
||||
case options.textImportedAsText && ["text/html", "text/markdown", "text/x-markdown"].includes(mimeLc):
|
||||
case options.textImportedAsText && ["text/html", "text/markdown", "text/x-markdown", "text/mdx"].includes(mimeLc):
|
||||
return "text";
|
||||
|
||||
case options.codeImportedAsCode && CODE_MIME_TYPES.has(mimeLc):
|
||||
|
21
src/services/import/samples/Text Note.mdx
Normal file
21
src/services/import/samples/Text Note.mdx
Normal file
@ -0,0 +1,21 @@
|
||||
Page 1
|
||||
|
||||
Heading 1
|
||||
---------
|
||||
|
||||
Heading 2
|
||||
---------
|
||||
|
||||
### Heading 3
|
||||
|
||||
```
|
||||
class Foo {
|
||||
hoistedNoteChangedEvent({ ntxId }) {
|
||||
if (this.isNoteContext(ntxId)) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Page 2
|
BIN
src/services/import/samples/mdx.zip
Normal file
BIN
src/services/import/samples/mdx.zip
Normal file
Binary file not shown.
49
src/services/import/single.spec.ts
Normal file
49
src/services/import/single.spec.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { dirname } from "path";
|
||||
import becca from "../../becca/becca.js";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import cls from "../cls.js";
|
||||
import sql_init from "../sql_init.js";
|
||||
import { initializeTranslations } from "../i18n.js";
|
||||
import single from "./single.js";
|
||||
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
describe("processNoteContent", () => {
|
||||
it("treats single MDX as Markdown", async () => {
|
||||
const mdxSample = fs.readFileSync(path.join(scriptDir, "samples", "Text Note.mdx"));
|
||||
const taskContext = TaskContext.getInstance("import-mdx", "import", {
|
||||
textImportedAsText: true
|
||||
});
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
cls.init(async () => {
|
||||
initializeTranslations();
|
||||
sql_init.initializeDb();
|
||||
await sql_init.dbReady;
|
||||
|
||||
const rootNote = becca.getNote("root");
|
||||
if (!rootNote) {
|
||||
reject("Missing root note.");
|
||||
}
|
||||
|
||||
const importedNote = single.importSingleFile(taskContext, {
|
||||
originalname: "Text Note.mdx",
|
||||
mimetype: "text/mdx",
|
||||
buffer: mdxSample
|
||||
}, rootNote as BNote);
|
||||
try {
|
||||
expect(importedNote.mime).toBe("text/html");
|
||||
expect(importedNote.type).toBe("text");
|
||||
expect(importedNote.title).toBe("Text Note");
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
@ -19,7 +19,7 @@ function importSingleFile(taskContext: TaskContext, file: File, parentNote: BNot
|
||||
if (taskContext?.data?.textImportedAsText) {
|
||||
if (mime === "text/html") {
|
||||
return importHtml(taskContext, file, parentNote);
|
||||
} else if (["text/markdown", "text/x-markdown"].includes(mime)) {
|
||||
} else if (["text/markdown", "text/x-markdown", "text/mdx"].includes(mime)) {
|
||||
return importMarkdown(taskContext, file, parentNote);
|
||||
} else if (mime === "text/plain") {
|
||||
return importPlainText(taskContext, file, parentNote);
|
||||
|
46
src/services/import/zip.spec.ts
Normal file
46
src/services/import/zip.spec.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { dirname } from "path";
|
||||
import zip from "./zip.js";
|
||||
import becca from "../../becca/becca.js";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import cls from "../cls.js";
|
||||
import sql_init from "../sql_init.js";
|
||||
import { initializeTranslations } from "../i18n.js";
|
||||
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
describe("processNoteContent", () => {
|
||||
it("treats single MDX as Markdown in ZIP as text note", async () => {
|
||||
const mdxSample = fs.readFileSync(path.join(scriptDir, "samples", "mdx.zip"));
|
||||
const taskContext = TaskContext.getInstance("import-mdx", "import", {
|
||||
textImportedAsText: true
|
||||
});
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
cls.init(async () => {
|
||||
initializeTranslations();
|
||||
sql_init.initializeDb();
|
||||
await sql_init.dbReady;
|
||||
|
||||
const rootNote = becca.getNote("root");
|
||||
if (!rootNote) {
|
||||
expect(rootNote).toBeTruthy();
|
||||
return;
|
||||
}
|
||||
|
||||
const importedNote = await zip.importZip(taskContext, mdxSample, rootNote as BNote);
|
||||
try {
|
||||
expect(importedNote.mime).toBe("text/mdx");
|
||||
expect(importedNote.type).toBe("text");
|
||||
expect(importedNote.title).toBe("Text Note");
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
@ -386,7 +386,7 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
|
||||
}
|
||||
|
||||
function processNoteContent(noteMeta: NoteMeta | undefined, type: string, mime: string, content: string | Buffer, noteTitle: string, filePath: string) {
|
||||
if ((noteMeta?.format === "markdown" || (!noteMeta && taskContext.data?.textImportedAsText && ["text/markdown", "text/x-markdown"].includes(mime))) && typeof content === "string") {
|
||||
if ((noteMeta?.format === "markdown" || (!noteMeta && taskContext.data?.textImportedAsText && ["text/markdown", "text/x-markdown", "text/mdx"].includes(mime))) && typeof content === "string") {
|
||||
content = markdownService.renderToHtml(content, noteTitle);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import { crash } from "./utils.js";
|
||||
import resourceDir from "./resource_dir.js";
|
||||
import appInfo from "./app_info.js";
|
||||
import cls from "./cls.js";
|
||||
import { t } from "i18next";
|
||||
|
||||
interface MigrationInfo {
|
||||
dbVersion: number;
|
||||
@ -18,9 +19,7 @@ async function migrate() {
|
||||
const currentDbVersion = getDbVersion();
|
||||
|
||||
if (currentDbVersion < 214) {
|
||||
log.error("Direct migration from your current version is not supported. Please upgrade to the latest v0.60.4 first and only then to this version.");
|
||||
|
||||
await crash();
|
||||
await crash(t("migration.old_version"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -83,10 +82,7 @@ async function migrate() {
|
||||
|
||||
log.info(`Migration to version ${mig.dbVersion} has been successful.`);
|
||||
} catch (e: any) {
|
||||
log.error(`error during migration to version ${mig.dbVersion}: ${e.stack}`);
|
||||
log.error("migration failed, crashing hard"); // this is not very user-friendly :-/
|
||||
|
||||
crash();
|
||||
crash(t("migration.error_message", { version: mig.dbVersion, stack: e.stack }));
|
||||
break; // crash() is sometimes async
|
||||
}
|
||||
}
|
||||
@ -136,11 +132,7 @@ async function migrateIfNecessary() {
|
||||
const currentDbVersion = getDbVersion();
|
||||
|
||||
if (currentDbVersion > appInfo.dbVersion && process.env.TRILIUM_IGNORE_DB_VERSION !== "true") {
|
||||
log.error(
|
||||
`Current DB version ${currentDbVersion} is newer than the current DB version ${appInfo.dbVersion}, which means that it was created by a newer and incompatible version of Trilium. Upgrade to the latest version of Trilium to resolve this issue.`
|
||||
);
|
||||
|
||||
await crash();
|
||||
await crash(t("migration.wrong_db_version", { version: currentDbVersion, targetVersion: appInfo.dbVersion }));
|
||||
}
|
||||
|
||||
if (!isDbUpToDate()) {
|
||||
|
@ -10,6 +10,8 @@ import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { dirname, join } from "path";
|
||||
import type NoteMeta from "./meta/note_meta.js";
|
||||
import log from "./log.js";
|
||||
import { t } from "i18next";
|
||||
|
||||
const randtoken = generator({ source: "crypto" });
|
||||
|
||||
@ -105,10 +107,13 @@ export function escapeRegExp(str: string) {
|
||||
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
|
||||
}
|
||||
|
||||
export async function crash() {
|
||||
export async function crash(message: string) {
|
||||
if (isElectron) {
|
||||
(await import("electron")).app.exit(1);
|
||||
const electron = await import("electron");
|
||||
electron.dialog.showErrorBox(t("modals.error_title"), message);
|
||||
electron.app.exit(1);
|
||||
} else {
|
||||
log.error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@ -168,6 +173,7 @@ export function removeTextFileExtension(filePath: string) {
|
||||
|
||||
switch (extension) {
|
||||
case ".md":
|
||||
case ".mdx":
|
||||
case ".markdown":
|
||||
case ".html":
|
||||
case ".htm":
|
||||
|
@ -194,8 +194,80 @@
|
||||
"not-configured": "Der Synchronisations-Server-Host ist nicht konfiguriert. Bitte konfiguriere zuerst die Synchronisation.",
|
||||
"successful": "Die Server-Verbindung wurde erfolgreich hergestellt, die Synchronisation wurde gestartet."
|
||||
},
|
||||
"hidden-subtree": {
|
||||
"root-title": "Versteckte Notizen",
|
||||
"search-history-title": "Suchverlauf",
|
||||
"note-map-title": "Notiz Karte",
|
||||
"sql-console-history-title": "SQL Konsolen Verlauf",
|
||||
"shared-notes-title": "Geteilte Notizen",
|
||||
"bulk-action-title": "Massenverarbeitung",
|
||||
"backend-log-title": "Backend Log",
|
||||
"user-hidden-title": "Versteckt vom Nutzer",
|
||||
"launch-bar-templates-title": "Startleiste Vorlagen",
|
||||
"base-abstract-launcher-title": "Basis Abstrakte Startleiste",
|
||||
"command-launcher-title": "Befehlslauncher",
|
||||
"note-launcher-title": "Notiz Launcher",
|
||||
"script-launcher-title": "Script Launcher",
|
||||
"built-in-widget-title": "Eingebautes Widget",
|
||||
"spacer-title": "Freifeld",
|
||||
"custom-widget-title": "Custom Widget",
|
||||
"launch-bar-title": "Launchbar",
|
||||
"available-launchers-title": "Verfügbare Launchers",
|
||||
"go-to-previous-note-title": "Zur vorherigen Notiz gehen",
|
||||
"go-to-next-note-title": "Zur nächsten Notiz gehen",
|
||||
"new-note-title": "Neue Notiz",
|
||||
"search-notes-title": "Notizen durchsuchen",
|
||||
"jump-to-note-title": "Zur Notiz springen",
|
||||
"calendar-title": "Kalender",
|
||||
"recent-changes-title": "neue Änderungen",
|
||||
"bookmarks-title": "Lesezeichen",
|
||||
"open-today-journal-note-title": "Heutigen Journaleintrag öffnen",
|
||||
"quick-search-title": "Schnellsuche",
|
||||
"protected-session-title": "Geschützte Sitzung",
|
||||
"sync-status-title": "Sync Status",
|
||||
"settings-title": "Einstellungen",
|
||||
"options-title": "Optionen",
|
||||
"appearance-title": "Erscheinungsbild",
|
||||
"shortcuts-title": "Tastaturkürzel",
|
||||
"text-notes": "Text Notizen",
|
||||
"code-notes-title": "Code Notizen",
|
||||
"images-title": "Bilder",
|
||||
"spellcheck-title": "Rechtschreibprüfung",
|
||||
"password-title": "Passwort",
|
||||
"etapi-title": "ETAPI",
|
||||
"backup-title": "Sicherung",
|
||||
"sync-title": "Sync",
|
||||
"other": "Weitere",
|
||||
"advanced-title": "Erweitert",
|
||||
"visible-launchers-title": "Sichtbare Launcher",
|
||||
"user-guide": "Nutzerhandbuch"
|
||||
},
|
||||
"notes": {
|
||||
"new-note": "Neue Notiz",
|
||||
"duplicate-note-suffix": "(dup)",
|
||||
"duplicate-note-title": "{{ noteTitle }} {{ duplicateNoteSuffix }}"
|
||||
},
|
||||
"backend_log": {
|
||||
"log-does-not-exist": "Die Backend-Log-Datei '{{ fileName }}' existiert (noch) nicht.",
|
||||
"reading-log-failed": "Das Lesen der Backend-Log-Datei '{{ fileName }}' ist fehlgeschlagen."
|
||||
},
|
||||
"content_renderer": {
|
||||
"note-cannot-be-displayed": "Dieser Notiztyp kann nicht angezeigt werden."
|
||||
},
|
||||
"pdf": {
|
||||
"export_filter": "PDF Dokument (*.pdf)",
|
||||
"unable-to-export-message": "Die aktuelle Notiz konnte nicht als PDF exportiert werden.",
|
||||
"unable-to-export-title": "Export als PDF fehlgeschlagen",
|
||||
"unable-to-save-message": "Die ausgewählte Datei konnte nicht beschrieben werden. Erneut versuchen oder ein anderes Ziel auswählen."
|
||||
},
|
||||
"tray": {
|
||||
"tooltip": "TriliumNext Notes",
|
||||
"close": "Trilium schließen",
|
||||
"recents": "Kürzliche Notizen",
|
||||
"bookmarks": "Lesezeichen",
|
||||
"today": "Heutigen Journal Eintrag öffnen",
|
||||
"new-note": "Neue Notiz",
|
||||
"show-windows": "Fenster anzeigen"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -272,5 +272,13 @@
|
||||
"today": "Open today's journal note",
|
||||
"new-note": "New note",
|
||||
"show-windows": "Show windows"
|
||||
},
|
||||
"migration": {
|
||||
"old_version": "Direct migration from your current version is not supported. Please upgrade to the latest v0.60.4 first and only then to this version.",
|
||||
"error_message": "Error during migration to version {{version}}: {{stack}}",
|
||||
"wrong_db_version": "Current DB version {{version}} is newer than the current DB version {{targetVersion}}, which means that it was created by a newer and incompatible version of Trilium. Upgrade to the latest version of Trilium to resolve this issue."
|
||||
},
|
||||
"modals": {
|
||||
"error_title": "Error"
|
||||
}
|
||||
}
|
||||
|
@ -272,5 +272,13 @@
|
||||
"today": "Mergi la notița de astăzi",
|
||||
"tooltip": "TriliumNext Notes",
|
||||
"show-windows": "Afișează ferestrele"
|
||||
},
|
||||
"migration": {
|
||||
"error_message": "Eroare la migrarea către versiunea {{version}}: {{stack}}",
|
||||
"old_version": "Nu se poate migra la ultima versiune direct de la versiunea dvs. Actualizați mai întâi la versiunea v0.60.4 și ulterior la această versiune.",
|
||||
"wrong_db_version": "Versiunea actuală a bazei de date ({{version}}) este mai nouă decât versiunea de bază de date suportată de aplicație ({{targetVersion}}), ceea ce înseamnă că a fost creată de către o versiune mai nouă de Trilium. Actualizați aplicația la ultima versiune pentru a putea continua."
|
||||
},
|
||||
"modals": {
|
||||
"error_title": "Eroare"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user