mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-10 18:39:22 +08:00
Merge branch 'develop' of ssh://github.com/TriliumNext/Notes into develop
This commit is contained in:
commit
293db6962e
@ -1,5 +1,7 @@
|
|||||||
# TriliumNext Notes
|
# TriliumNext Notes
|
||||||
|
|
||||||
|
 
|
||||||
|
|
||||||
[English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
|
[English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
|
||||||
|
|
||||||
TriliumNext Notes is an open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
|
TriliumNext Notes is an open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"src": "dist/trilium-linux-x64",
|
|
||||||
"dest": "dist/",
|
|
||||||
"compression": "xz",
|
|
||||||
"name": "trilium",
|
|
||||||
"productName": "Trilium Notes",
|
|
||||||
"genericName": "Note taker",
|
|
||||||
"description": "Trilium Notes is a hierarchical note taking application with focus on building large personal knowledge bases.",
|
|
||||||
"sections": "misc",
|
|
||||||
"maintainer": "zadam.apps@gmail.com",
|
|
||||||
"homepage": "https://github.com/zadam/trilium",
|
|
||||||
"bin": "trilium",
|
|
||||||
"icon": "dist/trilium-linux-x64/icon.png",
|
|
||||||
"categories": [ "Office" ]
|
|
||||||
}
|
|
12
bin/electron-forge/desktop.ejs
Normal file
12
bin/electron-forge/desktop.ejs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
<% if (productName) { %>Name=<%= productName %>
|
||||||
|
<% } %><% if (description) { %>Comment=<%= description %>
|
||||||
|
<% } %><% if (genericName) { %>GenericName=<%= genericName %>
|
||||||
|
<% } %><% if (name) { %>Exec=<%= name %> %U
|
||||||
|
Icon=<%= name %>
|
||||||
|
<% } %>Type=Application
|
||||||
|
StartupNotify=true
|
||||||
|
<% if (productName) { %>StartupWMClass=<%= productName %>
|
||||||
|
<% } if (categories && categories.length) { %>Categories=<%= categories.join(';') %>;
|
||||||
|
<% } %><% if (mimeType && mimeType.length) { %>MimeType=<%= mimeType.join(';') %>;
|
||||||
|
<% } %>
|
@ -20,13 +20,20 @@ module.exports = {
|
|||||||
afterComplete: [(buildPath, _electronVersion, platform, _arch, callback) => {
|
afterComplete: [(buildPath, _electronVersion, platform, _arch, callback) => {
|
||||||
const extraResources = getExtraResourcesForPlatform();
|
const extraResources = getExtraResourcesForPlatform();
|
||||||
for (const resource of extraResources) {
|
for (const resource of extraResources) {
|
||||||
|
const baseName = path.basename(resource);
|
||||||
let sourcePath;
|
let sourcePath;
|
||||||
if (platform === 'darwin') {
|
if (platform === 'darwin') {
|
||||||
sourcePath = path.join(buildPath, `${APP_NAME}.app`, 'Contents', 'Resources', path.basename(resource));
|
sourcePath = path.join(buildPath, `${APP_NAME}.app`, 'Contents', 'Resources', baseName);
|
||||||
} else {
|
} else {
|
||||||
sourcePath = path.join(buildPath, 'resources', path.basename(resource));
|
sourcePath = path.join(buildPath, 'resources', baseName);
|
||||||
|
}
|
||||||
|
let destPath;
|
||||||
|
|
||||||
|
if (baseName !== "256x256.png") {
|
||||||
|
destPath = path.join(buildPath, baseName);
|
||||||
|
} else {
|
||||||
|
destPath = path.join(buildPath, "icon.png");
|
||||||
}
|
}
|
||||||
const destPath = path.join(buildPath, path.basename(resource));
|
|
||||||
|
|
||||||
// Copy files from resources folder to root
|
// Copy files from resources folder to root
|
||||||
fs.move(sourcePath, destPath)
|
fs.move(sourcePath, destPath)
|
||||||
@ -44,6 +51,7 @@ module.exports = {
|
|||||||
config: {
|
config: {
|
||||||
options: {
|
options: {
|
||||||
icon: "./images/app-icons/png/128x128.png",
|
icon: "./images/app-icons/png/128x128.png",
|
||||||
|
desktopTemplate: path.resolve("./bin/electron-forge/desktop.ejs")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -95,6 +103,7 @@ function getExtraResourcesForPlatform() {
|
|||||||
case 'darwin':
|
case 'darwin':
|
||||||
break;
|
break;
|
||||||
case 'linux':
|
case 'linux':
|
||||||
|
resources.push("images/app-icons/png/256x256.png")
|
||||||
for (const script of scripts) {
|
for (const script of scripts) {
|
||||||
resources.push(`./bin/tpl/${script}.sh`)
|
resources.push(`./bin/tpl/${script}.sh`)
|
||||||
}
|
}
|
||||||
|
177
package-lock.json
generated
177
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"version": "0.90.8",
|
"version": "0.90.9-beta",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"version": "0.90.8",
|
"version": "0.90.9-beta",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@braintree/sanitize-url": "7.1.0",
|
"@braintree/sanitize-url": "7.1.0",
|
||||||
@ -23,11 +23,11 @@
|
|||||||
"cls-hooked": "4.2.2",
|
"cls-hooked": "4.2.2",
|
||||||
"codemirror": "5.65.18",
|
"codemirror": "5.65.18",
|
||||||
"compression": "1.7.4",
|
"compression": "1.7.4",
|
||||||
"cookie-parser": "1.4.6",
|
"cookie-parser": "1.4.7",
|
||||||
"csurf": "1.11.0",
|
"csurf": "1.11.0",
|
||||||
"dayjs": "1.11.13",
|
"dayjs": "1.11.13",
|
||||||
"dayjs-plugin-utc": "0.1.2",
|
"dayjs-plugin-utc": "0.1.2",
|
||||||
"debounce": "2.1.1",
|
"debounce": "2.2.0",
|
||||||
"ejs": "3.1.10",
|
"ejs": "3.1.10",
|
||||||
"electron-debug": "4.0.1",
|
"electron-debug": "4.0.1",
|
||||||
"electron-dl": "4.0.0",
|
"electron-dl": "4.0.0",
|
||||||
@ -35,18 +35,18 @@
|
|||||||
"electron-window-state": "5.0.3",
|
"electron-window-state": "5.0.3",
|
||||||
"escape-html": "1.0.3",
|
"escape-html": "1.0.3",
|
||||||
"eslint": "9.10.0",
|
"eslint": "9.10.0",
|
||||||
"express": "4.21.0",
|
"express": "4.21.1",
|
||||||
"express-partial-content": "1.0.2",
|
"express-partial-content": "1.0.2",
|
||||||
"express-rate-limit": "7.4.0",
|
"express-rate-limit": "7.4.1",
|
||||||
"express-session": "1.18.0",
|
"express-session": "1.18.1",
|
||||||
"force-graph": "1.43.5",
|
"force-graph": "1.45.0",
|
||||||
"fs-extra": "11.2.0",
|
"fs-extra": "11.2.0",
|
||||||
"helmet": "7.1.0",
|
"helmet": "7.1.0",
|
||||||
"html": "1.0.0",
|
"html": "1.0.0",
|
||||||
"html2plaintext": "2.1.4",
|
"html2plaintext": "2.1.4",
|
||||||
"http-proxy-agent": "7.0.2",
|
"http-proxy-agent": "7.0.2",
|
||||||
"https-proxy-agent": "7.0.5",
|
"https-proxy-agent": "7.0.5",
|
||||||
"i18next": "23.16.0",
|
"i18next": "23.16.2",
|
||||||
"i18next-fs-backend": "2.3.2",
|
"i18next-fs-backend": "2.3.2",
|
||||||
"i18next-http-backend": "2.6.2",
|
"i18next-http-backend": "2.6.2",
|
||||||
"image-type": "4.1.0",
|
"image-type": "4.1.0",
|
||||||
@ -63,10 +63,10 @@
|
|||||||
"katex": "0.16.11",
|
"katex": "0.16.11",
|
||||||
"knockout": "3.5.1",
|
"knockout": "3.5.1",
|
||||||
"mark.js": "8.11.1",
|
"mark.js": "8.11.1",
|
||||||
"marked": "14.1.2",
|
"marked": "14.1.3",
|
||||||
"mermaid": "11.3.0",
|
"mermaid": "11.3.0",
|
||||||
"mime-types": "2.1.35",
|
"mime-types": "2.1.35",
|
||||||
"mind-elixir": "4.2.0",
|
"mind-elixir": "4.2.3",
|
||||||
"multer": "1.4.5-lts.1",
|
"multer": "1.4.5-lts.1",
|
||||||
"node-abi": "3.67.0",
|
"node-abi": "3.67.0",
|
||||||
"normalize-strings": "1.1.1",
|
"normalize-strings": "1.1.1",
|
||||||
@ -79,7 +79,7 @@
|
|||||||
"request": "2.88.2",
|
"request": "2.88.2",
|
||||||
"safe-compare": "1.1.4",
|
"safe-compare": "1.1.4",
|
||||||
"sanitize-filename": "1.6.3",
|
"sanitize-filename": "1.6.3",
|
||||||
"sanitize-html": "2.13.0",
|
"sanitize-html": "2.13.1",
|
||||||
"sax": "1.4.1",
|
"sax": "1.4.1",
|
||||||
"semver": "7.6.3",
|
"semver": "7.6.3",
|
||||||
"serve-favicon": "2.5.0",
|
"serve-favicon": "2.5.0",
|
||||||
@ -92,7 +92,7 @@
|
|||||||
"tree-kill": "1.2.2",
|
"tree-kill": "1.2.2",
|
||||||
"turndown": "7.2.0",
|
"turndown": "7.2.0",
|
||||||
"unescape": "1.0.1",
|
"unescape": "1.0.1",
|
||||||
"vanilla-js-wheel-zoom": "9.0.2",
|
"vanilla-js-wheel-zoom": "9.0.4",
|
||||||
"ws": "8.18.0",
|
"ws": "8.18.0",
|
||||||
"xml2js": "0.6.2",
|
"xml2js": "0.6.2",
|
||||||
"yauzl": "3.1.3"
|
"yauzl": "3.1.3"
|
||||||
@ -126,7 +126,7 @@
|
|||||||
"@types/jsdom": "21.1.7",
|
"@types/jsdom": "21.1.7",
|
||||||
"@types/mime-types": "2.1.4",
|
"@types/mime-types": "2.1.4",
|
||||||
"@types/multer": "1.4.12",
|
"@types/multer": "1.4.12",
|
||||||
"@types/node": "22.5.4",
|
"@types/node": "22.7.8",
|
||||||
"@types/safe-compare": "1.1.2",
|
"@types/safe-compare": "1.1.2",
|
||||||
"@types/sanitize-html": "2.13.0",
|
"@types/sanitize-html": "2.13.0",
|
||||||
"@types/sax": "1.2.7",
|
"@types/sax": "1.2.7",
|
||||||
@ -145,14 +145,14 @@
|
|||||||
"electron-rebuild": "3.2.9",
|
"electron-rebuild": "3.2.9",
|
||||||
"esm": "3.2.25",
|
"esm": "3.2.25",
|
||||||
"iconsur": "1.7.0",
|
"iconsur": "1.7.0",
|
||||||
"jasmine": "5.3.1",
|
"jasmine": "5.4.0",
|
||||||
"jsdoc": "4.0.3",
|
"jsdoc": "4.0.3",
|
||||||
"lorem-ipsum": "2.0.8",
|
"lorem-ipsum": "2.0.8",
|
||||||
"nodemon": "3.1.7",
|
"nodemon": "3.1.7",
|
||||||
"rcedit": "4.0.1",
|
"rcedit": "4.0.1",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
"ts-node": "10.9.2",
|
"ts-node": "10.9.2",
|
||||||
"tslib": "2.7.0",
|
"tslib": "2.8.0",
|
||||||
"tsx": "4.19.1",
|
"tsx": "4.19.1",
|
||||||
"typescript": "5.6.3",
|
"typescript": "5.6.3",
|
||||||
"webpack": "5.95.0",
|
"webpack": "5.95.0",
|
||||||
@ -3360,9 +3360,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/express-serve-static-core": {
|
"node_modules/@types/express-serve-static-core": {
|
||||||
"version": "4.17.43",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz",
|
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz",
|
||||||
"integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==",
|
"integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
@ -3380,6 +3380,18 @@
|
|||||||
"@types/express": "*"
|
"@types/express": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/express/node_modules/@types/express-serve-static-core": {
|
||||||
|
"version": "4.19.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
|
||||||
|
"integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"@types/qs": "*",
|
||||||
|
"@types/range-parser": "*",
|
||||||
|
"@types/send": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/fs-extra": {
|
"node_modules/@types/fs-extra": {
|
||||||
"version": "9.0.13",
|
"version": "9.0.13",
|
||||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
||||||
@ -3528,9 +3540,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.5.4",
|
"version": "22.7.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.8.tgz",
|
||||||
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
|
"integrity": "sha512-a922jJy31vqR5sk+kAdIENJjHblqcZ4RmERviFsER4WJcEONqxKcjNOlk0q7OUfrF5sddT+vng070cdfMlrPLg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.19.2"
|
"undici-types": "~6.19.2"
|
||||||
}
|
}
|
||||||
@ -5319,9 +5331,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/canvas-color-tracker": {
|
"node_modules/canvas-color-tracker": {
|
||||||
"version": "1.2.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/canvas-color-tracker/-/canvas-color-tracker-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/canvas-color-tracker/-/canvas-color-tracker-1.3.1.tgz",
|
||||||
"integrity": "sha512-i5clg2pEdaWqHuEM/B74NZNLkHh5+OkXbA/T4iaBiaNDagkOCXkLNrhqUfdUugsRwuaNRU20e/OygzxWRor3yg==",
|
"integrity": "sha512-eNycxGS7oQ3IS/9QQY41f/aQjiO9Y/MtedhCgSdsbLSxC9EyUD8L3ehl/Q3Kfmvt8um79S45PBV+5Rxm5ztdSw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tinycolor2": "^1.6.0"
|
"tinycolor2": "^1.6.0"
|
||||||
},
|
},
|
||||||
@ -5926,11 +5938,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cookie-parser": {
|
"node_modules/cookie-parser": {
|
||||||
"version": "1.4.6",
|
"version": "1.4.7",
|
||||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
|
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
|
||||||
"integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
|
"integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie": "0.4.1",
|
"cookie": "0.7.2",
|
||||||
"cookie-signature": "1.0.6"
|
"cookie-signature": "1.0.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -5938,9 +5950,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cookie-parser/node_modules/cookie": {
|
"node_modules/cookie-parser/node_modules/cookie": {
|
||||||
"version": "0.4.1",
|
"version": "0.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@ -6753,9 +6765,9 @@
|
|||||||
"integrity": "sha512-ExERH5o3oo6jFOdkvMP3gytTCQ9Ksi5PtylclJWghr7k7m3o2U5QrwtdiJkOxLOH4ghr0EKhpqGefzGz1VvVJg=="
|
"integrity": "sha512-ExERH5o3oo6jFOdkvMP3gytTCQ9Ksi5PtylclJWghr7k7m3o2U5QrwtdiJkOxLOH4ghr0EKhpqGefzGz1VvVJg=="
|
||||||
},
|
},
|
||||||
"node_modules/debounce": {
|
"node_modules/debounce": {
|
||||||
"version": "2.1.1",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/debounce/-/debounce-2.2.0.tgz",
|
||||||
"integrity": "sha512-+xRWxgel9LgTC4PwKlm7TJUK6B6qsEK77NaiNvXmeQ7Y3e6OVVsBC4a9BSptS/mAYceyAz37Oa8JTTuPRft7uQ==",
|
"integrity": "sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
@ -8229,16 +8241,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.21.0",
|
"version": "4.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||||
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
|
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.8",
|
"accepts": "~1.3.8",
|
||||||
"array-flatten": "1.1.1",
|
"array-flatten": "1.1.1",
|
||||||
"body-parser": "1.20.3",
|
"body-parser": "1.20.3",
|
||||||
"content-disposition": "0.5.4",
|
"content-disposition": "0.5.4",
|
||||||
"content-type": "~1.0.4",
|
"content-type": "~1.0.4",
|
||||||
"cookie": "0.6.0",
|
"cookie": "0.7.1",
|
||||||
"cookie-signature": "1.0.6",
|
"cookie-signature": "1.0.6",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
@ -8278,9 +8290,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express-rate-limit": {
|
"node_modules/express-rate-limit": {
|
||||||
"version": "7.4.0",
|
"version": "7.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.4.1.tgz",
|
||||||
"integrity": "sha512-v1204w3cXu5gCDmAvgvzI6qjzZzoMWKnyVDk3ACgfswTQLYiGen+r8w0VnXnGMmzEN/g8fwIQ4JrFFd4ZP6ssg==",
|
"integrity": "sha512-KS3efpnpIDVIXopMc65EMbWbUht7qvTCdtCR2dD/IZmi9MIkopYESwyRqLgv8Pfu589+KqDqOdzJWW7AHoACeg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
},
|
},
|
||||||
@ -8292,11 +8304,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express-session": {
|
"node_modules/express-session": {
|
||||||
"version": "1.18.0",
|
"version": "1.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz",
|
||||||
"integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==",
|
"integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie": "0.6.0",
|
"cookie": "0.7.2",
|
||||||
"cookie-signature": "1.0.7",
|
"cookie-signature": "1.0.7",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "~2.0.0",
|
"depd": "~2.0.0",
|
||||||
@ -8310,9 +8322,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express-session/node_modules/cookie": {
|
"node_modules/express-session/node_modules/cookie": {
|
||||||
"version": "0.6.0",
|
"version": "0.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@ -8358,9 +8370,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/express/node_modules/cookie": {
|
"node_modules/express/node_modules/cookie": {
|
||||||
"version": "0.6.0",
|
"version": "0.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@ -8835,14 +8847,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/force-graph": {
|
"node_modules/force-graph": {
|
||||||
"version": "1.43.5",
|
"version": "1.45.0",
|
||||||
"resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.43.5.tgz",
|
"resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.45.0.tgz",
|
||||||
"integrity": "sha512-HveLELh9yhZXO/QOfaFS38vlwJZ/3sKu+jarfXzRmbmihSOH/BbRWnUvmg8wLFiYy6h4HlH4lkRfZRccHYmXgA==",
|
"integrity": "sha512-QM/J72Vji5D3ug+TDu8wH+qne0zEKE9Cn7m9ocH/1RtaVY0BBqZQ4Mn6MiwNRyxwl28lsUd0F54kDpINnagvOA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tweenjs/tween.js": "18 - 23",
|
"@tweenjs/tween.js": "18 - 25",
|
||||||
"accessor-fn": "1",
|
"accessor-fn": "1",
|
||||||
"bezier-js": "3 - 6",
|
"bezier-js": "3 - 6",
|
||||||
"canvas-color-tracker": "1",
|
"canvas-color-tracker": "^1.3",
|
||||||
"d3-array": "1 - 3",
|
"d3-array": "1 - 3",
|
||||||
"d3-drag": "2 - 3",
|
"d3-drag": "2 - 3",
|
||||||
"d3-force-3d": "2 - 3",
|
"d3-force-3d": "2 - 3",
|
||||||
@ -9715,9 +9727,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/i18next": {
|
"node_modules/i18next": {
|
||||||
"version": "23.16.0",
|
"version": "23.16.2",
|
||||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.2.tgz",
|
||||||
"integrity": "sha512-Ni3CG6c14teOogY19YNRl+kYaE/Rb59khy0VyHVn4uOZ97E2E/Yziyi6r3C3s9+wacjdLZiq/LLYyx+Cgd+FCw==",
|
"integrity": "sha512-dFyxwLXxEQK32f6tITBMaRht25mZPJhQ0WbC0p3bO2mWBal9lABTMqSka5k+GLSRWLzeJBKDpH7BeIA9TZI7Jg==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@ -10828,22 +10840,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jasmine": {
|
"node_modules/jasmine": {
|
||||||
"version": "5.3.1",
|
"version": "5.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-5.4.0.tgz",
|
||||||
"integrity": "sha512-3zeUCfr3d1iga3s+NgDpggCP+ex5sdbNgqNn+Tq4yw/QfnwGrWC/ZvXX1IRm5deSIZ1LnvoeGY55F/ztbVOXPQ==",
|
"integrity": "sha512-E2u4ylX5tgGYvbynImU6EUBKKrSVB1L72FEPjGh4M55ov1VsxR26RA2JU91L9YSPFgcjo4mCLyKn/QXvEYGBkA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": "^10.2.2",
|
"glob": "^10.2.2",
|
||||||
"jasmine-core": "~5.3.0"
|
"jasmine-core": "~5.4.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"jasmine": "bin/jasmine.js"
|
"jasmine": "bin/jasmine.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jasmine-core": {
|
"node_modules/jasmine-core": {
|
||||||
"version": "5.3.0",
|
"version": "5.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.4.0.tgz",
|
||||||
"integrity": "sha512-zsOmeBKESky4toybvWEikRiZ0jHoBEu79wNArLfMdSnlLMZx3Xcp6CSm2sUcYyoJC+Uyj8LBJap/MUbVSfJ27g==",
|
"integrity": "sha512-T4fio3W++llLd7LGSGsioriDHgWyhoL6YTu4k37uwJLF7DzOzspz7mNxRoM3cQdLWtL/ebazQpIf/yZGJx/gzg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/jasmine/node_modules/brace-expansion": {
|
"node_modules/jasmine/node_modules/brace-expansion": {
|
||||||
@ -11817,9 +11829,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/marked": {
|
"node_modules/marked": {
|
||||||
"version": "14.1.2",
|
"version": "14.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-14.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-14.1.3.tgz",
|
||||||
"integrity": "sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==",
|
"integrity": "sha512-ZibJqTULGlt9g5k4VMARAktMAjXoVnnr+Y3aCqW1oDftcV4BA3UmrBifzXoZyenHRk75csiPu9iwsTj4VNBT0g==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"marked": "bin/marked.js"
|
"marked": "bin/marked.js"
|
||||||
},
|
},
|
||||||
@ -12028,9 +12040,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mind-elixir": {
|
"node_modules/mind-elixir": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/mind-elixir/-/mind-elixir-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/mind-elixir/-/mind-elixir-4.2.3.tgz",
|
||||||
"integrity": "sha512-FBmTri+lfuScRtaBQGh6WNFU1Bbqp2IDq6dF9coxv5aj34wuTsacR8fwyTaK79Wh8A5mUL/D/HO/KvSMBKJBqg=="
|
"integrity": "sha512-o/t9/mrJkRu0PE5UjXBv8ZZuhwSdm6C1Hw65v/+bIlB2CS2MOGZ/GNPvU3U4kPDu6LnCZ0kw0L7hoVfHhrZLtw=="
|
||||||
},
|
},
|
||||||
"node_modules/minimalistic-assert": {
|
"node_modules/minimalistic-assert": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@ -14321,9 +14333,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sanitize-html": {
|
"node_modules/sanitize-html": {
|
||||||
"version": "2.13.0",
|
"version": "2.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.13.1.tgz",
|
||||||
"integrity": "sha512-Xff91Z+4Mz5QiNSLdLWwjgBDm5b1RU6xBT0+12rapjiaR7SwfRdjw8f+6Rir2MXKLrDicRFHdb51hGOAxmsUIA==",
|
"integrity": "sha512-ZXtKq89oue4RP7abL9wp/9URJcqQNABB5GGJ2acW1sdO8JTVl92f4ygD7Yc9Ze09VAZhnt2zegeU0tbNsdcLYg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
@ -15647,9 +15659,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.7.0",
|
"version": "2.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
|
||||||
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
|
"integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA=="
|
||||||
},
|
},
|
||||||
"node_modules/tsscmp": {
|
"node_modules/tsscmp": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
@ -16032,10 +16044,9 @@
|
|||||||
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
|
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
|
||||||
},
|
},
|
||||||
"node_modules/vanilla-js-wheel-zoom": {
|
"node_modules/vanilla-js-wheel-zoom": {
|
||||||
"version": "9.0.2",
|
"version": "9.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/vanilla-js-wheel-zoom/-/vanilla-js-wheel-zoom-9.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/vanilla-js-wheel-zoom/-/vanilla-js-wheel-zoom-9.0.4.tgz",
|
||||||
"integrity": "sha512-GleJm/qTDcfQC7gdFH4BT5vCZmnz2LOTgLAQ5CCCwftFC/zrBURRWr5Y7jRPi3W3rRf8bTIAN3hLZYFqvK5jwA==",
|
"integrity": "sha512-OjmS9ihEKBCRw2OQ7IiIdQGXdC5gTEEmtcAWZcPeNAJaYiS61KCd02Z72YMtIoXLGN5TZP+wliBMylLAsr6wow=="
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
|
30
package.json
30
package.json
@ -2,7 +2,7 @@
|
|||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"productName": "TriliumNext Notes",
|
"productName": "TriliumNext Notes",
|
||||||
"description": "Build your personal knowledge base with TriliumNext Notes",
|
"description": "Build your personal knowledge base with TriliumNext Notes",
|
||||||
"version": "0.90.8",
|
"version": "0.90.9-beta",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"main": "./dist/electron-main.js",
|
"main": "./dist/electron-main.js",
|
||||||
"author": {
|
"author": {
|
||||||
@ -63,11 +63,11 @@
|
|||||||
"cls-hooked": "4.2.2",
|
"cls-hooked": "4.2.2",
|
||||||
"codemirror": "5.65.18",
|
"codemirror": "5.65.18",
|
||||||
"compression": "1.7.4",
|
"compression": "1.7.4",
|
||||||
"cookie-parser": "1.4.6",
|
"cookie-parser": "1.4.7",
|
||||||
"csurf": "1.11.0",
|
"csurf": "1.11.0",
|
||||||
"dayjs": "1.11.13",
|
"dayjs": "1.11.13",
|
||||||
"dayjs-plugin-utc": "0.1.2",
|
"dayjs-plugin-utc": "0.1.2",
|
||||||
"debounce": "2.1.1",
|
"debounce": "2.2.0",
|
||||||
"ejs": "3.1.10",
|
"ejs": "3.1.10",
|
||||||
"electron-debug": "4.0.1",
|
"electron-debug": "4.0.1",
|
||||||
"electron-dl": "4.0.0",
|
"electron-dl": "4.0.0",
|
||||||
@ -75,18 +75,18 @@
|
|||||||
"electron-window-state": "5.0.3",
|
"electron-window-state": "5.0.3",
|
||||||
"escape-html": "1.0.3",
|
"escape-html": "1.0.3",
|
||||||
"eslint": "9.10.0",
|
"eslint": "9.10.0",
|
||||||
"express": "4.21.0",
|
"express": "4.21.1",
|
||||||
"express-partial-content": "1.0.2",
|
"express-partial-content": "1.0.2",
|
||||||
"express-rate-limit": "7.4.0",
|
"express-rate-limit": "7.4.1",
|
||||||
"express-session": "1.18.0",
|
"express-session": "1.18.1",
|
||||||
"force-graph": "1.43.5",
|
"force-graph": "1.45.0",
|
||||||
"fs-extra": "11.2.0",
|
"fs-extra": "11.2.0",
|
||||||
"helmet": "7.1.0",
|
"helmet": "7.1.0",
|
||||||
"html": "1.0.0",
|
"html": "1.0.0",
|
||||||
"html2plaintext": "2.1.4",
|
"html2plaintext": "2.1.4",
|
||||||
"http-proxy-agent": "7.0.2",
|
"http-proxy-agent": "7.0.2",
|
||||||
"https-proxy-agent": "7.0.5",
|
"https-proxy-agent": "7.0.5",
|
||||||
"i18next": "23.16.0",
|
"i18next": "23.16.2",
|
||||||
"i18next-fs-backend": "2.3.2",
|
"i18next-fs-backend": "2.3.2",
|
||||||
"i18next-http-backend": "2.6.2",
|
"i18next-http-backend": "2.6.2",
|
||||||
"image-type": "4.1.0",
|
"image-type": "4.1.0",
|
||||||
@ -103,10 +103,10 @@
|
|||||||
"katex": "0.16.11",
|
"katex": "0.16.11",
|
||||||
"knockout": "3.5.1",
|
"knockout": "3.5.1",
|
||||||
"mark.js": "8.11.1",
|
"mark.js": "8.11.1",
|
||||||
"marked": "14.1.2",
|
"marked": "14.1.3",
|
||||||
"mermaid": "11.3.0",
|
"mermaid": "11.3.0",
|
||||||
"mime-types": "2.1.35",
|
"mime-types": "2.1.35",
|
||||||
"mind-elixir": "4.2.0",
|
"mind-elixir": "4.2.3",
|
||||||
"multer": "1.4.5-lts.1",
|
"multer": "1.4.5-lts.1",
|
||||||
"node-abi": "3.67.0",
|
"node-abi": "3.67.0",
|
||||||
"normalize-strings": "1.1.1",
|
"normalize-strings": "1.1.1",
|
||||||
@ -119,7 +119,7 @@
|
|||||||
"request": "2.88.2",
|
"request": "2.88.2",
|
||||||
"safe-compare": "1.1.4",
|
"safe-compare": "1.1.4",
|
||||||
"sanitize-filename": "1.6.3",
|
"sanitize-filename": "1.6.3",
|
||||||
"sanitize-html": "2.13.0",
|
"sanitize-html": "2.13.1",
|
||||||
"sax": "1.4.1",
|
"sax": "1.4.1",
|
||||||
"semver": "7.6.3",
|
"semver": "7.6.3",
|
||||||
"serve-favicon": "2.5.0",
|
"serve-favicon": "2.5.0",
|
||||||
@ -132,7 +132,7 @@
|
|||||||
"tree-kill": "1.2.2",
|
"tree-kill": "1.2.2",
|
||||||
"turndown": "7.2.0",
|
"turndown": "7.2.0",
|
||||||
"unescape": "1.0.1",
|
"unescape": "1.0.1",
|
||||||
"vanilla-js-wheel-zoom": "9.0.2",
|
"vanilla-js-wheel-zoom": "9.0.4",
|
||||||
"ws": "8.18.0",
|
"ws": "8.18.0",
|
||||||
"xml2js": "0.6.2",
|
"xml2js": "0.6.2",
|
||||||
"yauzl": "3.1.3"
|
"yauzl": "3.1.3"
|
||||||
@ -163,7 +163,7 @@
|
|||||||
"@types/jsdom": "21.1.7",
|
"@types/jsdom": "21.1.7",
|
||||||
"@types/mime-types": "2.1.4",
|
"@types/mime-types": "2.1.4",
|
||||||
"@types/multer": "1.4.12",
|
"@types/multer": "1.4.12",
|
||||||
"@types/node": "22.5.4",
|
"@types/node": "22.7.8",
|
||||||
"@types/safe-compare": "1.1.2",
|
"@types/safe-compare": "1.1.2",
|
||||||
"@types/sanitize-html": "2.13.0",
|
"@types/sanitize-html": "2.13.0",
|
||||||
"@types/sax": "1.2.7",
|
"@types/sax": "1.2.7",
|
||||||
@ -182,14 +182,14 @@
|
|||||||
"electron-rebuild": "3.2.9",
|
"electron-rebuild": "3.2.9",
|
||||||
"esm": "3.2.25",
|
"esm": "3.2.25",
|
||||||
"iconsur": "1.7.0",
|
"iconsur": "1.7.0",
|
||||||
"jasmine": "5.3.1",
|
"jasmine": "5.4.0",
|
||||||
"jsdoc": "4.0.3",
|
"jsdoc": "4.0.3",
|
||||||
"lorem-ipsum": "2.0.8",
|
"lorem-ipsum": "2.0.8",
|
||||||
"nodemon": "3.1.7",
|
"nodemon": "3.1.7",
|
||||||
"rcedit": "4.0.1",
|
"rcedit": "4.0.1",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
"ts-node": "10.9.2",
|
"ts-node": "10.9.2",
|
||||||
"tslib": "2.7.0",
|
"tslib": "2.8.0",
|
||||||
"tsx": "4.19.1",
|
"tsx": "4.19.1",
|
||||||
"typescript": "5.6.3",
|
"typescript": "5.6.3",
|
||||||
"webpack": "5.95.0",
|
"webpack": "5.95.0",
|
||||||
|
@ -9,6 +9,7 @@ import ws from "../services/ws.js";
|
|||||||
import bundleService from "../services/bundle.js";
|
import bundleService from "../services/bundle.js";
|
||||||
import froca from "../services/froca.js";
|
import froca from "../services/froca.js";
|
||||||
import linkService from "../services/link.js";
|
import linkService from "../services/link.js";
|
||||||
|
import { t } from "../services/i18n.js";
|
||||||
|
|
||||||
export default class Entrypoints extends Component {
|
export default class Entrypoints extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -172,13 +173,13 @@ export default class Entrypoints extends Component {
|
|||||||
const resp = await server.post(`sql/execute/${note.noteId}`);
|
const resp = await server.post(`sql/execute/${note.noteId}`);
|
||||||
|
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
toastService.showError(`Error occurred while executing SQL query: ${resp.error}`);
|
toastService.showError(t("entrypoints.sql-error", { message: resp.error }));
|
||||||
}
|
}
|
||||||
|
|
||||||
await appContext.triggerEvent('sqlQueryResults', {ntxId: ntxId, results: resp.results});
|
await appContext.triggerEvent('sqlQueryResults', {ntxId: ntxId, results: resp.results});
|
||||||
}
|
}
|
||||||
|
|
||||||
toastService.showMessage("Note executed");
|
toastService.showMessage(t("entrypoints.note-executed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
hideAllPopups() {
|
hideAllPopups() {
|
||||||
@ -200,6 +201,6 @@ export default class Entrypoints extends Component {
|
|||||||
|
|
||||||
await server.post(`notes/${noteId}/revision`);
|
await server.post(`notes/${noteId}/revision`);
|
||||||
|
|
||||||
toastService.showMessage("Note revision has been created.");
|
toastService.showMessage(t("entrypoints.note-revision-created"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -551,7 +551,7 @@ export default class TabManager extends Component {
|
|||||||
await this.removeNoteContext(ntxIdToRemove);
|
await this.removeNoteContext(ntxIdToRemove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async closeOtherTabsCommand({ntxId}) {
|
async closeOtherTabsCommand({ntxId}) {
|
||||||
for (const ntxIdToRemove of this.mainNoteContexts.map(nc => nc.ntxId)) {
|
for (const ntxIdToRemove of this.mainNoteContexts.map(nc => nc.ntxId)) {
|
||||||
if (ntxIdToRemove !== ntxId) {
|
if (ntxIdToRemove !== ntxId) {
|
||||||
@ -560,6 +560,18 @@ export default class TabManager extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async closeRightTabsCommand({ntxId}) {
|
||||||
|
const ntxIds = this.mainNoteContexts.map(nc => nc.ntxId);
|
||||||
|
const index = ntxIds.indexOf(ntxId);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
const idsToRemove = ntxIds.slice(index + 1);
|
||||||
|
for (const ntxIdToRemove of idsToRemove) {
|
||||||
|
await this.removeNoteContext(ntxIdToRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async closeTabCommand({ntxId}) {
|
async closeTabCommand({ntxId}) {
|
||||||
await this.removeNoteContext(ntxId);
|
await this.removeNoteContext(ntxId);
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,9 @@ import electronContextMenu from "./menus/electron_context_menu.js";
|
|||||||
import glob from "./services/glob.js";
|
import glob from "./services/glob.js";
|
||||||
import { t } from "./services/i18n.js";
|
import { t } from "./services/i18n.js";
|
||||||
|
|
||||||
|
await appContext.earlyInit();
|
||||||
|
|
||||||
bundleService.getWidgetBundlesByParent().then(async widgetBundles => {
|
bundleService.getWidgetBundlesByParent().then(async widgetBundles => {
|
||||||
await appContext.earlyInit();
|
|
||||||
|
|
||||||
// A dynamic import is required for layouts since they initialize components which require translations.
|
// A dynamic import is required for layouts since they initialize components which require translations.
|
||||||
const DesktopLayout = (await import("./layouts/desktop_layout.js")).default;
|
const DesktopLayout = (await import("./layouts/desktop_layout.js")).default;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import froca from "../services/froca.js";
|
|||||||
import contextMenu from "./context_menu.js";
|
import contextMenu from "./context_menu.js";
|
||||||
import dialogService from "../services/dialog.js";
|
import dialogService from "../services/dialog.js";
|
||||||
import server from "../services/server.js";
|
import server from "../services/server.js";
|
||||||
|
import { t } from '../services/i18n.js';
|
||||||
|
|
||||||
export default class LauncherContextMenu {
|
export default class LauncherContextMenu {
|
||||||
/**
|
/**
|
||||||
@ -33,29 +34,27 @@ export default class LauncherContextMenu {
|
|||||||
const isAvailableItem = parentNoteId === '_lbAvailableLaunchers';
|
const isAvailableItem = parentNoteId === '_lbAvailableLaunchers';
|
||||||
const isItem = isVisibleItem || isAvailableItem;
|
const isItem = isVisibleItem || isAvailableItem;
|
||||||
const canBeDeleted = !note.noteId.startsWith("_"); // fixed notes can't be deleted
|
const canBeDeleted = !note.noteId.startsWith("_"); // fixed notes can't be deleted
|
||||||
const canBeReset = !canBeDeleted && note.isLaunchBarConfig();;
|
const canBeReset = !canBeDeleted && note.isLaunchBarConfig();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a note launcher', command: 'addNoteLauncher', uiIcon: "bx bx-plus" } : null,
|
(isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-note-launcher"), command: 'addNoteLauncher', uiIcon: "bx bx-plus" } : null,
|
||||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a script launcher', command: 'addScriptLauncher', uiIcon: "bx bx-plus" } : null,
|
(isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-script-launcher"), command: 'addScriptLauncher', uiIcon: "bx bx-plus" } : null,
|
||||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a custom widget', command: 'addWidgetLauncher', uiIcon: "bx bx-plus" } : null,
|
(isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-custom-widget"), command: 'addWidgetLauncher', uiIcon: "bx bx-plus" } : null,
|
||||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add spacer', command: 'addSpacerLauncher', uiIcon: "bx bx-plus" } : null,
|
(isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-spacer"), command: 'addSpacerLauncher', uiIcon: "bx bx-plus" } : null,
|
||||||
(isVisibleRoot || isAvailableRoot) ? { title: "----" } : null,
|
(isVisibleRoot || isAvailableRoot) ? { title: "----" } : null,
|
||||||
{ title: 'Delete <kbd data-command="deleteNotes"></kbd>', command: "deleteNotes", uiIcon: "bx bx-trash", enabled: canBeDeleted },
|
{ title: `${t("launcher_context_menu.delete")} <kbd data-command="deleteNotes"></kbd>`, command: "deleteNotes", uiIcon: "bx bx-trash", enabled: canBeDeleted },
|
||||||
{ title: 'Reset', command: "resetLauncher", uiIcon: "bx bx-empty", enabled: canBeReset},
|
{ title: t("launcher_context_menu.reset"), command: "resetLauncher", uiIcon: "bx bx-empty", enabled: canBeReset},
|
||||||
{ title: "----" },
|
{ title: "----" },
|
||||||
isAvailableItem ? { title: 'Move to visible launchers', command: "moveLauncherToVisible", uiIcon: "bx bx-show", enabled: true } : null,
|
isAvailableItem ? { title: t("launcher_context_menu.move-to-visible-launchers"), command: "moveLauncherToVisible", uiIcon: "bx bx-show", enabled: true } : null,
|
||||||
isVisibleItem ? { title: 'Move to available launchers', command: "moveLauncherToAvailable", uiIcon: "bx bx-hide", enabled: true } : null,
|
isVisibleItem ? { title: t("launcher_context_menu.move-to-available-launchers"), command: "moveLauncherToAvailable", uiIcon: "bx bx-hide", enabled: true } : null,
|
||||||
{ title: `Duplicate launcher <kbd data-command="duplicateSubtree">`, command: "duplicateSubtree", uiIcon: "bx bx-empty",
|
{ title: `${t("launcher_context_menu.duplicate-launcher")} <kbd data-command="duplicateSubtree">`, command: "duplicateSubtree", uiIcon: "bx bx-empty",
|
||||||
enabled: isItem }
|
enabled: isItem }
|
||||||
].filter(row => row !== null);
|
].filter(row => row !== null);
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectMenuItemHandler({command}) {
|
async selectMenuItemHandler({command}) {
|
||||||
if (command === 'resetLauncher') {
|
if (command === 'resetLauncher') {
|
||||||
const confirmed = await dialogService.confirm(`Do you really want to reset "${this.node.title}"?
|
const confirmed = await dialogService.confirm(t("launcher_context_menu.reset_launcher_confirm", { title: this.node.title }));
|
||||||
All data / settings in this note (and its children) will be lost
|
|
||||||
and the launcher will be returned to its original location.`);
|
|
||||||
|
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
await server.post(`special-notes/launchers/${this.node.data.noteId}/reset`);
|
await server.post(`special-notes/launchers/${this.node.data.noteId}/reset`);
|
||||||
|
@ -136,7 +136,7 @@ export default class TreeContextMenu {
|
|||||||
this.treeWidget.triggerCommand("openNewNoteSplit", {ntxId, notePath});
|
this.treeWidget.triggerCommand("openNewNoteSplit", {ntxId, notePath});
|
||||||
}
|
}
|
||||||
else if (command === 'convertNoteToAttachment') {
|
else if (command === 'convertNoteToAttachment') {
|
||||||
if (!await dialogService.confirm(`Are you sure you want to convert note selected notes into attachments of their parent notes?`)) {
|
if (!await dialogService.confirm(t("tree-context-menu.convert-to-attachment-confirm"))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ export default class TreeContextMenu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toastService.showMessage(`${converted} notes have been converted to attachments.`);
|
toastService.showMessage(t("tree-context-menu.converted-to-attachments", { count: converted }));
|
||||||
}
|
}
|
||||||
else if (command === 'copyNotePathToClipboard') {
|
else if (command === 'copyNotePathToClipboard') {
|
||||||
navigator.clipboard.writeText('#' + notePath);
|
navigator.clipboard.writeText('#' + notePath);
|
||||||
|
@ -5,6 +5,7 @@ import froca from "./froca.js";
|
|||||||
import hoistedNoteService from "./hoisted_note.js";
|
import hoistedNoteService from "./hoisted_note.js";
|
||||||
import ws from "./ws.js";
|
import ws from "./ws.js";
|
||||||
import appContext from "../components/app_context.js";
|
import appContext from "../components/app_context.js";
|
||||||
|
import { t } from './i18n.js';
|
||||||
|
|
||||||
async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
|
async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
|
||||||
branchIdsToMove = filterRootNote(branchIdsToMove);
|
branchIdsToMove = filterRootNote(branchIdsToMove);
|
||||||
@ -13,7 +14,7 @@ async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
|
|||||||
const beforeBranch = froca.getBranch(beforeBranchId);
|
const beforeBranch = froca.getBranch(beforeBranchId);
|
||||||
|
|
||||||
if (['root', '_lbRoot', '_lbAvailableLaunchers', '_lbVisibleLaunchers'].includes(beforeBranch.noteId)) {
|
if (['root', '_lbRoot', '_lbAvailableLaunchers', '_lbVisibleLaunchers'].includes(beforeBranch.noteId)) {
|
||||||
toastService.showError('Cannot move notes here.');
|
toastService.showError(t("branches.cannot-move-notes-here"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ async function moveAfterBranch(branchIdsToMove, afterBranchId) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (forbiddenNoteIds.includes(afterNote.noteId)) {
|
if (forbiddenNoteIds.includes(afterNote.noteId)) {
|
||||||
toastService.showError('Cannot move notes here.');
|
toastService.showError(t("branches.cannot-move-notes-here"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ async function moveToParentNote(branchIdsToMove, newParentBranchId) {
|
|||||||
const newParentBranch = froca.getBranch(newParentBranchId);
|
const newParentBranch = froca.getBranch(newParentBranchId);
|
||||||
|
|
||||||
if (newParentBranch.noteId === '_lbRoot') {
|
if (newParentBranch.noteId === '_lbRoot') {
|
||||||
toastService.showError('Cannot move notes here.');
|
toastService.showError(t("branches.cannot-move-notes-here"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +193,7 @@ function filterRootNote(branchIds) {
|
|||||||
function makeToast(id, message) {
|
function makeToast(id, message) {
|
||||||
return {
|
return {
|
||||||
id: id,
|
id: id,
|
||||||
title: "Delete status",
|
title: t("branches.delete-status"),
|
||||||
message: message,
|
message: message,
|
||||||
icon: "trash"
|
icon: "trash"
|
||||||
};
|
};
|
||||||
@ -207,9 +208,9 @@ ws.subscribeToMessages(async message => {
|
|||||||
toastService.closePersistent(message.taskId);
|
toastService.closePersistent(message.taskId);
|
||||||
toastService.showError(message.message);
|
toastService.showError(message.message);
|
||||||
} else if (message.type === 'taskProgressCount') {
|
} else if (message.type === 'taskProgressCount') {
|
||||||
toastService.showPersistent(makeToast(message.taskId, `Delete notes in progress: ${message.progressCount}`));
|
toastService.showPersistent(makeToast(message.taskId, t("branches.delete-notes-in-progress", { count: message.progressCount })));
|
||||||
} else if (message.type === 'taskSucceeded') {
|
} else if (message.type === 'taskSucceeded') {
|
||||||
const toast = makeToast(message.taskId, "Delete finished successfully.");
|
const toast = makeToast(message.taskId, t("branches.delete-finished-successfully"));
|
||||||
toast.closeAfter = 5000;
|
toast.closeAfter = 5000;
|
||||||
|
|
||||||
toastService.showPersistent(toast);
|
toastService.showPersistent(toast);
|
||||||
@ -225,9 +226,9 @@ ws.subscribeToMessages(async message => {
|
|||||||
toastService.closePersistent(message.taskId);
|
toastService.closePersistent(message.taskId);
|
||||||
toastService.showError(message.message);
|
toastService.showError(message.message);
|
||||||
} else if (message.type === 'taskProgressCount') {
|
} else if (message.type === 'taskProgressCount') {
|
||||||
toastService.showPersistent(makeToast(message.taskId, `Undeleting notes in progress: ${message.progressCount}`));
|
toastService.showPersistent(makeToast(message.taskId, t("branches.undeleting-notes-in-progress", { count: message.progressCount })));
|
||||||
} else if (message.type === 'taskSucceeded') {
|
} else if (message.type === 'taskSucceeded') {
|
||||||
const toast = makeToast(message.taskId, "Undeleting notes finished successfully.");
|
const toast = makeToast(message.taskId, t("branches.undeleting-notes-finished-successfully"));
|
||||||
toast.closeAfter = 5000;
|
toast.closeAfter = 5000;
|
||||||
|
|
||||||
toastService.showPersistent(toast);
|
toastService.showPersistent(toast);
|
||||||
|
@ -3,6 +3,7 @@ import server from "./server.js";
|
|||||||
import toastService from "./toast.js";
|
import toastService from "./toast.js";
|
||||||
import froca from "./froca.js";
|
import froca from "./froca.js";
|
||||||
import utils from "./utils.js";
|
import utils from "./utils.js";
|
||||||
|
import { t } from "./i18n.js";
|
||||||
|
|
||||||
async function getAndExecuteBundle(noteId, originEntity = null, script = null, params = null) {
|
async function getAndExecuteBundle(noteId, originEntity = null, script = null, params = null) {
|
||||||
const bundle = await server.post(`script/bundle/${noteId}`, {
|
const bundle = await server.post(`script/bundle/${noteId}`, {
|
||||||
@ -75,9 +76,23 @@ async function getWidgetBundlesByParent() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
widget = await executeBundle(bundle);
|
widget = await executeBundle(bundle);
|
||||||
widgetsByParent.add(widget);
|
if (widget) {
|
||||||
}
|
widget._noteId = bundle.noteId;
|
||||||
catch (e) {
|
widgetsByParent.add(widget);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
const noteId = bundle.noteId;
|
||||||
|
const note = await froca.getNote(noteId);
|
||||||
|
toastService.showPersistent({
|
||||||
|
title: t("toast.bundle-error.title"),
|
||||||
|
icon: "alert",
|
||||||
|
message: t("toast.bundle-error.message", {
|
||||||
|
id: noteId,
|
||||||
|
title: note.title,
|
||||||
|
message: e.message
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
logError("Widget initialization failed: ", e);
|
logError("Widget initialization failed: ", e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ async function copy(branchIds) {
|
|||||||
clipboard.writeHTML(links.join(', '));
|
clipboard.writeHTML(links.join(', '));
|
||||||
}
|
}
|
||||||
|
|
||||||
toastService.showMessage("Note(s) have been copied into clipboard.");
|
toastService.showMessage(t("clipboard.copied"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function cut(branchIds) {
|
function cut(branchIds) {
|
||||||
@ -87,7 +87,7 @@ function cut(branchIds) {
|
|||||||
if (clipboardBranchIds.length > 0) {
|
if (clipboardBranchIds.length > 0) {
|
||||||
clipboardMode = 'cut';
|
clipboardMode = 'cut';
|
||||||
|
|
||||||
toastService.showMessage("Note(s) have been cut into clipboard.");
|
toastService.showMessage(t("clipboard.cut"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,8 +217,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
|||||||
*/
|
*/
|
||||||
this.runOnBackend = async (func, params = []) => {
|
this.runOnBackend = async (func, params = []) => {
|
||||||
if (func?.constructor.name === "AsyncFunction" || func?.startsWith?.("async ")) {
|
if (func?.constructor.name === "AsyncFunction" || func?.startsWith?.("async ")) {
|
||||||
toastService.showError("You're passing an async function to api.runOnBackend() which will likely not work as you intended. "
|
toastService.showError(t("frontend_script_api.async_warning"));
|
||||||
+ "Either make the function synchronous (by removing 'async' keyword), or use api.runAsyncOnBackendWithManualTransactionHandling()");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.__runOnBackendInner(func, params, true);
|
return await this.__runOnBackendInner(func, params, true);
|
||||||
@ -240,8 +239,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
|||||||
*/
|
*/
|
||||||
this.runAsyncOnBackendWithManualTransactionHandling = async (func, params = []) => {
|
this.runAsyncOnBackendWithManualTransactionHandling = async (func, params = []) => {
|
||||||
if (func?.constructor.name === "Function" || func?.startsWith?.("function")) {
|
if (func?.constructor.name === "Function" || func?.startsWith?.("function")) {
|
||||||
toastService.showError("You're passing a synchronous function to api.runAsyncOnBackendWithManualTransactionHandling(), " +
|
toastService.showError(t("frontend_script_api.sync_warning"));
|
||||||
"while you should likely use api.runOnBackend() instead.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.__runOnBackendInner(func, params, false);
|
return await this.__runOnBackendInner(func, params, false);
|
||||||
|
@ -26,21 +26,6 @@ function setupGlobs() {
|
|||||||
// for CKEditor integration (button on block toolbar)
|
// for CKEditor integration (button on block toolbar)
|
||||||
window.glob.importMarkdownInline = async () => appContext.triggerCommand("importMarkdownInline");
|
window.glob.importMarkdownInline = async () => appContext.triggerCommand("importMarkdownInline");
|
||||||
|
|
||||||
window.glob.SEARCH_HELP_TEXT = `
|
|
||||||
<strong>Search tips</strong> - also see <button class="btn btn-sm" type="button" data-help-page="search.html">complete help on search</button>
|
|
||||||
<p>
|
|
||||||
<ul>
|
|
||||||
<li>Just enter any text for full text search</li>
|
|
||||||
<li><code>#abc</code> - returns notes with label abc</li>
|
|
||||||
<li><code>#year = 2019</code> - matches notes with label <code>year</code> having value <code>2019</code></li>
|
|
||||||
<li><code>#rock #pop</code> - matches notes which have both <code>rock</code> and <code>pop</code> labels</li>
|
|
||||||
<li><code>#rock or #pop</code> - only one of the labels must be present</li>
|
|
||||||
<li><code>#year <= 2000</code> - numerical comparison (also >, >=, <).</li>
|
|
||||||
<li><code>note.dateCreated >= MONTH-1</code> - notes created in the last month</li>
|
|
||||||
<li><code>=handler</code> - will execute script defined in <code>handler</code> relation to get results</li>
|
|
||||||
</ul>
|
|
||||||
</p>`;
|
|
||||||
|
|
||||||
window.onerror = function (msg, url, lineNo, columnNo, error) {
|
window.onerror = function (msg, url, lineNo, columnNo, error) {
|
||||||
const string = msg.toLowerCase();
|
const string = msg.toLowerCase();
|
||||||
|
|
||||||
@ -64,6 +49,28 @@ function setupGlobs() {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.addEventListener("unhandledrejection", (e) => {
|
||||||
|
const string = e?.reason?.message?.toLowerCase();
|
||||||
|
|
||||||
|
let message = "Uncaught error: ";
|
||||||
|
|
||||||
|
if (string?.includes("script error")) {
|
||||||
|
message += 'No details available';
|
||||||
|
} else {
|
||||||
|
message += [
|
||||||
|
`Message: ${e.reason.message}`,
|
||||||
|
`Line: ${e.reason.lineNumber}`,
|
||||||
|
`Column: ${e.reason.columnNumber}`,
|
||||||
|
`Error object: ${JSON.stringify(e.reason)}`,
|
||||||
|
`Stack: ${e.reason && e.reason.stack}`
|
||||||
|
].join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.logError(message);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
for (const appCssNoteId of glob.appCssNoteIds || []) {
|
for (const appCssNoteId of glob.appCssNoteIds || []) {
|
||||||
libraryLoader.requireCss(`api/notes/download/${appCssNoteId}`, false);
|
libraryLoader.requireCss(`api/notes/download/${appCssNoteId}`, false);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import appContext from "../components/app_context.js";
|
|||||||
import treeService from "./tree.js";
|
import treeService from "./tree.js";
|
||||||
import dialogService from "./dialog.js";
|
import dialogService from "./dialog.js";
|
||||||
import froca from "./froca.js";
|
import froca from "./froca.js";
|
||||||
|
import { t } from "./i18n.js";
|
||||||
|
|
||||||
function getHoistedNoteId() {
|
function getHoistedNoteId() {
|
||||||
const activeNoteContext = appContext.tabManager.getActiveContext();
|
const activeNoteContext = appContext.tabManager.getActiveContext();
|
||||||
@ -53,7 +54,7 @@ async function checkNoteAccess(notePath, noteContext) {
|
|||||||
const hoistedNote = await froca.getNote(hoistedNoteId);
|
const hoistedNote = await froca.getNote(hoistedNoteId);
|
||||||
|
|
||||||
if ((!hoistedNote.hasAncestor('_hidden') || resolvedNotePath.includes('_lbBookmarks'))
|
if ((!hoistedNote.hasAncestor('_hidden') || resolvedNotePath.includes('_lbBookmarks'))
|
||||||
&& !await dialogService.confirm(`Requested note '${requestedNote.title}' is outside of hoisted note '${hoistedNote.title}' subtree and you must unhoist to access the note. Do you want to proceed with unhoisting?`)) {
|
&& !await dialogService.confirm(t("hoisted_note.confirm_unhoisting", { requestedNote: requestedNote.title, hoistedNote: hoistedNote.title }))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@ function copyImageReferenceToClipboard($imageWrapper) {
|
|||||||
const success = document.execCommand('copy');
|
const success = document.execCommand('copy');
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
toastService.showMessage("A reference to the image has been copied to clipboard. This can be pasted in any text note.");
|
toastService.showMessage(t("image.copied-to-clipboard"));
|
||||||
} else {
|
} else {
|
||||||
toastService.showAndLogError("Could not copy the image reference to clipboard.");
|
toastService.showAndLogError(t("image.cannot-copy"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -36,7 +36,7 @@ export async function uploadFiles(entityType, parentNoteId, files, options) {
|
|||||||
type: 'POST',
|
type: 'POST',
|
||||||
timeout: 60 * 60 * 1000,
|
timeout: 60 * 60 * 1000,
|
||||||
error: function (xhr) {
|
error: function (xhr) {
|
||||||
toastService.showError(`Import failed: ${xhr.responseText}`);
|
toastService.showError(t("import.failed", { message: xhr.responseText }));
|
||||||
},
|
},
|
||||||
contentType: false, // NEEDED, DON'T REMOVE THIS
|
contentType: false, // NEEDED, DON'T REMOVE THIS
|
||||||
processData: false, // NEEDED, DON'T REMOVE THIS
|
processData: false, // NEEDED, DON'T REMOVE THIS
|
||||||
|
@ -5,6 +5,7 @@ import ws from "./ws.js";
|
|||||||
import froca from "./froca.js";
|
import froca from "./froca.js";
|
||||||
import treeService from "./tree.js";
|
import treeService from "./tree.js";
|
||||||
import toastService from "./toast.js";
|
import toastService from "./toast.js";
|
||||||
|
import { t } from "./i18n.js";
|
||||||
|
|
||||||
async function createNote(parentNotePath, options = {}) {
|
async function createNote(parentNotePath, options = {}) {
|
||||||
options = Object.assign({
|
options = Object.assign({
|
||||||
@ -119,7 +120,7 @@ async function duplicateSubtree(noteId, parentNotePath) {
|
|||||||
activeNoteContext.setNote(`${parentNotePath}/${note.noteId}`);
|
activeNoteContext.setNote(`${parentNotePath}/${note.noteId}`);
|
||||||
|
|
||||||
const origNote = await froca.getNote(noteId);
|
const origNote = await froca.getNote(noteId);
|
||||||
toastService.showMessage(`Note "${origNote.title}" has been duplicated`);
|
toastService.showMessage(t("note_create.duplicated", { title: origNote.title }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -6,6 +6,7 @@ import appContext from "../components/app_context.js";
|
|||||||
import froca from "./froca.js";
|
import froca from "./froca.js";
|
||||||
import utils from "./utils.js";
|
import utils from "./utils.js";
|
||||||
import options from "./options.js";
|
import options from "./options.js";
|
||||||
|
import { t } from './i18n.js';
|
||||||
|
|
||||||
let protectedSessionDeferred = null;
|
let protectedSessionDeferred = null;
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ async function setupProtectedSession(password) {
|
|||||||
const response = await server.post('login/protected', { password: password });
|
const response = await server.post('login/protected', { password: password });
|
||||||
|
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
toastService.showError("Wrong password.", 3000);
|
toastService.showError(t("protected_session.wrong_password"), 3000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ ws.subscribeToMessages(async message => {
|
|||||||
protectedSessionDeferred = null;
|
protectedSessionDeferred = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
toastService.showMessage("Protected session has been started.");
|
toastService.showMessage(t("protected_session.started"));
|
||||||
}
|
}
|
||||||
else if (message.type === 'protectedSessionLogout') {
|
else if (message.type === 'protectedSessionLogout') {
|
||||||
utils.reloadFrontendApp(`Protected session logout`);
|
utils.reloadFrontendApp(`Protected session logout`);
|
||||||
@ -85,10 +86,10 @@ async function protectNote(noteId, protect, includingSubtree) {
|
|||||||
await server.put(`notes/${noteId}/protect/${protect ? 1 : 0}?subtree=${includingSubtree ? 1 : 0}`);
|
await server.put(`notes/${noteId}/protect/${protect ? 1 : 0}?subtree=${includingSubtree ? 1 : 0}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeToast(message, protectingLabel, text) {
|
function makeToast(message, title, text) {
|
||||||
return {
|
return {
|
||||||
id: message.taskId,
|
id: message.taskId,
|
||||||
title: `${protectingLabel} status`,
|
title,
|
||||||
message: text,
|
message: text,
|
||||||
icon: message.data.protect ? "check-shield" : "shield"
|
icon: message.data.protect ? "check-shield" : "shield"
|
||||||
};
|
};
|
||||||
@ -99,15 +100,19 @@ ws.subscribeToMessages(async message => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const protectingLabel = message.data.protect ? "Protecting" : "Unprotecting";
|
const isProtecting = message.data.protect;
|
||||||
|
const title = isProtecting ? t("protected_session.protecting-title") : t("protected_session.unprotecting-title");
|
||||||
|
|
||||||
if (message.type === 'taskError') {
|
if (message.type === 'taskError') {
|
||||||
toastService.closePersistent(message.taskId);
|
toastService.closePersistent(message.taskId);
|
||||||
toastService.showError(message.message);
|
toastService.showError(message.message);
|
||||||
} else if (message.type === 'taskProgressCount') {
|
} else if (message.type === 'taskProgressCount') {
|
||||||
toastService.showPersistent(makeToast(message, protectingLabel,`${protectingLabel} in progress: ${message.progressCount}`));
|
const count = message.progressCount;
|
||||||
|
const text = ( isProtecting ? t("protected_session.protecting-in-progress", { count }) : t("protected_session.unprotecting-in-progress-count", { count }));
|
||||||
|
toastService.showPersistent(makeToast(message, title, text));
|
||||||
} else if (message.type === 'taskSucceeded') {
|
} else if (message.type === 'taskSucceeded') {
|
||||||
const toast = makeToast(message, protectingLabel, `${protectingLabel} finished successfully.`);
|
const text = (isProtecting ? t("protected_session.protecting-finished-successfully") : t("protected_session.unprotecting-finished-successfully"))
|
||||||
|
const toast = makeToast(message, title, text);
|
||||||
toast.closeAfter = 3000;
|
toast.closeAfter = 3000;
|
||||||
|
|
||||||
toastService.showPersistent(toast);
|
toastService.showPersistent(toast);
|
||||||
|
@ -5,7 +5,7 @@ async function syncNow(ignoreNotConfigured = false) {
|
|||||||
const result = await server.post('sync/now');
|
const result = await server.post('sync/now');
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
toastService.showMessage("Sync finished successfully.");
|
toastService.showMessage(t("sync.finished-successfully"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (result.message.length > 200) {
|
if (result.message.length > 200) {
|
||||||
@ -13,7 +13,7 @@ async function syncNow(ignoreNotConfigured = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ignoreNotConfigured || result.errorCode !== 'NOT_CONFIGURED') {
|
if (!ignoreNotConfigured || result.errorCode !== 'NOT_CONFIGURED') {
|
||||||
toastService.showError(`Sync failed: ${result.message}`);
|
toastService.showError(t("sync.failed", { message: result.message }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ function toast(options) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$toast.find('.toast-title').text(options.title);
|
$toast.find('.toast-title').text(options.title);
|
||||||
$toast.find('.toast-body').text(options.message);
|
$toast.find('.toast-body').html(options.message);
|
||||||
|
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
$toast.attr("id", `toast-${options.id}`);
|
$toast.attr("id", `toast-${options.id}`);
|
||||||
|
@ -114,10 +114,10 @@ async function handleMessage(event) {
|
|||||||
await executeFrontendUpdate(message.data.entityChanges);
|
await executeFrontendUpdate(message.data.entityChanges);
|
||||||
}
|
}
|
||||||
else if (message.type === 'sync-hash-check-failed') {
|
else if (message.type === 'sync-hash-check-failed') {
|
||||||
toastService.showError("Sync check failed!", 60000);
|
toastService.showError(t("ws.sync-check-failed"), 60000);
|
||||||
}
|
}
|
||||||
else if (message.type === 'consistency-checks-failed') {
|
else if (message.type === 'consistency-checks-failed') {
|
||||||
toastService.showError("Consistency checks failed! See logs for details.", 50 * 60000);
|
toastService.showError(t("ws.consistency-checks-failed"), 50 * 60000);
|
||||||
}
|
}
|
||||||
else if (message.type === 'api-log-messages') {
|
else if (message.type === 'api-log-messages') {
|
||||||
appContext.triggerEvent("apiLogMessages", {noteId: message.noteId, messages: message.messages});
|
appContext.triggerEvent("apiLogMessages", {noteId: message.noteId, messages: message.messages});
|
||||||
@ -189,7 +189,7 @@ async function consumeFrontendUpdateData() {
|
|||||||
else {
|
else {
|
||||||
console.log("nonProcessedEntityChanges causing the timeout", nonProcessedEntityChanges);
|
console.log("nonProcessedEntityChanges causing the timeout", nonProcessedEntityChanges);
|
||||||
|
|
||||||
toastService.showError(`Encountered error "${e.message}", check out the console.`);
|
toastService.showError(t("ws.encountered-error", { message: e.message }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import Component from "../components/component.js";
|
import Component from "../components/component.js";
|
||||||
|
import froca from "../services/froca.js";
|
||||||
import { t } from "../services/i18n.js";
|
import { t } from "../services/i18n.js";
|
||||||
import toastService from "../services/toast.js";
|
import toastService from "../services/toast.js";
|
||||||
|
|
||||||
@ -84,15 +85,8 @@ class BasicWidget extends Component {
|
|||||||
render() {
|
render() {
|
||||||
try {
|
try {
|
||||||
this.doRender();
|
this.doRender();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toastService.showPersistent({
|
this.logRenderingError(e);
|
||||||
title: t("toast.widget-error.title"),
|
|
||||||
icon: "alert",
|
|
||||||
message: t("toast.widget-error.message", {
|
|
||||||
title: this.widgetTitle,
|
|
||||||
message: e.message
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$widget.attr('data-component-id', this.componentId);
|
this.$widget.attr('data-component-id', this.componentId);
|
||||||
@ -131,6 +125,35 @@ class BasicWidget extends Component {
|
|||||||
return this.$widget;
|
return this.$widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logRenderingError(e) {
|
||||||
|
console.log("Got issue in widget ", this);
|
||||||
|
console.error(e);
|
||||||
|
|
||||||
|
let noteId = this._noteId;
|
||||||
|
if (this._noteId) {
|
||||||
|
froca.getNote(noteId, true).then((note) => {
|
||||||
|
toastService.showPersistent({
|
||||||
|
title: t("toast.widget-error.title"),
|
||||||
|
icon: "alert",
|
||||||
|
message: t("toast.widget-error.message-custom", {
|
||||||
|
id: noteId,
|
||||||
|
title: note.title,
|
||||||
|
message: e.message
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toastService.showPersistent({
|
||||||
|
title: t("toast.widget-error.title"),
|
||||||
|
icon: "alert",
|
||||||
|
message: t("toast.widget-error.message-unknown", {
|
||||||
|
message: e.message
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the widget is enabled. Widgets are enabled by default. Generally setting this to `false` will cause the widget not to be displayed, however it will still be available on the DOM but hidden.
|
* Indicates if the widget is enabled. Widgets are enabled by default. Generally setting this to `false` will cause the widget not to be displayed, however it will still be available on the DOM but hidden.
|
||||||
* @returns
|
* @returns
|
||||||
|
@ -127,18 +127,18 @@ export default class NoteActionsWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async convertNoteIntoAttachmentCommand() {
|
async convertNoteIntoAttachmentCommand() {
|
||||||
if (!await dialogService.confirm(`Are you sure you want to convert note '${this.note.title}' into an attachment of the parent note?`)) {
|
if (!await dialogService.confirm(t("note_actions.convert_into_attachment_prompt", { title: this.note.title }))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {attachment: newAttachment} = await server.post(`notes/${this.noteId}/convert-to-attachment`);
|
const {attachment: newAttachment} = await server.post(`notes/${this.noteId}/convert-to-attachment`);
|
||||||
|
|
||||||
if (!newAttachment) {
|
if (!newAttachment) {
|
||||||
toastService.showMessage(`Converting note '${this.note.title}' failed.`);
|
toastService.showMessage(t("note_actions.convert_into_attachment_failed", { title: this.note.title }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
toastService.showMessage(`Note '${newAttachment.title}' has been converted to attachment.`);
|
toastService.showMessage(t("note_actions.convert_into_attachment_successful", { title: newAttachment.title }));
|
||||||
await ws.waitForMaxKnownEntityChangeId();
|
await ws.waitForMaxKnownEntityChangeId();
|
||||||
await appContext.tabManager.getActiveContext().setNote(newAttachment.ownerId, {
|
await appContext.tabManager.getActiveContext().setNote(newAttachment.ownerId, {
|
||||||
viewScope: {
|
viewScope: {
|
||||||
|
@ -8,7 +8,11 @@ export default class Container extends BasicWidget {
|
|||||||
|
|
||||||
renderChildren() {
|
renderChildren() {
|
||||||
for (const widget of this.children) {
|
for (const widget of this.children) {
|
||||||
this.$widget.append(widget.render());
|
try {
|
||||||
|
this.$widget.append(widget.render());
|
||||||
|
} catch (e) {
|
||||||
|
widget.logRenderingError(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -666,8 +666,9 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const node = this.prepareNode(branch);
|
const node = this.prepareNode(branch);
|
||||||
|
if (node) {
|
||||||
noteList.push(node);
|
noteList.push(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return noteList;
|
return noteList;
|
||||||
@ -709,7 +710,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
const note = branch.getNoteFromCache();
|
const note = branch.getNoteFromCache();
|
||||||
|
|
||||||
if (!note) {
|
if (!note) {
|
||||||
throw new Error(`Branch '${branch.branchId}' has no child note '${branch.noteId}'`);
|
console.warn(`Branch '${branch.branchId}' has no child note '${branch.noteId}'`);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = `${branch.prefix ? (`${branch.prefix} - `) : ""}${note.title}`;
|
const title = `${branch.prefix ? (`${branch.prefix} - `) : ""}${note.title}`;
|
||||||
@ -1031,7 +1033,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
activeNode.load(true);
|
activeNode.load(true);
|
||||||
activeNode.setExpanded(true, {noAnimation: true});
|
activeNode.setExpanded(true, {noAnimation: true});
|
||||||
|
|
||||||
toastService.showMessage("Saved search note refreshed.");
|
toastService.showMessage(t("note_tree.saved-search-note-refreshed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
async batchUpdate(cb) {
|
async batchUpdate(cb) {
|
||||||
@ -1075,7 +1077,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
node.setExpanded(false);
|
node.setExpanded(false);
|
||||||
|
|
||||||
if (noneCollapsedYet) {
|
if (noneCollapsedYet) {
|
||||||
toastService.showMessage("Auto collapsing notes after inactivity...");
|
toastService.showMessage(t("note_tree.auto-collapsing-notes-after-inactivity"));
|
||||||
noneCollapsedYet = false;
|
noneCollapsedYet = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ export default class NoteTypeWidget extends NoteContextAwareWidget {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await dialogService.confirm("It is not recommended to change note type when note content is not empty. Do you want to continue anyway?");
|
return await dialogService.confirm(t("note_types.confirm-change"));
|
||||||
}
|
}
|
||||||
|
|
||||||
async entitiesReloadedEvent({ loadResults }) {
|
async entitiesReloadedEvent({ loadResults }) {
|
||||||
|
@ -42,6 +42,10 @@ const TPL = `
|
|||||||
word-break:keep-all;
|
word-break:keep-all;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
.promoted-attribute-cell input[type="checkbox"] {
|
||||||
|
height: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="promoted-attributes-container"></div>
|
<div class="promoted-attributes-container"></div>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||||
|
import toastService from "../services/toast.js";
|
||||||
|
import { t } from "../services/i18n.js";
|
||||||
|
|
||||||
const WIDGET_TPL = `
|
const WIDGET_TPL = `
|
||||||
<div class="card widget">
|
<div class="card widget">
|
||||||
@ -54,7 +56,9 @@ class RightPanelWidget extends NoteContextAwareWidget {
|
|||||||
this.$buttons.append(buttonWidget.render());
|
this.$buttons.append(buttonWidget.render());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initialized = this.doRenderBody();
|
this.initialized = this.doRenderBody().catch(e => {
|
||||||
|
this.logRenderingError(e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,9 +61,9 @@ export default class SearchString extends AbstractSearchOption {
|
|||||||
|
|
||||||
await this.setAttribute('label', 'searchString', searchString);
|
await this.setAttribute('label', 'searchString', searchString);
|
||||||
|
|
||||||
if (this.note.title.startsWith('Search: ')) {
|
if (this.note.title.startsWith(t("search_string.search_prefix"))) {
|
||||||
await server.put(`notes/${this.note.noteId}/title`, {
|
await server.put(`notes/${this.note.noteId}/title`, {
|
||||||
title: `Search: ${searchString.length < 30 ? searchString : `${searchString.substr(0, 30)}…`}`
|
title: `${t("search_string.search_prefix")} ${searchString.length < 30 ? searchString : `${searchString.substr(0, 30)}…`}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
@ -260,8 +260,10 @@ export default class TabRowWidget extends BasicWidget {
|
|||||||
y: e.pageY,
|
y: e.pageY,
|
||||||
items: [
|
items: [
|
||||||
{title: t('tab_row.close'), command: "closeTab", uiIcon: "bx bx-x"},
|
{title: t('tab_row.close'), command: "closeTab", uiIcon: "bx bx-x"},
|
||||||
{title: t('tab_row.close_other_tabs'), command: "closeOtherTabs", uiIcon: "bx bx-x"},
|
{title: t('tab_row.close_other_tabs'), command: "closeOtherTabs", uiIcon: "bx bx-empty", enabled: appContext.tabManager.noteContexts.length !== 1},
|
||||||
{title: t('tab_row.close_all_tabs'), command: "closeAllTabs", uiIcon: "bx bx-x"},
|
{title: t('tab_row.close_right_tabs'), command: "closeRightTabs", uiIcon: "bx bx-empty", enabled: appContext.tabManager.noteContexts.at(-1).ntxId !== ntxId},
|
||||||
|
{title: t('tab_row.close_all_tabs'), command: "closeAllTabs", uiIcon: "bx bx-empty"},
|
||||||
|
{ title: "----" },
|
||||||
{title: t('tab_row.move_tab_to_new_window'), command: "moveTabToNewWindow", uiIcon: "bx bx-window-open"}
|
{title: t('tab_row.move_tab_to_new_window'), command: "moveTabToNewWindow", uiIcon: "bx bx-window-open"}
|
||||||
],
|
],
|
||||||
selectMenuItemHandler: ({command}) => {
|
selectMenuItemHandler: ({command}) => {
|
||||||
|
120
src/public/app/widgets/type_widgets/abstract_code_type_widget.js
Normal file
120
src/public/app/widgets/type_widgets/abstract_code_type_widget.js
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import TypeWidget from "./type_widget.js";
|
||||||
|
import libraryLoader from "../../services/library_loader.js";
|
||||||
|
import options from "../../services/options.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract {@link TypeWidget} which implements the CodeMirror editor, meant to be used as a parent for
|
||||||
|
* widgets requiring the editor.
|
||||||
|
*
|
||||||
|
* The widget handles the loading and initialization of the CodeMirror editor, as well as some common
|
||||||
|
* actions.
|
||||||
|
*
|
||||||
|
* The derived class must:
|
||||||
|
*
|
||||||
|
* - Define `$editor` in the constructor.
|
||||||
|
* - Call `super.doRender()` in the extended class.
|
||||||
|
* - Call `this._update(note, content)` in `#doRefresh(note)`.
|
||||||
|
*/
|
||||||
|
export default class AbstractCodeTypeWidget extends TypeWidget {
|
||||||
|
|
||||||
|
doRender() {
|
||||||
|
this.initialized = this.#initEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
async #initEditor() {
|
||||||
|
await libraryLoader.requireLibrary(libraryLoader.CODE_MIRROR);
|
||||||
|
|
||||||
|
// these conflict with backward/forward navigation shortcuts
|
||||||
|
delete CodeMirror.keyMap.default["Alt-Left"];
|
||||||
|
delete CodeMirror.keyMap.default["Alt-Right"];
|
||||||
|
|
||||||
|
CodeMirror.modeURL = `${window.glob.assetPath}/node_modules/codemirror/mode/%N/%N.js`;
|
||||||
|
CodeMirror.modeInfo.find(mode=>mode.name === "JavaScript").mimes.push(...["application/javascript;env=frontend", "application/javascript;env=backend"]);
|
||||||
|
CodeMirror.modeInfo.find(mode=>mode.name === "SQLite").mimes=["text/x-sqlite", "text/x-sqlite;schema=trilium"];
|
||||||
|
|
||||||
|
this.codeEditor = CodeMirror(this.$editor[0], {
|
||||||
|
value: "",
|
||||||
|
viewportMargin: Infinity,
|
||||||
|
indentUnit: 4,
|
||||||
|
matchBrackets: true,
|
||||||
|
matchTags: {bothTags: true},
|
||||||
|
highlightSelectionMatches: {showToken: false, annotateScrollbar: false},
|
||||||
|
lineNumbers: true,
|
||||||
|
// we line wrap partly also because without it horizontal scrollbar displays only when you scroll
|
||||||
|
// all the way to the bottom of the note. With line wrap, there's no horizontal scrollbar so no problem
|
||||||
|
lineWrapping: options.is('codeLineWrapEnabled'),
|
||||||
|
...this.getExtraOpts()
|
||||||
|
});
|
||||||
|
this.onEditorInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be extended in derived classes to add extra options to the CodeMirror constructor. The options are appended
|
||||||
|
* at the end, so it is possible to override the default values introduced by the abstract editor as well.
|
||||||
|
*
|
||||||
|
* @returns the extra options to be passed to the CodeMirror constructor.
|
||||||
|
*/
|
||||||
|
getExtraOpts() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called as soon as the CodeMirror library has been loaded and the editor was constructed. Can be extended in
|
||||||
|
* derived classes to add additional functionality or to register event handlers.
|
||||||
|
*
|
||||||
|
* By default, it does nothing.
|
||||||
|
*/
|
||||||
|
onEditorInitialized() {
|
||||||
|
// Do nothing by default.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must be called by the derived classes in `#doRefresh(note)` in order to react to changes.
|
||||||
|
*
|
||||||
|
* @param {*} note the note that was changed.
|
||||||
|
* @param {*} content the new content of the note.
|
||||||
|
*/
|
||||||
|
_update(note, content) {
|
||||||
|
// CodeMirror breaks pretty badly on null, so even though it shouldn't happen (guarded by a consistency check)
|
||||||
|
// we provide fallback
|
||||||
|
this.codeEditor.setValue(content || "");
|
||||||
|
this.codeEditor.clearHistory();
|
||||||
|
|
||||||
|
let info = CodeMirror.findModeByMIME(note.mime);
|
||||||
|
if (!info) {
|
||||||
|
// Switch back to plain text if CodeMirror does not have a mode for whatever MIME type we're editing.
|
||||||
|
// To avoid inheriting a mode from a previously open code note.
|
||||||
|
info = CodeMirror.findModeByMIME("text/plain");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.codeEditor.setOption("mode", info.mime);
|
||||||
|
CodeMirror.autoLoadMode(this.codeEditor, info.mode);
|
||||||
|
};
|
||||||
|
|
||||||
|
show() {
|
||||||
|
this.$widget.show();
|
||||||
|
|
||||||
|
if (this.codeEditor) { // show can be called before render
|
||||||
|
this.codeEditor.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
focus() {
|
||||||
|
this.$editor.focus();
|
||||||
|
this.codeEditor.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToEnd() {
|
||||||
|
this.codeEditor.setCursor(this.codeEditor.lineCount(), 0);
|
||||||
|
this.codeEditor.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
if (this.codeEditor) {
|
||||||
|
this.spacedUpdate.allowUpdateWithoutChange(() => {
|
||||||
|
this.codeEditor.setValue('');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,7 @@
|
|||||||
import { t } from "../../services/i18n.js";
|
import { t } from "../../services/i18n.js";
|
||||||
import libraryLoader from "../../services/library_loader.js";
|
|
||||||
import TypeWidget from "./type_widget.js";
|
|
||||||
import keyboardActionService from "../../services/keyboard_actions.js";
|
import keyboardActionService from "../../services/keyboard_actions.js";
|
||||||
import options from "../../services/options.js";
|
import options from "../../services/options.js";
|
||||||
|
import AbstractCodeTypeWidget from "./abstract_code_type_widget.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="note-detail-code note-detail-printable">
|
<div class="note-detail-code note-detail-printable">
|
||||||
@ -21,53 +20,31 @@ const TPL = `
|
|||||||
<div class="note-detail-code-editor"></div>
|
<div class="note-detail-code-editor"></div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
export default class EditableCodeTypeWidget extends TypeWidget {
|
export default class EditableCodeTypeWidget extends AbstractCodeTypeWidget {
|
||||||
static getType() { return "editableCode"; }
|
static getType() { return "editableCode"; }
|
||||||
|
|
||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
|
this.contentSized();
|
||||||
this.$editor = this.$widget.find('.note-detail-code-editor');
|
this.$editor = this.$widget.find('.note-detail-code-editor');
|
||||||
|
|
||||||
keyboardActionService.setupActionsForElement('code-detail', this.$widget, this);
|
keyboardActionService.setupActionsForElement('code-detail', this.$widget, this);
|
||||||
|
|
||||||
super.doRender();
|
super.doRender();
|
||||||
|
|
||||||
this.initialized = this.initEditor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async initEditor() {
|
getExtraOpts() {
|
||||||
await libraryLoader.requireLibrary(libraryLoader.CODE_MIRROR);
|
return {
|
||||||
|
|
||||||
CodeMirror.keyMap.default["Shift-Tab"] = "indentLess";
|
|
||||||
CodeMirror.keyMap.default["Tab"] = "indentMore";
|
|
||||||
|
|
||||||
// these conflict with backward/forward navigation shortcuts
|
|
||||||
delete CodeMirror.keyMap.default["Alt-Left"];
|
|
||||||
delete CodeMirror.keyMap.default["Alt-Right"];
|
|
||||||
|
|
||||||
CodeMirror.modeURL = `${window.glob.assetPath}/node_modules/codemirror/mode/%N/%N.js`;
|
|
||||||
CodeMirror.modeInfo.find(mode=>mode.name === "JavaScript").mimes.push(...["application/javascript;env=frontend", "application/javascript;env=backend"]);
|
|
||||||
CodeMirror.modeInfo.find(mode=>mode.name === "SQLite").mimes=["text/x-sqlite", "text/x-sqlite;schema=trilium"];
|
|
||||||
|
|
||||||
this.codeEditor = CodeMirror(this.$editor[0], {
|
|
||||||
value: "",
|
|
||||||
viewportMargin: Infinity,
|
|
||||||
indentUnit: 4,
|
|
||||||
matchBrackets: true,
|
|
||||||
keyMap: options.is('vimKeymapEnabled') ? "vim": "default",
|
keyMap: options.is('vimKeymapEnabled') ? "vim": "default",
|
||||||
matchTags: {bothTags: true},
|
|
||||||
highlightSelectionMatches: {showToken: false, annotateScrollbar: false},
|
|
||||||
lint: true,
|
lint: true,
|
||||||
gutters: ["CodeMirror-lint-markers"],
|
gutters: ["CodeMirror-lint-markers"],
|
||||||
lineNumbers: true,
|
|
||||||
tabindex: 300,
|
tabindex: 300,
|
||||||
// we line wrap partly also because without it horizontal scrollbar displays only when you scroll
|
|
||||||
// all the way to the bottom of the note. With line wrap, there's no horizontal scrollbar so no problem
|
|
||||||
lineWrapping: options.is('codeLineWrapEnabled'),
|
|
||||||
dragDrop: false, // with true the editor inlines dropped files which is not what we expect
|
dragDrop: false, // with true the editor inlines dropped files which is not what we expect
|
||||||
placeholder: t('editable_code.placeholder'),
|
placeholder: t('editable_code.placeholder'),
|
||||||
});
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditorInitialized() {
|
||||||
this.codeEditor.on('change', () => this.spacedUpdate.scheduleUpdate());
|
this.codeEditor.on('change', () => this.spacedUpdate.scheduleUpdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,57 +52,18 @@ export default class EditableCodeTypeWidget extends TypeWidget {
|
|||||||
const blob = await this.note.getBlob();
|
const blob = await this.note.getBlob();
|
||||||
|
|
||||||
await this.spacedUpdate.allowUpdateWithoutChange(() => {
|
await this.spacedUpdate.allowUpdateWithoutChange(() => {
|
||||||
// CodeMirror breaks pretty badly on null, so even though it shouldn't happen (guarded by a consistency check)
|
this._update(note, blob.content);
|
||||||
// we provide fallback
|
|
||||||
this.codeEditor.setValue(blob.content || "");
|
|
||||||
this.codeEditor.clearHistory();
|
|
||||||
|
|
||||||
let info = CodeMirror.findModeByMIME(note.mime);
|
|
||||||
if (!info) {
|
|
||||||
// Switch back to plain text if CodeMirror does not have a mode for whatever MIME type we're editing.
|
|
||||||
// To avoid inheriting a mode from a previously open code note.
|
|
||||||
info = CodeMirror.findModeByMIME("text/plain");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.codeEditor.setOption("mode", info.mime);
|
|
||||||
CodeMirror.autoLoadMode(this.codeEditor, info.mode);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.show();
|
this.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
show() {
|
|
||||||
this.$widget.show();
|
|
||||||
|
|
||||||
if (this.codeEditor) { // show can be called before render
|
|
||||||
this.codeEditor.refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getData() {
|
getData() {
|
||||||
return {
|
return {
|
||||||
content: this.codeEditor.getValue()
|
content: this.codeEditor.getValue()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
|
||||||
this.$editor.focus();
|
|
||||||
this.codeEditor.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollToEnd() {
|
|
||||||
this.codeEditor.setCursor(this.codeEditor.lineCount(), 0);
|
|
||||||
this.codeEditor.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
if (this.codeEditor) {
|
|
||||||
this.spacedUpdate.allowUpdateWithoutChange(() => {
|
|
||||||
this.codeEditor.setValue('');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async executeWithCodeEditorEvent({resolve, ntxId}) {
|
async executeWithCodeEditorEvent({resolve, ntxId}) {
|
||||||
if (!this.isNoteContext(ntxId)) {
|
if (!this.isNoteContext(ntxId)) {
|
||||||
return;
|
return;
|
||||||
|
@ -18,14 +18,28 @@ const TPL = `
|
|||||||
width: 130px;
|
width: 130px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
padding; 10px;
|
|
||||||
border: 1px transparent solid;
|
border: 1px transparent solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspace-notes .workspace-note:hover {
|
.workspace-notes .workspace-note:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid var(--main-border-color);
|
border: 1px solid var(--main-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.note-detail-empty-results .aa-dropdown-menu {
|
||||||
|
max-height: 50vh;
|
||||||
|
overflow: scroll;
|
||||||
|
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-tab-search .note-autocomplete-input {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-tab-search .input-clearer-button {
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.workspace-icon {
|
.workspace-icon {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -33,14 +47,14 @@ const TPL = `
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="workspace-notes"></div>
|
||||||
|
<div class="form-group empty-tab-search">
|
||||||
<label>${t('empty.open_note_instruction')}</label>
|
<label>${t('empty.open_note_instruction')}</label>
|
||||||
<div class="input-group">
|
<div class="input-group mt-1">
|
||||||
<input class="form-control note-autocomplete" placeholder="${t('empty.search_placeholder')}">
|
<input class="form-control note-autocomplete" placeholder="${t('empty.search_placeholder')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="note-detail-empty-results"></div>
|
||||||
<div class="workspace-notes"></div>
|
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
export default class EmptyTypeWidget extends TypeWidget {
|
export default class EmptyTypeWidget extends TypeWidget {
|
||||||
@ -51,10 +65,12 @@ export default class EmptyTypeWidget extends TypeWidget {
|
|||||||
|
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.$autoComplete = this.$widget.find(".note-autocomplete");
|
this.$autoComplete = this.$widget.find(".note-autocomplete");
|
||||||
|
this.$results = this.$widget.find(".note-detail-empty-results");
|
||||||
|
|
||||||
noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, {
|
noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, {
|
||||||
hideGoToSelectedNoteButton: true,
|
hideGoToSelectedNoteButton: true,
|
||||||
allowCreatingNotes: true
|
allowCreatingNotes: true,
|
||||||
|
container: this.$results
|
||||||
})
|
})
|
||||||
.on('autocomplete:noteselected', function(event, suggestion, dataset) {
|
.on('autocomplete:noteselected', function(event, suggestion, dataset) {
|
||||||
if (!suggestion.notePath) {
|
if (!suggestion.notePath) {
|
||||||
@ -66,6 +82,7 @@ export default class EmptyTypeWidget extends TypeWidget {
|
|||||||
|
|
||||||
this.$workspaceNotes = this.$widget.find('.workspace-notes');
|
this.$workspaceNotes = this.$widget.find('.workspace-notes');
|
||||||
|
|
||||||
|
noteAutocompleteService.showRecentNotes(this.$autoComplete);
|
||||||
super.doRender();
|
super.doRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import TypeWidget from "./type_widget.js";
|
import AbstractCodeTypeWidget from "./abstract_code_type_widget.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="note-detail-readonly-code note-detail-printable">
|
<div class="note-detail-readonly-code note-detail-printable">
|
||||||
@ -16,12 +16,13 @@ const TPL = `
|
|||||||
<pre class="note-detail-readonly-code-content"></pre>
|
<pre class="note-detail-readonly-code-content"></pre>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
export default class ReadOnlyCodeTypeWidget extends TypeWidget {
|
export default class ReadOnlyCodeTypeWidget extends AbstractCodeTypeWidget {
|
||||||
static getType() { return "readOnlyCode"; }
|
static getType() { return "readOnlyCode"; }
|
||||||
|
|
||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.$content = this.$widget.find('.note-detail-readonly-code-content');
|
this.contentSized();
|
||||||
|
this.$editor = this.$widget.find('.note-detail-readonly-code-content');
|
||||||
|
|
||||||
super.doRender();
|
super.doRender();
|
||||||
}
|
}
|
||||||
@ -33,7 +34,14 @@ export default class ReadOnlyCodeTypeWidget extends TypeWidget {
|
|||||||
content = this.format(content);
|
content = this.format(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$content.text(content);
|
this._update(note, content);
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
getExtraOpts() {
|
||||||
|
return {
|
||||||
|
readOnly: true
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async executeWithContentElementEvent({resolve, ntxId}) {
|
async executeWithContentElementEvent({resolve, ntxId}) {
|
||||||
|
@ -70,30 +70,10 @@ textarea,
|
|||||||
background: var(--input-background-color) url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='%23ffffff' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/></svg>") right .75rem center/15px 20px no-repeat;
|
background: var(--input-background-color) url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='%23ffffff' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/></svg>") right .75rem center/15px 20px no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide number input arrows */
|
|
||||||
input[type="number"]::-webkit-inner-spin-button,
|
|
||||||
input[type="number"]::-webkit-outer-spin-button {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Firefox browser */
|
|
||||||
input[type="number"] {
|
|
||||||
-moz-appearance: textfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Show number input arrows when focus or hover */
|
|
||||||
input[type="number"]:focus::-webkit-inner-spin-button,
|
|
||||||
input[type="number"]:focus::-webkit-outer-spin-button,
|
|
||||||
input[type="number"]:hover::-webkit-inner-spin-button,
|
|
||||||
input[type="number"]:hover::-webkit-outer-spin-button {
|
|
||||||
-webkit-appearance: inner-spin-button;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore default apperance */
|
/* Restore default apperance */
|
||||||
input[type="number"]:focus,
|
input[type="number"],
|
||||||
input[type="number"]:hover {
|
input[type="checkbox"] {
|
||||||
appearance: auto;
|
appearance: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#left-pane input,
|
#left-pane input,
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
"message": "发生了严重错误,导致客户端应用程序无法启动:\n\n{{message}}\n\n这很可能是由于脚本以意外的方式失败引起的。请尝试以安全模式启动应用程序并解决问题。"
|
"message": "发生了严重错误,导致客户端应用程序无法启动:\n\n{{message}}\n\n这很可能是由于脚本以意外的方式失败引起的。请尝试以安全模式启动应用程序并解决问题。"
|
||||||
},
|
},
|
||||||
"widget-error": {
|
"widget-error": {
|
||||||
"title": "小部件初始化失败",
|
"title": "小部件初始化失败"
|
||||||
"message": "标题为 \"{{title}}\" 的小部件由于以下原因无法初始化:\n\n{{message}}"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"add_link": {
|
"add_link": {
|
||||||
|
@ -16,7 +16,12 @@
|
|||||||
},
|
},
|
||||||
"widget-error": {
|
"widget-error": {
|
||||||
"title": "Failed to initialize a widget",
|
"title": "Failed to initialize a widget",
|
||||||
"message": "Widget with title \"{{title}}\" could not be initialized due to:\n\n{{message}}"
|
"message-custom": "Custom widget from note with ID \"{{id}}\", titled \"{{title}}\" could not be initialized due to:\n\n{{message}}",
|
||||||
|
"message-unknown": "Unknown widget could not be initialized due to:\n\n{{message}}"
|
||||||
|
},
|
||||||
|
"bundle-error": {
|
||||||
|
"title": "Failed to load a custom script",
|
||||||
|
"message": "Script from note with ID \"{{id}}\", titled \"{{title}}\" could not be executed due to:\n\n{{message}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"add_link": {
|
"add_link": {
|
||||||
@ -165,7 +170,8 @@
|
|||||||
"textImportedAsText": "Import HTML, Markdown and TXT as text notes if it's unclear from metadata",
|
"textImportedAsText": "Import HTML, Markdown and TXT as text notes if it's unclear from metadata",
|
||||||
"codeImportedAsCode": "Import recognized code files (e.g. <code>.json</code>) as code notes if it's unclear from metadata",
|
"codeImportedAsCode": "Import recognized code files (e.g. <code>.json</code>) as code notes if it's unclear from metadata",
|
||||||
"replaceUnderscoresWithSpaces": "Replace underscores with spaces in imported note names",
|
"replaceUnderscoresWithSpaces": "Replace underscores with spaces in imported note names",
|
||||||
"import": "Import"
|
"import": "Import",
|
||||||
|
"failed": "Import failed: {{message}}."
|
||||||
},
|
},
|
||||||
"include_note": {
|
"include_note": {
|
||||||
"dialog_title": "Include note",
|
"dialog_title": "Include note",
|
||||||
@ -631,7 +637,10 @@
|
|||||||
"export_note": "Export note",
|
"export_note": "Export note",
|
||||||
"delete_note": "Delete note",
|
"delete_note": "Delete note",
|
||||||
"print_note": "Print note",
|
"print_note": "Print note",
|
||||||
"save_revision": "Save revision"
|
"save_revision": "Save revision",
|
||||||
|
"convert_into_attachment_failed": "Converting note '{{title}}' failed.",
|
||||||
|
"convert_into_attachment_successful": "Note '{{title}}' has been converted to attachment.",
|
||||||
|
"convert_into_attachment_prompt": "Are you sure you want to convert note '{{title}}' into an attachment of the parent note?"
|
||||||
},
|
},
|
||||||
"onclick_button": {
|
"onclick_button": {
|
||||||
"no_click_handler": "Button widget '{{componentId}}' has no defined click handler"
|
"no_click_handler": "Button widget '{{componentId}}' has no defined click handler"
|
||||||
@ -886,7 +895,8 @@
|
|||||||
"label_rock_or_pop": "only one of the labels must be present",
|
"label_rock_or_pop": "only one of the labels must be present",
|
||||||
"label_year_comparison": "numerical comparison (also >, >=, <).",
|
"label_year_comparison": "numerical comparison (also >, >=, <).",
|
||||||
"label_date_created": "notes created in the last month",
|
"label_date_created": "notes created in the last month",
|
||||||
"error": "Search error: {{error}}"
|
"error": "Search error: {{error}}",
|
||||||
|
"search_prefix": "Search:"
|
||||||
},
|
},
|
||||||
"attachment_detail": {
|
"attachment_detail": {
|
||||||
"open_help_page": "Open help page on attachments",
|
"open_help_page": "Open help page on attachments",
|
||||||
@ -920,7 +930,15 @@
|
|||||||
},
|
},
|
||||||
"protected_session": {
|
"protected_session": {
|
||||||
"enter_password_instruction": "Showing protected note requires entering your password:",
|
"enter_password_instruction": "Showing protected note requires entering your password:",
|
||||||
"start_session_button": "Start protected session"
|
"start_session_button": "Start protected session",
|
||||||
|
"started": "Protected session has been started.",
|
||||||
|
"wrong_password": "Wrong password.",
|
||||||
|
"protecting-finished-successfully": "Protecting finished successfully.",
|
||||||
|
"unprotecting-finished-successfully": "Unprotecting finished successfully.",
|
||||||
|
"protecting-in-progress": "Protecting in progress: {{count}}",
|
||||||
|
"unprotecting-in-progress-count": "Unprotecting in progress: {{count}}",
|
||||||
|
"protecting-title": "Protecting status",
|
||||||
|
"unprotecting-title": "Unprotecting status"
|
||||||
},
|
},
|
||||||
"relation_map": {
|
"relation_map": {
|
||||||
"open_in_new_tab": "Open in new tab",
|
"open_in_new_tab": "Open in new tab",
|
||||||
@ -975,7 +993,7 @@
|
|||||||
"error_creating_anonymized_database": "Could not create anonymized database, check backend logs for details",
|
"error_creating_anonymized_database": "Could not create anonymized database, check backend logs for details",
|
||||||
"successfully_created_fully_anonymized_database": "Created fully anonymized database in {{anonymizedFilePath}}",
|
"successfully_created_fully_anonymized_database": "Created fully anonymized database in {{anonymizedFilePath}}",
|
||||||
"successfully_created_lightly_anonymized_database": "Created lightly anonymized database in {{anonymizedFilePath}}",
|
"successfully_created_lightly_anonymized_database": "Created lightly anonymized database in {{anonymizedFilePath}}",
|
||||||
"no_anonymized_database_yet": "no anonymized database yet"
|
"no_anonymized_database_yet": "No anonymized database yet."
|
||||||
},
|
},
|
||||||
"database_integrity_check": {
|
"database_integrity_check": {
|
||||||
"title": "Database Integrity Check",
|
"title": "Database Integrity Check",
|
||||||
@ -991,7 +1009,9 @@
|
|||||||
"fill_entity_changes_button": "Fill entity changes records",
|
"fill_entity_changes_button": "Fill entity changes records",
|
||||||
"full_sync_triggered": "Full sync triggered",
|
"full_sync_triggered": "Full sync triggered",
|
||||||
"filling_entity_changes": "Filling entity changes rows...",
|
"filling_entity_changes": "Filling entity changes rows...",
|
||||||
"sync_rows_filled_successfully": "Sync rows filled successfully"
|
"sync_rows_filled_successfully": "Sync rows filled successfully",
|
||||||
|
"finished-successfully": "Sync finished successfully.",
|
||||||
|
"failed": "Sync failed: {{message}}"
|
||||||
},
|
},
|
||||||
"vacuum_database": {
|
"vacuum_database": {
|
||||||
"title": "Vacuum Database",
|
"title": "Vacuum Database",
|
||||||
@ -1198,7 +1218,7 @@
|
|||||||
"password": {
|
"password": {
|
||||||
"heading": "Password",
|
"heading": "Password",
|
||||||
"alert_message": "Please take care to remember your new password. Password is used for logging into the web interface and to encrypt protected notes. If you forget your password, then all your protected notes are forever lost.",
|
"alert_message": "Please take care to remember your new password. Password is used for logging into the web interface and to encrypt protected notes. If you forget your password, then all your protected notes are forever lost.",
|
||||||
"reset_link": "click here to reset it.",
|
"reset_link": "Click here to reset it.",
|
||||||
"old_password": "Old password",
|
"old_password": "Old password",
|
||||||
"new_password": "New password",
|
"new_password": "New password",
|
||||||
"new_password_confirmation": "New password confirmation",
|
"new_password_confirmation": "New password confirmation",
|
||||||
@ -1310,7 +1330,9 @@
|
|||||||
"duplicate-subtree": "Duplicate subtree",
|
"duplicate-subtree": "Duplicate subtree",
|
||||||
"export": "Export",
|
"export": "Export",
|
||||||
"import-into-note": "Import into note",
|
"import-into-note": "Import into note",
|
||||||
"apply-bulk-actions": "Apply bulk actions"
|
"apply-bulk-actions": "Apply bulk actions",
|
||||||
|
"converted-to-attachments": "{{count}} notes have been converted to attachments.",
|
||||||
|
"convert-to-attachment-confirm": "Are you sure you want to convert note selected notes into attachments of their parent notes?"
|
||||||
},
|
},
|
||||||
"shared_info": {
|
"shared_info": {
|
||||||
"shared_publicly": "This note is shared publicly on",
|
"shared_publicly": "This note is shared publicly on",
|
||||||
@ -1333,7 +1355,8 @@
|
|||||||
"image": "Image",
|
"image": "Image",
|
||||||
"launcher": "Launcher",
|
"launcher": "Launcher",
|
||||||
"doc": "Doc",
|
"doc": "Doc",
|
||||||
"widget": "Widget"
|
"widget": "Widget",
|
||||||
|
"confirm-change": "It is not recommended to change note type when note content is not empty. Do you want to continue anyway?"
|
||||||
},
|
},
|
||||||
"protect_note": {
|
"protect_note": {
|
||||||
"toggle-on": "Protect the note",
|
"toggle-on": "Protect the note",
|
||||||
@ -1379,7 +1402,9 @@
|
|||||||
"hide-archived-notes": "Hide archived notes",
|
"hide-archived-notes": "Hide archived notes",
|
||||||
"automatically-collapse-notes": "Automatically collapse notes",
|
"automatically-collapse-notes": "Automatically collapse notes",
|
||||||
"automatically-collapse-notes-title": "Notes will be collapsed after period of inactivity to declutter the tree.",
|
"automatically-collapse-notes-title": "Notes will be collapsed after period of inactivity to declutter the tree.",
|
||||||
"save-changes": "Save & apply changes"
|
"save-changes": "Save & apply changes",
|
||||||
|
"auto-collapsing-notes-after-inactivity": "Auto collapsing notes after inactivity...",
|
||||||
|
"saved-search-note-refreshed": "Saved search note refreshed."
|
||||||
},
|
},
|
||||||
"title_bar_buttons": {
|
"title_bar_buttons": {
|
||||||
"window-on-top": "Keep this window on top."
|
"window-on-top": "Keep this window on top."
|
||||||
@ -1408,6 +1433,7 @@
|
|||||||
"add_new_tab": "Add new tab",
|
"add_new_tab": "Add new tab",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"close_other_tabs": "Close other tabs",
|
"close_other_tabs": "Close other tabs",
|
||||||
|
"close_right_tabs": "Close tabs to the right",
|
||||||
"close_all_tabs": "Close all tabs",
|
"close_all_tabs": "Close all tabs",
|
||||||
"move_tab_to_new_window": "Move this tab to a new window",
|
"move_tab_to_new_window": "Move this tab to a new window",
|
||||||
"new_tab": "New tab"
|
"new_tab": "New tab"
|
||||||
@ -1423,5 +1449,53 @@
|
|||||||
},
|
},
|
||||||
"app_context": {
|
"app_context": {
|
||||||
"please_wait_for_save": "Please wait for a couple of seconds for the save to finish, then you can try again."
|
"please_wait_for_save": "Please wait for a couple of seconds for the save to finish, then you can try again."
|
||||||
|
},
|
||||||
|
"note_create": {
|
||||||
|
"duplicated": "Note \"{{title}}\" has been duplicated."
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"copied-to-clipboard": "A reference to the image has been copied to clipboard. This can be pasted in any text note.",
|
||||||
|
"cannot-copy": "Could not copy the image reference to clipboard."
|
||||||
|
},
|
||||||
|
"clipboard": {
|
||||||
|
"cut": "Note(s) have been cut into clipboard.",
|
||||||
|
"copied": "Note(s) have been copied into clipboard."
|
||||||
|
},
|
||||||
|
"entrypoints": {
|
||||||
|
"note-revision-created": "Note revision has been created.",
|
||||||
|
"note-executed": "Note executed.",
|
||||||
|
"sql-error": "Error occurred while executing SQL query: {{message}}"
|
||||||
|
},
|
||||||
|
"branches": {
|
||||||
|
"cannot-move-notes-here": "Cannot move notes here.",
|
||||||
|
"delete-status": "Delete status",
|
||||||
|
"delete-notes-in-progress": "Delete notes in progress: {{count}}",
|
||||||
|
"delete-finished-successfully": "Delete finished successfully.",
|
||||||
|
"undeleting-notes-in-progress": "Undeleting notes in progress: {{count}}",
|
||||||
|
"undeleting-notes-finished-successfully": "Undeleting notes finished successfully."
|
||||||
|
},
|
||||||
|
"frontend_script_api": {
|
||||||
|
"async_warning": "You're passing an async function to `api.runOnBackend()` which will likely not work as you intended.\\nEither make the function synchronous (by removing `async` keyword), or use `api.runAsyncOnBackendWithManualTransactionHandling()`.",
|
||||||
|
"sync_warning": "You're passing a synchronous function to `api.runAsyncOnBackendWithManualTransactionHandling()`,\\nwhile you should likely use `api.runOnBackend()` instead."
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"sync-check-failed": "Sync check failed!",
|
||||||
|
"consistency-checks-failed": "Consistency checks failed! See logs for details.",
|
||||||
|
"encountered-error": "Encountered error \"{{message}}\", check out the console."
|
||||||
|
},
|
||||||
|
"hoisted_note": {
|
||||||
|
"confirm_unhoisting": "Requested note '{{requestedNote}}' is outside of hoisted note '{{hoistedNote}}' subtree and you must unhoist to access the note. Do you want to proceed with unhoisting?"
|
||||||
|
},
|
||||||
|
"launcher_context_menu": {
|
||||||
|
"reset_launcher_confirm": "Do you really want to reset \"{{title}}\"? All data / settings in this note (and its children) will be lost and the launcher will be returned to its original location.",
|
||||||
|
"add-note-launcher": "Add a note launcher",
|
||||||
|
"add-script-launcher": "Add a script launcher",
|
||||||
|
"add-custom-widget": "Add a custom widget",
|
||||||
|
"add-spacer": "Add spacer",
|
||||||
|
"delete": "Delete",
|
||||||
|
"reset": "Reset",
|
||||||
|
"move-to-visible-launchers": "Move to visible launchers",
|
||||||
|
"move-to-available-launchers": "Move to available launchers",
|
||||||
|
"duplicate-launcher": "Duplicate launcher"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,12 @@
|
|||||||
},
|
},
|
||||||
"widget-error": {
|
"widget-error": {
|
||||||
"title": "No se pudo inicializar un widget",
|
"title": "No se pudo inicializar un widget",
|
||||||
"message": "Widget con título \"{{title}}\" no pudo ser inicializado debido a:\n\n{{message}}"
|
"message-custom": "El widget personalizado de la nota con ID \"{{id}}\", titulada \"{{title}}\" no pudo ser inicializado debido a:\n\n{{message}}",
|
||||||
|
"message-unknown": "Un widget no pudo ser inicializado debido a:\n\n{{message}}"
|
||||||
|
},
|
||||||
|
"bundle-error": {
|
||||||
|
"title": "Hubo un fallo al cargar un script personalizado",
|
||||||
|
"message": "El script de la nota con ID \"{{id}}\", titulado \"{{title}}\" no pudo ser ejecutado debido a:\n\n{{message}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"add_link": {
|
"add_link": {
|
||||||
@ -165,7 +170,8 @@
|
|||||||
"textImportedAsText": "Importar HTML, Markdown y TXT como notas de texto si no está claro en los metadatos",
|
"textImportedAsText": "Importar HTML, Markdown y TXT como notas de texto si no está claro en los metadatos",
|
||||||
"codeImportedAsCode": "Importar archivos de código reconocidos (por ejemplo, <code>.json</code>) como notas de código si no están claros en los metadatos",
|
"codeImportedAsCode": "Importar archivos de código reconocidos (por ejemplo, <code>.json</code>) como notas de código si no están claros en los metadatos",
|
||||||
"replaceUnderscoresWithSpaces": "Reemplazar guiones bajos con espacios en nombres de notas importadas",
|
"replaceUnderscoresWithSpaces": "Reemplazar guiones bajos con espacios en nombres de notas importadas",
|
||||||
"import": "Importar"
|
"import": "Importar",
|
||||||
|
"failed": "La importación falló: {{message}}."
|
||||||
},
|
},
|
||||||
"include_note": {
|
"include_note": {
|
||||||
"dialog_title": "Incluir nota",
|
"dialog_title": "Incluir nota",
|
||||||
@ -329,9 +335,9 @@
|
|||||||
"run_on_instance": "Definir en qué instancia de Trilium se debe ejecutar esto. Predeterminado para todas las instancias.",
|
"run_on_instance": "Definir en qué instancia de Trilium se debe ejecutar esto. Predeterminado para todas las instancias.",
|
||||||
"run_at_hour": "¿A qué hora debería funcionar? Debe usarse junto con <code>#run=hourly</code>. Se puede definir varias veces para varias ejecuciones durante el día.",
|
"run_at_hour": "¿A qué hora debería funcionar? Debe usarse junto con <code>#run=hourly</code>. Se puede definir varias veces para varias ejecuciones durante el día.",
|
||||||
"disable_inclusion": "los scripts con esta etiqueta no se incluirán en la ejecución del script principal.",
|
"disable_inclusion": "los scripts con esta etiqueta no se incluirán en la ejecución del script principal.",
|
||||||
"sorted": "mantiene las notas hijo ordenadas alfabéticamente por título",
|
"sorted": "mantiene las subnotas ordenadas alfabéticamente por título",
|
||||||
"sort_direction": "ASC (el valor predeterminado) o DESC",
|
"sort_direction": "ASC (el valor predeterminado) o DESC",
|
||||||
"sort_folders_first": "Las carpetas (notas con hijos) deben ordenarse en la parte superior",
|
"sort_folders_first": "Las carpetas (notas con subnotas) deben ordenarse en la parte superior",
|
||||||
"top": "mantener la nota dada en la parte superior de su padre (se aplica solo en padres ordenados)",
|
"top": "mantener la nota dada en la parte superior de su padre (se aplica solo en padres ordenados)",
|
||||||
"hide_promoted_attributes": "Ocultar atributos promovidos en esta nota",
|
"hide_promoted_attributes": "Ocultar atributos promovidos en esta nota",
|
||||||
"read_only": "el editor está en modo de sólo lectura. Funciona sólo para notas de texto y código.",
|
"read_only": "el editor está en modo de sólo lectura. Funciona sólo para notas de texto y código.",
|
||||||
@ -349,9 +355,9 @@
|
|||||||
"workspace_tab_background_color": "color CSS utilizado en la pestaña de nota cuando se ancla a esta nota",
|
"workspace_tab_background_color": "color CSS utilizado en la pestaña de nota cuando se ancla a esta nota",
|
||||||
"workspace_calendar_root": "Define la raíz del calendario por cada espacio de trabajo",
|
"workspace_calendar_root": "Define la raíz del calendario por cada espacio de trabajo",
|
||||||
"workspace_template": "Esta nota aparecerá en la selección de plantillas disponibles al crear una nueva nota, pero solo cuando se levante a un espacio de trabajo que contenga esta plantilla",
|
"workspace_template": "Esta nota aparecerá en la selección de plantillas disponibles al crear una nueva nota, pero solo cuando se levante a un espacio de trabajo que contenga esta plantilla",
|
||||||
"search_home": "se crearán nuevas notas de búsqueda como hijas de esta nota",
|
"search_home": "se crearán nuevas notas de búsqueda como subnotas de esta nota",
|
||||||
"workspace_search_home": "se crearán nuevas notas de búsqueda como hijo de esta nota cuando se anclan a algún antecesor de esta nota del espacio de trabajo",
|
"workspace_search_home": "se crearán nuevas notas de búsqueda como subnotas de esta nota cuando se anclan a algún antecesor de esta nota del espacio de trabajo",
|
||||||
"inbox": "ubicación predeterminada de la bandeja de entrada para nuevas notas - cuando crea una nota usando el botón \"nueva nota\" en la barra lateral, las notas serán creadas como notas hijo de la nota marcada con la etiqueta <code>#inbox</code>.",
|
"inbox": "ubicación predeterminada de la bandeja de entrada para nuevas notas - cuando crea una nota usando el botón \"nueva nota\" en la barra lateral, las notas serán creadas como subnotas de la nota marcada con la etiqueta <code>#inbox</code>.",
|
||||||
"workspace_inbox": "ubicación predeterminada de la bandeja de entrada para nuevas notas cuando se anclan a algún antecesor de esta nota del espacio de trabajo",
|
"workspace_inbox": "ubicación predeterminada de la bandeja de entrada para nuevas notas cuando se anclan a algún antecesor de esta nota del espacio de trabajo",
|
||||||
"sql_console_home": "ubicación predeterminada de las notas de la consola SQL",
|
"sql_console_home": "ubicación predeterminada de las notas de la consola SQL",
|
||||||
"bookmark_folder": "la nota con esta etiqueta aparecerá en los marcadores como carpeta (permitiendo el acceso a sus elementos hijos).",
|
"bookmark_folder": "la nota con esta etiqueta aparecerá en los marcadores como carpeta (permitiendo el acceso a sus elementos hijos).",
|
||||||
@ -367,7 +373,7 @@
|
|||||||
"share_index": "tenga en cuenta que con esto esta etiqueta enumerará todas las raíces de las notas compartidas",
|
"share_index": "tenga en cuenta que con esto esta etiqueta enumerará todas las raíces de las notas compartidas",
|
||||||
"display_relations": "nombres de relaciones delimitados por comas que deben mostrarse. Todos los demás estarán ocultos.",
|
"display_relations": "nombres de relaciones delimitados por comas que deben mostrarse. Todos los demás estarán ocultos.",
|
||||||
"hide_relations": "nombres de relaciones delimitados por comas que deben ocultarse. Se mostrarán todos los demás.",
|
"hide_relations": "nombres de relaciones delimitados por comas que deben ocultarse. Se mostrarán todos los demás.",
|
||||||
"title_template": "título por defecto de notas creadas como hijo de esta nota. El valor es evaluado como una cadena de JavaScript \n y por lo tanto puede ser enriquecida con contenido dinámico vía las variables inyectadas <code>now</code> y <code>parentNote</code>. Ejemplos:\n \n <ul>\n <li><code>trabajos literarios de ${parentNote.getLabelValue('authorName')}</code></li>\n <li><code>Registro para ${now.format('YYYY-MM-DD HH:mm:ss')}</code></li>\n </ul>\n \n Consulte la <a href=\"https://triliumnext.github.io/Docs/Wiki/default-note-title.html\">wiki para obtener más detalles</a>, documentación de la API para <a href=\"https://zadam.github.io/trilium/backend_api/Note.html\">parentNote</a> y <a href=\"https://day.js.org/docs/en/display/format\">now</a> para más detalles.",
|
"title_template": "título por defecto de notas creadas como subnota de esta nota. El valor es evaluado como una cadena de JavaScript \n y por lo tanto puede ser enriquecida con contenido dinámico vía las variables inyectadas <code>now</code> y <code>parentNote</code>. Ejemplos:\n \n <ul>\n <li><code>trabajos literarios de ${parentNote.getLabelValue('authorName')}</code></li>\n <li><code>Registro para ${now.format('YYYY-MM-DD HH:mm:ss')}</code></li>\n </ul>\n \n Consulte la <a href=\"https://triliumnext.github.io/Docs/Wiki/default-note-title.html\">wiki para obtener más detalles</a>, documentación de la API para <a href=\"https://zadam.github.io/trilium/backend_api/Note.html\">parentNote</a> y <a href=\"https://day.js.org/docs/en/display/format\">now</a> para más detalles.",
|
||||||
"template": "Esta nota aparecerá en la selección de plantillas disponibles al crear una nueva nota",
|
"template": "Esta nota aparecerá en la selección de plantillas disponibles al crear una nueva nota",
|
||||||
"toc": "<code>#toc</code> o <code>#toc=show</code> forzará que se muestre la tabla de contenido, <code>#toc=hide</code> forzará a ocultarla. Si la etiqueta no existe, se observa la configuración global",
|
"toc": "<code>#toc</code> o <code>#toc=show</code> forzará que se muestre la tabla de contenido, <code>#toc=hide</code> forzará a ocultarla. Si la etiqueta no existe, se observa la configuración global",
|
||||||
"color": "define el color de la nota en el árbol de notas, enlaces, etc. Utilice cualquier valor de color CSS válido como 'red' o #a13d5f",
|
"color": "define el color de la nota en el árbol de notas, enlaces, etc. Utilice cualquier valor de color CSS válido como 'red' o #a13d5f",
|
||||||
@ -631,7 +637,10 @@
|
|||||||
"export_note": "Exportar nota",
|
"export_note": "Exportar nota",
|
||||||
"delete_note": "Eliminar nota",
|
"delete_note": "Eliminar nota",
|
||||||
"print_note": "Imprimir nota",
|
"print_note": "Imprimir nota",
|
||||||
"save_revision": "Guardar revisión"
|
"save_revision": "Guardar revisión",
|
||||||
|
"convert_into_attachment_failed": "La conversión de nota '{{title}}' falló.",
|
||||||
|
"convert_into_attachment_successful": "La nota '{{title}}' ha sido convertida a un archivo adjunto.",
|
||||||
|
"convert_into_attachment_prompt": "¿Está seguro que desea convertir la nota '{{title}}' en un archivo adjunto de la nota padre?"
|
||||||
},
|
},
|
||||||
"onclick_button": {
|
"onclick_button": {
|
||||||
"no_click_handler": "El widget de botón '{{componentId}}' no tiene un controlador de clics definido"
|
"no_click_handler": "El widget de botón '{{componentId}}' no tiene un controlador de clics definido"
|
||||||
@ -669,7 +678,7 @@
|
|||||||
"button_title": "Exportar diagrama como SVG"
|
"button_title": "Exportar diagrama como SVG"
|
||||||
},
|
},
|
||||||
"relation_map_buttons": {
|
"relation_map_buttons": {
|
||||||
"create_child_note_title": "Crear una nueva nota hijo y agregarla a este mapa de relaciones",
|
"create_child_note_title": "Crear una nueva subnota y agregarla a este mapa de relaciones",
|
||||||
"reset_pan_zoom_title": "Restablecer la panorámica y el zoom a las coordenadas y ampliación iniciales",
|
"reset_pan_zoom_title": "Restablecer la panorámica y el zoom a las coordenadas y ampliación iniciales",
|
||||||
"zoom_in_title": "Acercar",
|
"zoom_in_title": "Acercar",
|
||||||
"zoom_out_title": "Alejar"
|
"zoom_out_title": "Alejar"
|
||||||
@ -680,7 +689,7 @@
|
|||||||
"relation": "relación"
|
"relation": "relación"
|
||||||
},
|
},
|
||||||
"mobile_detail_menu": {
|
"mobile_detail_menu": {
|
||||||
"insert_child_note": "Insertar nota hijo",
|
"insert_child_note": "Insertar subnota",
|
||||||
"delete_this_note": "Eliminar esta nota",
|
"delete_this_note": "Eliminar esta nota",
|
||||||
"error_cannot_get_branch_id": "No se puede obtener el branchID del notePath '{{notePath}}'",
|
"error_cannot_get_branch_id": "No se puede obtener el branchID del notePath '{{notePath}}'",
|
||||||
"error_unrecognized_command": "Comando no reconocido {{command}}"
|
"error_unrecognized_command": "Comando no reconocido {{command}}"
|
||||||
@ -701,7 +710,7 @@
|
|||||||
"grid": "Cuadrícula",
|
"grid": "Cuadrícula",
|
||||||
"list": "Lista",
|
"list": "Lista",
|
||||||
"collapse_all_notes": "Contraer todas las notas",
|
"collapse_all_notes": "Contraer todas las notas",
|
||||||
"expand_all_children": "Ampliar todos los hijos",
|
"expand_all_children": "Ampliar todas las subnotas",
|
||||||
"collapse": "Colapsar",
|
"collapse": "Colapsar",
|
||||||
"expand": "Expandir",
|
"expand": "Expandir",
|
||||||
"book_properties": "Propiedades del libro",
|
"book_properties": "Propiedades del libro",
|
||||||
@ -855,7 +864,7 @@
|
|||||||
"content_and_attachments_size": "Tenga en cuenta el tamaño del contenido, incluidos los archivos adjuntos",
|
"content_and_attachments_size": "Tenga en cuenta el tamaño del contenido, incluidos los archivos adjuntos",
|
||||||
"content_and_attachments_and_revisions_size": "Tenga en cuenta el tamaño del contenido, incluidos los archivos adjuntos y las revisiones",
|
"content_and_attachments_and_revisions_size": "Tenga en cuenta el tamaño del contenido, incluidos los archivos adjuntos y las revisiones",
|
||||||
"revision_count": "Número de revisiones",
|
"revision_count": "Número de revisiones",
|
||||||
"children_count": "Notas sobre el número de hijos",
|
"children_count": "Número de subnotas",
|
||||||
"parent_count": "Número de clones",
|
"parent_count": "Número de clones",
|
||||||
"owned_label_count": "Número de etiquetas",
|
"owned_label_count": "Número de etiquetas",
|
||||||
"owned_relation_count": "Número de relaciones",
|
"owned_relation_count": "Número de relaciones",
|
||||||
@ -891,7 +900,7 @@
|
|||||||
"attachment_detail": {
|
"attachment_detail": {
|
||||||
"open_help_page": "Abrir página de ayuda en archivos adjuntos",
|
"open_help_page": "Abrir página de ayuda en archivos adjuntos",
|
||||||
"owning_note": "Nota dueña: ",
|
"owning_note": "Nota dueña: ",
|
||||||
"you_can_also_open": ", también puedes abri el ",
|
"you_can_also_open": ", también puede abrir el ",
|
||||||
"list_of_all_attachments": "Lista de todos los archivos adjuntos",
|
"list_of_all_attachments": "Lista de todos los archivos adjuntos",
|
||||||
"attachment_deleted": "Este archivo adjunto ha sido eliminado."
|
"attachment_deleted": "Este archivo adjunto ha sido eliminado."
|
||||||
},
|
},
|
||||||
@ -902,7 +911,7 @@
|
|||||||
"no_attachments": "Esta nota no tiene archivos adjuntos."
|
"no_attachments": "Esta nota no tiene archivos adjuntos."
|
||||||
},
|
},
|
||||||
"book": {
|
"book": {
|
||||||
"no_children_help": "Esta nota de tipo libro no tieneninguna nota hijo así que no hay nada que mostrar. Véa la <a href=\"https://triliumnext.github.io/Docs/Wiki/book-note.html\">wiki</a> para más detalles."
|
"no_children_help": "Esta nota de tipo libro no tieneninguna subnota así que no hay nada que mostrar. Véa la <a href=\"https://triliumnext.github.io/Docs/Wiki/book-note.html\">wiki</a> para más detalles."
|
||||||
},
|
},
|
||||||
"editable_code": {
|
"editable_code": {
|
||||||
"placeholder": "Escriba el contenido de su nota de código aquí..."
|
"placeholder": "Escriba el contenido de su nota de código aquí..."
|
||||||
@ -920,7 +929,15 @@
|
|||||||
},
|
},
|
||||||
"protected_session": {
|
"protected_session": {
|
||||||
"enter_password_instruction": "Para mostrar una nota protegida es necesario ingresar su contraseña:",
|
"enter_password_instruction": "Para mostrar una nota protegida es necesario ingresar su contraseña:",
|
||||||
"start_session_button": "Iniciar sesión protegida"
|
"start_session_button": "Iniciar sesión protegida",
|
||||||
|
"started": "La sesión protegida ha iniciado.",
|
||||||
|
"wrong_password": "Contraseña incorrecta.",
|
||||||
|
"protecting-finished-successfully": "La protección finalizó exitosamente.",
|
||||||
|
"unprotecting-finished-successfully": "La desprotección finalizó exitosamente.",
|
||||||
|
"protecting-in-progress": "Protección en progreso: {{count}}",
|
||||||
|
"unprotecting-in-progress-count": "Desprotección en progreso: {{count}}",
|
||||||
|
"protecting-title": "Estado de protección",
|
||||||
|
"unprotecting-title": "Estado de desprotección"
|
||||||
},
|
},
|
||||||
"relation_map": {
|
"relation_map": {
|
||||||
"open_in_new_tab": "Abrir en nueva pestaña",
|
"open_in_new_tab": "Abrir en nueva pestaña",
|
||||||
@ -975,7 +992,7 @@
|
|||||||
"error_creating_anonymized_database": "No se pudo crear una base de datos anónima; consulte los registros de backend para obtener más detalles",
|
"error_creating_anonymized_database": "No se pudo crear una base de datos anónima; consulte los registros de backend para obtener más detalles",
|
||||||
"successfully_created_fully_anonymized_database": "Se creó una base de datos completamente anónima en {{anonymizedFilePath}}",
|
"successfully_created_fully_anonymized_database": "Se creó una base de datos completamente anónima en {{anonymizedFilePath}}",
|
||||||
"successfully_created_lightly_anonymized_database": "Se creó una base de datos ligeramente anónima en {{anonymizedFilePath}}",
|
"successfully_created_lightly_anonymized_database": "Se creó una base de datos ligeramente anónima en {{anonymizedFilePath}}",
|
||||||
"no_anonymized_database_yet": "aún no hay base de datos anónima"
|
"no_anonymized_database_yet": "Aún no hay base de datos anónima."
|
||||||
},
|
},
|
||||||
"database_integrity_check": {
|
"database_integrity_check": {
|
||||||
"title": "Verificación de integridad de la base de datos",
|
"title": "Verificación de integridad de la base de datos",
|
||||||
@ -991,7 +1008,9 @@
|
|||||||
"fill_entity_changes_button": "Llenar registros de cambios de entidad",
|
"fill_entity_changes_button": "Llenar registros de cambios de entidad",
|
||||||
"full_sync_triggered": "Sincronización completa activada",
|
"full_sync_triggered": "Sincronización completa activada",
|
||||||
"filling_entity_changes": "Rellenar filas de cambios de entidad...",
|
"filling_entity_changes": "Rellenar filas de cambios de entidad...",
|
||||||
"sync_rows_filled_successfully": "Sincronizar filas completadas correctamente"
|
"sync_rows_filled_successfully": "Sincronizar filas completadas correctamente",
|
||||||
|
"finished-successfully": "La sincronización finalizó exitosamente.",
|
||||||
|
"failed": "La sincronización falló: {{message}}"
|
||||||
},
|
},
|
||||||
"vacuum_database": {
|
"vacuum_database": {
|
||||||
"title": "Limpiar base de datos",
|
"title": "Limpiar base de datos",
|
||||||
@ -1137,7 +1156,7 @@
|
|||||||
},
|
},
|
||||||
"table_of_contents": {
|
"table_of_contents": {
|
||||||
"title": "Tabla de contenido",
|
"title": "Tabla de contenido",
|
||||||
"description": "La tabla de contenido aparecerá en las notas de texto cuando la nota tenga más de un número definido de títulos. Puedes personalizar este número:",
|
"description": "La tabla de contenido aparecerá en las notas de texto cuando la nota tenga más de un número definido de títulos. Puede personalizar este número:",
|
||||||
"disable_info": "También puede utilizar esta opción para desactivar la TDC (TOC) de forma efectiva estableciendo un número muy alto.",
|
"disable_info": "También puede utilizar esta opción para desactivar la TDC (TOC) de forma efectiva estableciendo un número muy alto.",
|
||||||
"shortcut_info": "Puede configurar un atajo de teclado para alternar rápidamente el panel derecho (incluido el TDC) en Opciones -> Atajos (nombre 'toggleRightPane')."
|
"shortcut_info": "Puede configurar un atajo de teclado para alternar rápidamente el panel derecho (incluido el TDC) en Opciones -> Atajos (nombre 'toggleRightPane')."
|
||||||
},
|
},
|
||||||
@ -1286,7 +1305,7 @@
|
|||||||
"open-in-a-new-tab": "Abrir en nueva pestaña",
|
"open-in-a-new-tab": "Abrir en nueva pestaña",
|
||||||
"open-in-a-new-split": "Abrir en nueva división",
|
"open-in-a-new-split": "Abrir en nueva división",
|
||||||
"insert-note-after": "Insertar nota después de",
|
"insert-note-after": "Insertar nota después de",
|
||||||
"insert-child-note": "Insertar nota hijo",
|
"insert-child-note": "Insertar subnota",
|
||||||
"delete": "Eliminar",
|
"delete": "Eliminar",
|
||||||
"search-in-subtree": "Buscar en subárbol",
|
"search-in-subtree": "Buscar en subárbol",
|
||||||
"hoist-note": "Anclar nota",
|
"hoist-note": "Anclar nota",
|
||||||
@ -1310,7 +1329,9 @@
|
|||||||
"duplicate-subtree": "Duplicar subárbol",
|
"duplicate-subtree": "Duplicar subárbol",
|
||||||
"export": "Exportar",
|
"export": "Exportar",
|
||||||
"import-into-note": "Importar a nota",
|
"import-into-note": "Importar a nota",
|
||||||
"apply-bulk-actions": "Aplicar acciones en lote"
|
"apply-bulk-actions": "Aplicar acciones en lote",
|
||||||
|
"converted-to-attachments": "{{count}} notas han sido convertidas en archivos adjuntos.",
|
||||||
|
"convert-to-attachment-confirm": "¿Está seguro que desea convertir las notas seleccionadas en archivos adjuntos de sus notas padres?"
|
||||||
},
|
},
|
||||||
"shared_info": {
|
"shared_info": {
|
||||||
"shared_publicly": "Esta nota está compartida públicamente en",
|
"shared_publicly": "Esta nota está compartida públicamente en",
|
||||||
@ -1333,7 +1354,8 @@
|
|||||||
"image": "Imagen",
|
"image": "Imagen",
|
||||||
"launcher": "Lanzador",
|
"launcher": "Lanzador",
|
||||||
"doc": "Doc",
|
"doc": "Doc",
|
||||||
"widget": "Widget"
|
"widget": "Widget",
|
||||||
|
"confirm-change": "No es recomendado cambiar el tipo de nota cuando el contenido de la nota no está vacío. ¿Desea continuar de cualquier manera?"
|
||||||
},
|
},
|
||||||
"protect_note": {
|
"protect_note": {
|
||||||
"toggle-on": "Proteger la nota",
|
"toggle-on": "Proteger la nota",
|
||||||
@ -1379,7 +1401,9 @@
|
|||||||
"hide-archived-notes": "Ocultar notas archivadas",
|
"hide-archived-notes": "Ocultar notas archivadas",
|
||||||
"automatically-collapse-notes": "Colapsar notas automaticamente",
|
"automatically-collapse-notes": "Colapsar notas automaticamente",
|
||||||
"automatically-collapse-notes-title": "Las notas serán colapsadas después de un periodo de inactividad para despejar el árbol.",
|
"automatically-collapse-notes-title": "Las notas serán colapsadas después de un periodo de inactividad para despejar el árbol.",
|
||||||
"save-changes": "Guardar y aplicar cambios"
|
"save-changes": "Guardar y aplicar cambios",
|
||||||
|
"auto-collapsing-notes-after-inactivity": "Colapsando notas automáticamente después de inactividad...",
|
||||||
|
"saved-search-note-refreshed": "La nota de búsqueda guardada fue recargada."
|
||||||
},
|
},
|
||||||
"title_bar_buttons": {
|
"title_bar_buttons": {
|
||||||
"window-on-top": "Mantener esta ventana en la parte superior."
|
"window-on-top": "Mantener esta ventana en la parte superior."
|
||||||
@ -1423,5 +1447,53 @@
|
|||||||
},
|
},
|
||||||
"app_context": {
|
"app_context": {
|
||||||
"please_wait_for_save": "Por favor espere algunos segundos a que se termine de guardar, después intente de nuevo."
|
"please_wait_for_save": "Por favor espere algunos segundos a que se termine de guardar, después intente de nuevo."
|
||||||
|
},
|
||||||
|
"note_create": {
|
||||||
|
"duplicated": "La nota \"{{title}}\" ha sido duplicada."
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"copied-to-clipboard": "Una referencia a la imagen ha sido copiada al portapapeles. Esta puede ser pegada en cualquier nota de texto.",
|
||||||
|
"cannot-copy": "No se pudo copiar la referencia de imagen al portapapeles."
|
||||||
|
},
|
||||||
|
"clipboard": {
|
||||||
|
"cut": "La(s) notas(s) han sido cortadas al portapapeles.",
|
||||||
|
"copied": "La(s) notas(s) han sido copiadas al portapapeles."
|
||||||
|
},
|
||||||
|
"entrypoints": {
|
||||||
|
"note-revision-created": "Una revisión de nota ha sido creada.",
|
||||||
|
"note-executed": "Nota ejecutada.",
|
||||||
|
"sql-error": "Ocurrió un error al ejecutar la consulta SQL: {{message}}"
|
||||||
|
},
|
||||||
|
"branches": {
|
||||||
|
"cannot-move-notes-here": "No se pueden mover notas aquí.",
|
||||||
|
"delete-status": "Estado de eliminación",
|
||||||
|
"delete-notes-in-progress": "Eliminación de notas en progreso: {{count}}",
|
||||||
|
"delete-finished-successfully": "La eliminación finalizó exitosamente.",
|
||||||
|
"undeleting-notes-in-progress": "Recuperación de notas en progreso: {{count}}",
|
||||||
|
"undeleting-notes-finished-successfully": "La recuperación de notas finalizó exitosamente."
|
||||||
|
},
|
||||||
|
"frontend_script_api": {
|
||||||
|
"async_warning": "Está pasando una función asíncrona a `api.runOnBackend ()` que probablemente no funcionará como pretendía.",
|
||||||
|
"sync_warning": "Estás pasando una función sincrónica a `api.runasynconbackendwithmanualTransactionHandling ()`, \\ n while debería usar `api.runonbackend ()` en su lugar."
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"sync-check-failed": "¡La comprobación de sincronización falló!",
|
||||||
|
"consistency-checks-failed": "¡Las comprobaciones de consistencia fallaron! Vea los registros para más detalles.",
|
||||||
|
"encountered-error": "Error encontrado \"{{message}}\", compruebe la consola."
|
||||||
|
},
|
||||||
|
"hoisted_note": {
|
||||||
|
"confirm_unhoisting": "La nota requerida '{{requestedNote}}' está fuera del subárbol de la nota anclada '{{hoistedNote}}' y debe desanclarla para acceder a la nota. ¿Desea proceder con el desanclaje?"
|
||||||
|
},
|
||||||
|
"launcher_context_menu": {
|
||||||
|
"reset_launcher_confirm": "¿Realmente desea restaurar \"{{title}}\"? Todos los datos / ajustes en esta nota (y sus subnotas) se van a perder y el lanzador regresará a su ubicación original.",
|
||||||
|
"add-note-launcher": "Agregar un lanzador de nota",
|
||||||
|
"add-script-launcher": "Agregar un lanzador de script",
|
||||||
|
"add-custom-widget": "Agregar un widget personalizado",
|
||||||
|
"add-spacer": "Agregar espaciador",
|
||||||
|
"delete": "Eliminar",
|
||||||
|
"reset": "Restaurar",
|
||||||
|
"move-to-visible-launchers": "Mover a lanzadores visibles",
|
||||||
|
"move-to-available-launchers": "Mover a lanzadores disponibles",
|
||||||
|
"duplicate-launcher": "Duplicar lanzador"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
"message": "Une erreur critique s'est produite qui empêche l'application client de démarrer :\n\n{{message}}\n\nCeci est probablement dû à un échec inattendu d'un script. Essayez de démarrer l'application en mode sans échec et de résoudre le problème."
|
"message": "Une erreur critique s'est produite qui empêche l'application client de démarrer :\n\n{{message}}\n\nCeci est probablement dû à un échec inattendu d'un script. Essayez de démarrer l'application en mode sans échec et de résoudre le problème."
|
||||||
},
|
},
|
||||||
"widget-error": {
|
"widget-error": {
|
||||||
"title": "Impossible d'initialiser un widget",
|
"title": "Impossible d'initialiser un widget"
|
||||||
"message": "Le widget portant le titre \"{{title}}\" n'a pas pu être initialisé en raison de :\n\n{{message}}"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"add_link": {
|
"add_link": {
|
||||||
@ -975,7 +974,7 @@
|
|||||||
"error_creating_anonymized_database": "Impossible de créer une base de données anonymisée, vérifiez les journaux backend pour plus de détails",
|
"error_creating_anonymized_database": "Impossible de créer une base de données anonymisée, vérifiez les journaux backend pour plus de détails",
|
||||||
"successfully_created_fully_anonymized_database": "Base de données entièrement anonymisée crée dans {{anonymizedFilePath}}",
|
"successfully_created_fully_anonymized_database": "Base de données entièrement anonymisée crée dans {{anonymizedFilePath}}",
|
||||||
"successfully_created_lightly_anonymized_database": "Base de données partiellement anonymisée crée dans {{anonymizedFilePath}}",
|
"successfully_created_lightly_anonymized_database": "Base de données partiellement anonymisée crée dans {{anonymizedFilePath}}",
|
||||||
"no_anonymized_database_yet": "aucune base de données anonymisée"
|
"no_anonymized_database_yet": "Aucune base de données anonymisée"
|
||||||
},
|
},
|
||||||
"database_integrity_check": {
|
"database_integrity_check": {
|
||||||
"title": "Vérification de l'intégrité de la base de données",
|
"title": "Vérification de l'intégrité de la base de données",
|
||||||
|
@ -381,7 +381,7 @@
|
|||||||
"full_anonymization_description": "Această acțiune va crea o nouă copie a bazei de date și o va anonimiza (se șterge conținutul tuturor notițelor și se menține doar structura și câteva metainformații neconfidențiale) pentru a putea fi partajate online cu scopul de a depana anumite probleme fără a risca expunerea datelor personale.",
|
"full_anonymization_description": "Această acțiune va crea o nouă copie a bazei de date și o va anonimiza (se șterge conținutul tuturor notițelor și se menține doar structura și câteva metainformații neconfidențiale) pentru a putea fi partajate online cu scopul de a depana anumite probleme fără a risca expunerea datelor personale.",
|
||||||
"light_anonymization": "Anonimizare parțială",
|
"light_anonymization": "Anonimizare parțială",
|
||||||
"light_anonymization_description": "Această acțiune va crea o copie a bazei de date și o va anonimiza parțial - mai exact se va șterge conținutul tuturor notițelor, dar titlurile și atributele vor rămâne. De asemenea, script-urile de front-end sau back-end și widget-urile personalizate vor rămâne și ele. Acest lucru oferă mai mult context pentru a depana probleme.",
|
"light_anonymization_description": "Această acțiune va crea o copie a bazei de date și o va anonimiza parțial - mai exact se va șterge conținutul tuturor notițelor, dar titlurile și atributele vor rămâne. De asemenea, script-urile de front-end sau back-end și widget-urile personalizate vor rămâne și ele. Acest lucru oferă mai mult context pentru a depana probleme.",
|
||||||
"no_anonymized_database_yet": "încă nu există nicio bază de date anonimizată",
|
"no_anonymized_database_yet": "Încă nu există nicio bază de date anonimizată.",
|
||||||
"save_fully_anonymized_database": "Salvează bază de date complet anonimizată",
|
"save_fully_anonymized_database": "Salvează bază de date complet anonimizată",
|
||||||
"save_lightly_anonymized_database": "Salvează bază de date parțial anonimizată",
|
"save_lightly_anonymized_database": "Salvează bază de date parțial anonimizată",
|
||||||
"successfully_created_fully_anonymized_database": "S-a creat cu succes o bază de date complet anonimizată în {{anonymizedFilePath}}",
|
"successfully_created_fully_anonymized_database": "S-a creat cu succes o bază de date complet anonimizată în {{anonymizedFilePath}}",
|
||||||
@ -553,7 +553,7 @@
|
|||||||
"open_sql_console": "Deschide consola SQL",
|
"open_sql_console": "Deschide consola SQL",
|
||||||
"open_sql_console_history": "Deschide istoricul consolei SQL",
|
"open_sql_console_history": "Deschide istoricul consolei SQL",
|
||||||
"options": "Opțiuni",
|
"options": "Opțiuni",
|
||||||
"reload_frontend": "Reîncarcă interfață",
|
"reload_frontend": "Reîncarcă interfața",
|
||||||
"reload_hint": "Reîncărcarea poate ajuta atunci când există ceva probleme vizuale fără a trebui repornită întreaga aplicație.",
|
"reload_hint": "Reîncărcarea poate ajuta atunci când există ceva probleme vizuale fără a trebui repornită întreaga aplicație.",
|
||||||
"reset_zoom_level": "Resetează nivelul de zoom",
|
"reset_zoom_level": "Resetează nivelul de zoom",
|
||||||
"show_backend_log": "Afișează log-ul din backend",
|
"show_backend_log": "Afișează log-ul din backend",
|
||||||
@ -684,7 +684,8 @@
|
|||||||
"safeImportTooltip": "Fișierele de Trilium exportate în format <code>.zip</code> pot conține scripturi executabile ce pot avea un comportament malițios. Importarea sigură va dezactiva execuția automată a tuturor scripturilor importate. Debifați „Importare sigură” dacă arhiva importată conține scripturi executabile dorite și aveți încredere deplină în conținutul acestora.",
|
"safeImportTooltip": "Fișierele de Trilium exportate în format <code>.zip</code> pot conține scripturi executabile ce pot avea un comportament malițios. Importarea sigură va dezactiva execuția automată a tuturor scripturilor importate. Debifați „Importare sigură” dacă arhiva importată conține scripturi executabile dorite și aveți încredere deplină în conținutul acestora.",
|
||||||
"shrinkImages": "Micșorare imagini",
|
"shrinkImages": "Micșorare imagini",
|
||||||
"shrinkImagesTooltip": "<p>Dacă bifați această opțiune, Trilium va încerca să micșoreze imaginea importată prin scalarea și importarea ei, aspect ce poate afecta calitatea aparentă a imaginii. Dacă nu este bifat, imaginile vor fi importate fără nicio modificare.</p><p>Acest lucru nu se aplică la importuri de tip <code>.zip</code> cu metainformații deoarece se asumă că aceste fișiere sunt deja optimizate.</p>",
|
"shrinkImagesTooltip": "<p>Dacă bifați această opțiune, Trilium va încerca să micșoreze imaginea importată prin scalarea și importarea ei, aspect ce poate afecta calitatea aparentă a imaginii. Dacă nu este bifat, imaginile vor fi importate fără nicio modificare.</p><p>Acest lucru nu se aplică la importuri de tip <code>.zip</code> cu metainformații deoarece se asumă că aceste fișiere sunt deja optimizate.</p>",
|
||||||
"textImportedAsText": "Importă HTML, Markdown și TXT ca notițe de tip text dacă este neclar din metainformații"
|
"textImportedAsText": "Importă HTML, Markdown și TXT ca notițe de tip text dacă este neclar din metainformații",
|
||||||
|
"failed": "Eroare la importare: {{message}}."
|
||||||
},
|
},
|
||||||
"include_archived_notes": {
|
"include_archived_notes": {
|
||||||
"include_archived_notes": "Include notițele arhivate"
|
"include_archived_notes": "Include notițele arhivate"
|
||||||
@ -784,7 +785,10 @@
|
|||||||
"print_note": "Imprimare notiță",
|
"print_note": "Imprimare notiță",
|
||||||
"re_render_note": "Reinterpretare notiță",
|
"re_render_note": "Reinterpretare notiță",
|
||||||
"save_revision": "Salvează o nouă revizie",
|
"save_revision": "Salvează o nouă revizie",
|
||||||
"search_in_note": "Caută în notiță"
|
"search_in_note": "Caută în notiță",
|
||||||
|
"convert_into_attachment_failed": "Nu s-a putut converti notița „{{title}}”.",
|
||||||
|
"convert_into_attachment_successful": "Notița „{{title}}” a fost convertită în atașament.",
|
||||||
|
"convert_into_attachment_prompt": "Doriți convertirea notiței „{{title}}” într-un atașament al notiței părinte?"
|
||||||
},
|
},
|
||||||
"note_erasure_timeout": {
|
"note_erasure_timeout": {
|
||||||
"deleted_notes_erased": "Notițele șterse au fost eliminate permanent.",
|
"deleted_notes_erased": "Notițele șterse au fost eliminate permanent.",
|
||||||
@ -902,7 +906,15 @@
|
|||||||
},
|
},
|
||||||
"protected_session": {
|
"protected_session": {
|
||||||
"enter_password_instruction": "Afișarea notițelor protejate necesită introducerea parolei:",
|
"enter_password_instruction": "Afișarea notițelor protejate necesită introducerea parolei:",
|
||||||
"start_session_button": "Deschide sesiunea protejată"
|
"start_session_button": "Deschide sesiunea protejată",
|
||||||
|
"started": "Sesiunea protejată este activă.",
|
||||||
|
"wrong_password": "Parolă greșită.",
|
||||||
|
"protecting-finished-successfully": "Protejarea a avut succes.",
|
||||||
|
"protecting-in-progress": "Protejare în curs: {{count}}",
|
||||||
|
"protecting-title": "Stare protejare",
|
||||||
|
"unprotecting-title": "Stare deprotejare",
|
||||||
|
"unprotecting-finished-successfully": "Deprotejarea a avut succes.",
|
||||||
|
"unprotecting-in-progress-count": "Deprotejare în curs: {{count}}"
|
||||||
},
|
},
|
||||||
"protected_session_password": {
|
"protected_session_password": {
|
||||||
"close_label": "Închide",
|
"close_label": "Închide",
|
||||||
@ -1081,7 +1093,8 @@
|
|||||||
"label_year_comparison": "comparații numerice (de asemenea >, >=, <).",
|
"label_year_comparison": "comparații numerice (de asemenea >, >=, <).",
|
||||||
"placeholder": "cuvinte cheie pentru căutarea în conținut, #etichetă = valoare...",
|
"placeholder": "cuvinte cheie pentru căutarea în conținut, #etichetă = valoare...",
|
||||||
"search_syntax": "Sintaxa de căutare",
|
"search_syntax": "Sintaxa de căutare",
|
||||||
"title_column": "Textul de căutat:"
|
"title_column": "Textul de căutat:",
|
||||||
|
"search_prefix": "Căutare:"
|
||||||
},
|
},
|
||||||
"shortcuts": {
|
"shortcuts": {
|
||||||
"action_name": "Denumirea acțiunii",
|
"action_name": "Denumirea acțiunii",
|
||||||
@ -1133,7 +1146,9 @@
|
|||||||
"force_full_sync_button": "Forțează sincronizare completă",
|
"force_full_sync_button": "Forțează sincronizare completă",
|
||||||
"full_sync_triggered": "S-a activat o sincronizare completă",
|
"full_sync_triggered": "S-a activat o sincronizare completă",
|
||||||
"sync_rows_filled_successfully": "Rândurile de sincronizare s-au completat cu succes",
|
"sync_rows_filled_successfully": "Rândurile de sincronizare s-au completat cu succes",
|
||||||
"title": "Sincronizare"
|
"title": "Sincronizare",
|
||||||
|
"failed": "Eroare la sincronizare: {{message}}",
|
||||||
|
"finished-successfully": "Sincronizarea a avut succes."
|
||||||
},
|
},
|
||||||
"sync_2": {
|
"sync_2": {
|
||||||
"config_title": "Configurația sincronizării",
|
"config_title": "Configurația sincronizării",
|
||||||
@ -1174,8 +1189,13 @@
|
|||||||
"title": "Eroare critică"
|
"title": "Eroare critică"
|
||||||
},
|
},
|
||||||
"widget-error": {
|
"widget-error": {
|
||||||
"message": "Widget-ul intitulat „{{title}}” nu a putut fi inițializat din cauza:\n\n{{message}}",
|
"title": "Eroare la inițializarea unui widget",
|
||||||
"title": "Eroare la inițializarea unui widget"
|
"message-custom": "Widget-ul personalizat din notița cu ID-ul „{{id}}”, întitulată ”{{title}}” nu a putut fi inițializată din cauza:\n\n{{message}}",
|
||||||
|
"message-unknown": "Un widget necunoscut nu a putut fi inițializat din cauza:\n\n{{message}}"
|
||||||
|
},
|
||||||
|
"bundle-error": {
|
||||||
|
"title": "Eroare la încărcarea unui script personalizat",
|
||||||
|
"message": "Scriptul din notița cu ID-ul „{{id}}”, întitulată „{{title}}” nu a putut fi executată din cauza:\n\n{{message}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tray": {
|
"tray": {
|
||||||
@ -1280,7 +1300,9 @@
|
|||||||
"sort-by": "Ordonare după...",
|
"sort-by": "Ordonare după...",
|
||||||
"unprotect-subtree": "Deprotejează ierarhia",
|
"unprotect-subtree": "Deprotejează ierarhia",
|
||||||
"hoist-note": "Focalizează notița",
|
"hoist-note": "Focalizează notița",
|
||||||
"unhoist-note": "Defocalizează notița"
|
"unhoist-note": "Defocalizează notița",
|
||||||
|
"converted-to-attachments": "{{count}} notițe au fost convertite în atașamente.",
|
||||||
|
"convert-to-attachment-confirm": "Doriți convertirea notițelor selectate în atașamente ale notiței părinte?"
|
||||||
},
|
},
|
||||||
"shared_info": {
|
"shared_info": {
|
||||||
"help_link": "Pentru informații vizitați <a href=\"https://triliumnext.github.io/Docs/Wiki/sharing.html\">wiki-ul</a>.",
|
"help_link": "Pentru informații vizitați <a href=\"https://triliumnext.github.io/Docs/Wiki/sharing.html\">wiki-ul</a>.",
|
||||||
@ -1303,7 +1325,8 @@
|
|||||||
"file": "Fișier",
|
"file": "Fișier",
|
||||||
"image": "Imagine",
|
"image": "Imagine",
|
||||||
"launcher": "Scurtătură",
|
"launcher": "Scurtătură",
|
||||||
"widget": "Widget"
|
"widget": "Widget",
|
||||||
|
"confirm-change": "Nu se recomandă schimbarea tipului notiței atunci când ea are un conținut. Procedați oricum?"
|
||||||
},
|
},
|
||||||
"protect_note": {
|
"protect_note": {
|
||||||
"toggle-off": "Deprotejează notița",
|
"toggle-off": "Deprotejează notița",
|
||||||
@ -1369,7 +1392,9 @@
|
|||||||
"hide-archived-notes": "Ascunde notițele arhivate",
|
"hide-archived-notes": "Ascunde notițele arhivate",
|
||||||
"save-changes": "Salvează și aplică modificările",
|
"save-changes": "Salvează și aplică modificările",
|
||||||
"scroll-active-title": "Mergi la notița activă",
|
"scroll-active-title": "Mergi la notița activă",
|
||||||
"tree-settings-title": "Setări ale ierarhiei notițelor"
|
"tree-settings-title": "Setări ale ierarhiei notițelor",
|
||||||
|
"auto-collapsing-notes-after-inactivity": "Se minimizează notițele după inactivitate...",
|
||||||
|
"saved-search-note-refreshed": "Notița de căutare salvată a fost reîmprospătată."
|
||||||
},
|
},
|
||||||
"title_bar_buttons": {
|
"title_bar_buttons": {
|
||||||
"window-on-top": "Menține fereastra mereu vizibilă"
|
"window-on-top": "Menține fereastra mereu vizibilă"
|
||||||
@ -1413,7 +1438,8 @@
|
|||||||
"close_other_tabs": "Închide celelalte taburi",
|
"close_other_tabs": "Închide celelalte taburi",
|
||||||
"close_tab": "Închide tab",
|
"close_tab": "Închide tab",
|
||||||
"move_tab_to_new_window": "Mută acest tab în altă fereastră",
|
"move_tab_to_new_window": "Mută acest tab în altă fereastră",
|
||||||
"new_tab": "Tab nou"
|
"new_tab": "Tab nou",
|
||||||
|
"close_right_tabs": "Închide taburile din dreapta"
|
||||||
},
|
},
|
||||||
"toc": {
|
"toc": {
|
||||||
"options": "Setări",
|
"options": "Setări",
|
||||||
@ -1423,5 +1449,53 @@
|
|||||||
"file_last_modified": "Fișierul <code class=\"file-path\"></code> a fost ultima oară modificat la data de <span class=\"file-last-modified\"></span>.",
|
"file_last_modified": "Fișierul <code class=\"file-path\"></code> a fost ultima oară modificat la data de <span class=\"file-last-modified\"></span>.",
|
||||||
"ignore_this_change": "Ignoră această schimbare",
|
"ignore_this_change": "Ignoră această schimbare",
|
||||||
"upload_modified_file": "Încarcă fișier modificat"
|
"upload_modified_file": "Încarcă fișier modificat"
|
||||||
|
},
|
||||||
|
"clipboard": {
|
||||||
|
"copied": "Notițele au fost copiate în clipboard.",
|
||||||
|
"cut": "Notițele au fost decupate în clipboard."
|
||||||
|
},
|
||||||
|
"entrypoints": {
|
||||||
|
"note-executed": "Notița a fost executată.",
|
||||||
|
"note-revision-created": "S-a creat o revizie a notiței.",
|
||||||
|
"sql-error": "A apărut o eroare la executarea interogării SQL: {{message}}"
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"cannot-copy": "Nu s-a putut copia în clipboard referința către imagine.",
|
||||||
|
"copied-to-clipboard": "S-a copiat o referință către imagine în clipboard. Aceasta se poate lipi în orice notiță text."
|
||||||
|
},
|
||||||
|
"note_create": {
|
||||||
|
"duplicated": "Notița „{{title}}” a fost dublificată."
|
||||||
|
},
|
||||||
|
"branches": {
|
||||||
|
"cannot-move-notes-here": "Nu se pot muta notițe aici.",
|
||||||
|
"delete-finished-successfully": "Ștergerea a avut succes.",
|
||||||
|
"delete-notes-in-progress": "Ștergere în curs: {{count}}",
|
||||||
|
"delete-status": "Starea ștergerii",
|
||||||
|
"undeleting-notes-finished-successfully": "Restaurarea notițelor a avut succes.",
|
||||||
|
"undeleting-notes-in-progress": "Restaurare notițe în curs: {{count}}"
|
||||||
|
},
|
||||||
|
"frontend_script_api": {
|
||||||
|
"async_warning": "Ați trimis o funcție asincronă metodei `api.runOnBackend()` și este posibil să nu se comporte așa cum vă așteptați.\\nFie faceți metoda sincronă (prin ștergerea cuvântului-cheie `async`), sau folosiți `api.runAsyncOnBackendWithManualTransactionHandling()`.",
|
||||||
|
"sync_warning": "Ați trimis o funcție sincronă funcției `api.runAsyncOnBackendWithManualTransactionHandling()`,\\ndar cel mai probabil trebuie folosit `api.runOnBackend()` în schimb."
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"consistency-checks-failed": "Au fost identificate erori de consistență! Vedeți mai multe detalii în loguri.",
|
||||||
|
"encountered-error": "A fost întâmpinată o eroare: „{{message}}”. Vedeți în loguri pentru mai multe detalii.",
|
||||||
|
"sync-check-failed": "Verificările de sincronizare au eșuat!"
|
||||||
|
},
|
||||||
|
"hoisted_note": {
|
||||||
|
"confirm_unhoisting": "Notița dorită „{{requestedNote}}” este în afara ierarhiei notiței focalizate „{{hoistedNote}}”. Doriți defocalizarea pentru a accesa notița?"
|
||||||
|
},
|
||||||
|
"launcher_context_menu": {
|
||||||
|
"reset_launcher_confirm": "Doriți resetarea lansatorului „{{title}}”? Toate datele și setările din această notiță (și subnotițele ei) vor fi pierdute, iar lansatorul va fi resetat în poziția lui originală.",
|
||||||
|
"add-custom-widget": "Adaugă un widget personalizat",
|
||||||
|
"add-note-launcher": "Adaugă un lansator de notiță",
|
||||||
|
"add-script-launcher": "Adaugă un lansator de script",
|
||||||
|
"add-spacer": "Adaugă un separator",
|
||||||
|
"delete": "Șterge",
|
||||||
|
"duplicate-launcher": "Dublifică lansatorul",
|
||||||
|
"move-to-available-launchers": "Mută în Lansatoare disponibile",
|
||||||
|
"move-to-visible-launchers": "Mută în Lansatoare vizibile",
|
||||||
|
"reset": "Resetează"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import log from "../../services/log.js";
|
|||||||
import searchService from "../../services/search/services/search.js";
|
import searchService from "../../services/search/services/search.js";
|
||||||
import ValidationError from "../../errors/validation_error.js";
|
import ValidationError from "../../errors/validation_error.js";
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
|
import { changeLanguage } from "../../services/i18n.js";
|
||||||
|
|
||||||
// options allowed to be updated directly in the Options dialog
|
// options allowed to be updated directly in the Options dialog
|
||||||
const ALLOWED_OPTIONS = new Set([
|
const ALLOWED_OPTIONS = new Set([
|
||||||
@ -108,6 +109,11 @@ function update(name: string, value: string) {
|
|||||||
|
|
||||||
optionService.setOption(name, value);
|
optionService.setOption(name, value);
|
||||||
|
|
||||||
|
if (name === "locale") {
|
||||||
|
// This runs asynchronously, so it's not perfect, but it does the trick for now.
|
||||||
|
changeLanguage(value);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,13 +23,10 @@ function register(app: Application) {
|
|||||||
|
|
||||||
// error handler
|
// error handler
|
||||||
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
|
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
|
||||||
if (err && err.message && (
|
if (err.status !== 404) {
|
||||||
(err.message.includes("Router not found for request") && err.message.includes(".js.map"))
|
|
||||||
|| (err.message.includes("Router not found for request") && err.message.includes(".css.map"))
|
|
||||||
)) {
|
|
||||||
// ignore
|
|
||||||
} else {
|
|
||||||
log.info(err);
|
log.info(err);
|
||||||
|
} else {
|
||||||
|
log.info(`${err.status} ${req.method} ${req.url}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(err.status || 500);
|
res.status(err.status || 500);
|
||||||
|
@ -9,14 +9,20 @@ import searchService from "../services/search/services/search.js";
|
|||||||
import SearchContext from "../services/search/search_context.js";
|
import SearchContext from "../services/search/search_context.js";
|
||||||
import hoistedNoteService from "./hoisted_note.js";
|
import hoistedNoteService from "./hoisted_note.js";
|
||||||
import BNote from "../becca/entities/bnote.js";
|
import BNote from "../becca/entities/bnote.js";
|
||||||
|
import { t } from "i18next";
|
||||||
|
|
||||||
const CALENDAR_ROOT_LABEL = 'calendarRoot';
|
const CALENDAR_ROOT_LABEL = 'calendarRoot';
|
||||||
const YEAR_LABEL = 'yearNote';
|
const YEAR_LABEL = 'yearNote';
|
||||||
const MONTH_LABEL = 'monthNote';
|
const MONTH_LABEL = 'monthNote';
|
||||||
const DATE_LABEL = 'dateNote';
|
const DATE_LABEL = 'dateNote';
|
||||||
|
|
||||||
const DAYS = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
|
const WEEKDAY_TRANSLATION_IDS = [
|
||||||
const MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];
|
"weekdays.sunday", "weekdays.monday", "weekdays.tuesday", "weekdays.wednesday", "weekdays.thursday", "weekdays.friday", "weekdays.saturday", "weekdays.sunday"
|
||||||
|
];
|
||||||
|
|
||||||
|
const MONTH_TRANSLATION_IDS = [
|
||||||
|
"months.january", "months.february", "months.march", "months.april", "months.may", "months.june", "months.july", "months.august", "months.september", "months.october", "months.november", "months.december"
|
||||||
|
];
|
||||||
|
|
||||||
type StartOfWeek = "monday" | "sunday";
|
type StartOfWeek = "monday" | "sunday";
|
||||||
|
|
||||||
@ -92,7 +98,7 @@ function getYearNote(dateStr: string, _rootNote: BNote | null = null): BNote {
|
|||||||
|
|
||||||
function getMonthNoteTitle(rootNote: BNote, monthNumber: string, dateObj: Date) {
|
function getMonthNoteTitle(rootNote: BNote, monthNumber: string, dateObj: Date) {
|
||||||
const pattern = rootNote.getOwnedLabelValue("monthPattern") || "{monthNumberPadded} - {month}";
|
const pattern = rootNote.getOwnedLabelValue("monthPattern") || "{monthNumberPadded} - {month}";
|
||||||
const monthName = MONTHS[dateObj.getMonth()];
|
const monthName = t(MONTH_TRANSLATION_IDS[dateObj.getMonth()]);
|
||||||
|
|
||||||
return pattern
|
return pattern
|
||||||
.replace(/{shortMonth3}/g, monthName.slice(0,3))
|
.replace(/{shortMonth3}/g, monthName.slice(0,3))
|
||||||
@ -138,7 +144,7 @@ function getMonthNote(dateStr: string, _rootNote: BNote | null = null): BNote {
|
|||||||
|
|
||||||
function getDayNoteTitle(rootNote: BNote, dayNumber: string, dateObj: Date) {
|
function getDayNoteTitle(rootNote: BNote, dayNumber: string, dateObj: Date) {
|
||||||
const pattern = rootNote.getOwnedLabelValue("datePattern") || "{dayInMonthPadded} - {weekDay}";
|
const pattern = rootNote.getOwnedLabelValue("datePattern") || "{dayInMonthPadded} - {weekDay}";
|
||||||
const weekDay = DAYS[dateObj.getDay()];
|
const weekDay = t(WEEKDAY_TRANSLATION_IDS[dateObj.getDay()]);
|
||||||
|
|
||||||
return pattern
|
return pattern
|
||||||
.replace(/{ordinal}/g, ordinal(parseInt(dayNumber)))
|
.replace(/{ordinal}/g, ordinal(parseInt(dayNumber)))
|
||||||
|
@ -58,8 +58,16 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
|
|||||||
|
|
||||||
function getDataFileName(type: string | null, mime: string, baseFileName: string, existingFileNames: Record<string, number>): string {
|
function getDataFileName(type: string | null, mime: string, baseFileName: string, existingFileNames: Record<string, number>): string {
|
||||||
let fileName = baseFileName.trim();
|
let fileName = baseFileName.trim();
|
||||||
|
|
||||||
|
// Crop fileName to avoid its length exceeding 30 and prevent cutting into the extension.
|
||||||
if (fileName.length > 30) {
|
if (fileName.length > 30) {
|
||||||
fileName = fileName.substr(0, 30).trim();
|
// We use regex to match the extension to preserve multiple dots in extensions (e.g. .tar.gz).
|
||||||
|
let match = fileName.match(/(\.[a-zA-Z0-9_.!#-]+)$/);
|
||||||
|
let ext = match ? match[0] : '';
|
||||||
|
// Crop the extension if extension length exceeds 30
|
||||||
|
const croppedExt = ext.slice(-30);
|
||||||
|
// Crop the file name section and append the cropped extension
|
||||||
|
fileName = fileName.slice(0, 30 - croppedExt.length) + croppedExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
let existingExtension = path.extname(fileName).toLowerCase();
|
let existingExtension = path.extname(fileName).toLowerCase();
|
||||||
@ -76,6 +84,9 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
|
|||||||
else if (mime === 'application/x-javascript' || mime === 'text/javascript') {
|
else if (mime === 'application/x-javascript' || mime === 'text/javascript') {
|
||||||
newExtension = 'js';
|
newExtension = 'js';
|
||||||
}
|
}
|
||||||
|
else if (type === 'canvas' || mime === 'application/json') {
|
||||||
|
newExtension = 'json';
|
||||||
|
}
|
||||||
else if (existingExtension.length > 0) { // if the page already has an extension, then we'll just keep it
|
else if (existingExtension.length > 0) { // if the page already has an extension, then we'll just keep it
|
||||||
newExtension = null;
|
newExtension = null;
|
||||||
}
|
}
|
||||||
|
@ -41,4 +41,8 @@ function getCurrentLanguage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function changeLanguage(locale: string) {
|
||||||
|
return i18next.changeLanguage(locale);
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ import hoistedNoteService from "./hoisted_note.js";
|
|||||||
import searchService from "./search/services/search.js";
|
import searchService from "./search/services/search.js";
|
||||||
import SearchContext from "./search/search_context.js";
|
import SearchContext from "./search/search_context.js";
|
||||||
import hiddenSubtree from "./hidden_subtree.js";
|
import hiddenSubtree from "./hidden_subtree.js";
|
||||||
|
import { t } from "i18next";
|
||||||
const { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } = hiddenSubtree;
|
const { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } = hiddenSubtree;
|
||||||
|
|
||||||
function getInboxNote(date: string) {
|
function getInboxNote(date: string) {
|
||||||
@ -75,7 +76,7 @@ function saveSqlConsole(sqlConsoleNoteId: string) {
|
|||||||
function createSearchNote(searchString: string, ancestorNoteId: string) {
|
function createSearchNote(searchString: string, ancestorNoteId: string) {
|
||||||
const {note} = noteService.createNewNote({
|
const {note} = noteService.createNewNote({
|
||||||
parentNoteId: getMonthlyParentNoteId('_search', 'search'),
|
parentNoteId: getMonthlyParentNoteId('_search', 'search'),
|
||||||
title: `Search: ${searchString}`,
|
title: `${t("special_notes.search_prefix")} ${searchString}`,
|
||||||
content: "",
|
content: "",
|
||||||
type: 'search',
|
type: 'search',
|
||||||
mime: 'application/json'
|
mime: 'application/json'
|
||||||
|
@ -219,11 +219,14 @@ function formatDownloadTitle(fileName: string, type: string | null, mime: string
|
|||||||
function removeTextFileExtension(filePath: string) {
|
function removeTextFileExtension(filePath: string) {
|
||||||
const extension = path.extname(filePath).toLowerCase();
|
const extension = path.extname(filePath).toLowerCase();
|
||||||
|
|
||||||
if (extension === '.md' || extension === '.markdown' || extension === '.html') {
|
switch (extension) {
|
||||||
return filePath.substr(0, filePath.length - extension.length);
|
case ".md":
|
||||||
}
|
case ".markdown":
|
||||||
else {
|
case ".html":
|
||||||
return filePath;
|
case ".htm":
|
||||||
|
return filePath.substr(0, filePath.length - extension.length);
|
||||||
|
default:
|
||||||
|
return filePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,5 +157,31 @@
|
|||||||
"clipped-from": "This note was originally clipped from {{- url}}",
|
"clipped-from": "This note was originally clipped from {{- url}}",
|
||||||
"child-notes": "Child notes:",
|
"child-notes": "Child notes:",
|
||||||
"no-content": "This note has no content."
|
"no-content": "This note has no content."
|
||||||
|
},
|
||||||
|
"weekdays": {
|
||||||
|
"monday": "Monday",
|
||||||
|
"tuesday": "Tuesday",
|
||||||
|
"wednesday": "Wednesday",
|
||||||
|
"thursday": "Thursday",
|
||||||
|
"friday": "Friday",
|
||||||
|
"saturday": "Saturday",
|
||||||
|
"sunday": "Sunday"
|
||||||
|
},
|
||||||
|
"months": {
|
||||||
|
"january": "January",
|
||||||
|
"february": "February",
|
||||||
|
"march": "March",
|
||||||
|
"april": "April",
|
||||||
|
"may": "May",
|
||||||
|
"june": "June",
|
||||||
|
"july": "July",
|
||||||
|
"august": "August",
|
||||||
|
"september": "September",
|
||||||
|
"october": "October",
|
||||||
|
"november": "November",
|
||||||
|
"december": "December"
|
||||||
|
},
|
||||||
|
"special_notes": {
|
||||||
|
"search_prefix": "Search:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,161 +1,184 @@
|
|||||||
{
|
{
|
||||||
"keyboard_actions": {
|
"keyboard_actions": {
|
||||||
"open-jump-to-note-dialog": "Abrir cuadro de diálogo \"Saltar a nota\"",
|
"open-jump-to-note-dialog": "Abrir cuadro de diálogo \"Saltar a nota\"",
|
||||||
"search-in-subtree": "Buscar notas en el subárbol de la nota activa",
|
"search-in-subtree": "Buscar notas en el subárbol de la nota activa",
|
||||||
"expand-subtree": "Expandir el subárbol de la nota actual",
|
"expand-subtree": "Expandir el subárbol de la nota actual",
|
||||||
"collapse-tree": "Colapsa el árbol de notas completo",
|
"collapse-tree": "Colapsa el árbol de notas completo",
|
||||||
"collapse-subtree": "Colapsa el subárbol de la nota actual",
|
"collapse-subtree": "Colapsa el subárbol de la nota actual",
|
||||||
"sort-child-notes": "Ordenar notas hijas",
|
"sort-child-notes": "Ordenar subnotas",
|
||||||
"creating-and-moving-notes": "Creando y moviendo notas",
|
"creating-and-moving-notes": "Creando y moviendo notas",
|
||||||
"create-note-into-inbox": "Crear una nota en la bandeja de entrada (si está definida) o nota del día",
|
"create-note-into-inbox": "Crear una nota en la bandeja de entrada (si está definida) o nota del día",
|
||||||
"delete-note": "Eliminar nota",
|
"delete-note": "Eliminar nota",
|
||||||
"move-note-up": "Mover nota hacia arriba",
|
"move-note-up": "Mover nota hacia arriba",
|
||||||
"move-note-down": "Mover nota hacia abajo",
|
"move-note-down": "Mover nota hacia abajo",
|
||||||
"move-note-up-in-hierarchy": "Mover nota hacia arriba en la jerarquía",
|
"move-note-up-in-hierarchy": "Mover nota hacia arriba en la jerarquía",
|
||||||
"move-note-down-in-hierarchy": "Mover nota hacia abajo en la jerarquía",
|
"move-note-down-in-hierarchy": "Mover nota hacia abajo en la jerarquía",
|
||||||
"edit-note-title": "Saltar del árbol al detalle de la nota y editar el título",
|
"edit-note-title": "Saltar del árbol al detalle de la nota y editar el título",
|
||||||
"edit-branch-prefix": "Mostrar cuadro de diálogo Editar prefijo de rama",
|
"edit-branch-prefix": "Mostrar cuadro de diálogo Editar prefijo de rama",
|
||||||
"note-clipboard": "Portapapeles de notas",
|
"note-clipboard": "Portapapeles de notas",
|
||||||
"copy-notes-to-clipboard": "Copiar las notas seleccionadas al portapapeles",
|
"copy-notes-to-clipboard": "Copiar las notas seleccionadas al portapapeles",
|
||||||
"paste-notes-from-clipboard": "Pegar las notas del portapapeles en una nota activa",
|
"paste-notes-from-clipboard": "Pegar las notas del portapapeles en una nota activa",
|
||||||
"cut-notes-to-clipboard": "Cortar las notas seleccionadas al portapapeles",
|
"cut-notes-to-clipboard": "Cortar las notas seleccionadas al portapapeles",
|
||||||
"select-all-notes-in-parent": "Seleccionar todas las notas del nivel de la nota actual",
|
"select-all-notes-in-parent": "Seleccionar todas las notas del nivel de la nota actual",
|
||||||
"add-note-above-to-the-selection": "Agregar nota arriba de la selección",
|
"add-note-above-to-the-selection": "Agregar nota arriba de la selección",
|
||||||
"add-note-below-to-selection": "Agregar nota arriba de la selección",
|
"add-note-below-to-selection": "Agregar nota arriba de la selección",
|
||||||
"duplicate-subtree": "Duplicar subárbol",
|
"duplicate-subtree": "Duplicar subárbol",
|
||||||
"tabs-and-windows": "Pestañas y ventanas",
|
"tabs-and-windows": "Pestañas y ventanas",
|
||||||
"open-new-tab": "Abre una nueva pestaña",
|
"open-new-tab": "Abre una nueva pestaña",
|
||||||
"close-active-tab": "Cierra la pestaña activa",
|
"close-active-tab": "Cierra la pestaña activa",
|
||||||
"reopen-last-tab": "Vuelve a abrir la última pestaña cerrada",
|
"reopen-last-tab": "Vuelve a abrir la última pestaña cerrada",
|
||||||
"activate-next-tab": "Activa la pestaña de la derecha",
|
"activate-next-tab": "Activa la pestaña de la derecha",
|
||||||
"activate-previous-tab": "Activa la pestaña de la izquierda",
|
"activate-previous-tab": "Activa la pestaña de la izquierda",
|
||||||
"open-new-window": "Abrir nueva ventana vacía",
|
"open-new-window": "Abrir nueva ventana vacía",
|
||||||
"toggle-tray": "Muestra/Oculta la aplicación en la bandeja del sistema",
|
"toggle-tray": "Muestra/Oculta la aplicación en la bandeja del sistema",
|
||||||
"first-tab": "Activa la primera pestaña de la lista",
|
"first-tab": "Activa la primera pestaña de la lista",
|
||||||
"second-tab": "Activa la segunda pestaña de la lista",
|
"second-tab": "Activa la segunda pestaña de la lista",
|
||||||
"third-tab": "Activa la tercera pestaña de la lista",
|
"third-tab": "Activa la tercera pestaña de la lista",
|
||||||
"fourth-tab": "Activa la cuarta pestaña de la lista",
|
"fourth-tab": "Activa la cuarta pestaña de la lista",
|
||||||
"fifth-tab": "Activa la quinta pestaña de la lista",
|
"fifth-tab": "Activa la quinta pestaña de la lista",
|
||||||
"sixth-tab": "Activa la sexta pestaña de la lista",
|
"sixth-tab": "Activa la sexta pestaña de la lista",
|
||||||
"seventh-tab": "Activa la séptima pestaña de la lista",
|
"seventh-tab": "Activa la séptima pestaña de la lista",
|
||||||
"eight-tab": "Activa la octava pestaña de la lista",
|
"eight-tab": "Activa la octava pestaña de la lista",
|
||||||
"ninth-tab": "Activa la novena pestaña de la lista",
|
"ninth-tab": "Activa la novena pestaña de la lista",
|
||||||
"last-tab": "Activa la última pestaña de la lista",
|
"last-tab": "Activa la última pestaña de la lista",
|
||||||
"dialogs": "Diálogos",
|
"dialogs": "Diálogos",
|
||||||
"show-note-source": "Muestra el cuadro de diálogo Fuente de nota",
|
"show-note-source": "Muestra el cuadro de diálogo Fuente de nota",
|
||||||
"show-options": "Muestra el cuadro de diálogo Opciones",
|
"show-options": "Muestra el cuadro de diálogo Opciones",
|
||||||
"show-revisions": "Muestra el cuadro de diálogo Revisiones de notas",
|
"show-revisions": "Muestra el cuadro de diálogo Revisiones de notas",
|
||||||
"show-recent-changes": "Muestra el cuadro de diálogo Cambios recientes",
|
"show-recent-changes": "Muestra el cuadro de diálogo Cambios recientes",
|
||||||
"show-sql-console": "Muestra el cuadro de diálogo Consola SQL",
|
"show-sql-console": "Muestra el cuadro de diálogo Consola SQL",
|
||||||
"show-backend-log": "Muestra el cuadro de diálogo Registro de backend",
|
"show-backend-log": "Muestra el cuadro de diálogo Registro de backend",
|
||||||
"text-note-operations": "Operaciones de notas de texto",
|
"text-note-operations": "Operaciones de notas de texto",
|
||||||
"add-link-to-text": "Abrir cuadro de diálogo para agregar un enlace al texto",
|
"add-link-to-text": "Abrir cuadro de diálogo para agregar un enlace al texto",
|
||||||
"follow-link-under-cursor": "Seguir el enlace dentro del cual se coloca el cursor",
|
"follow-link-under-cursor": "Seguir el enlace dentro del cual se coloca el cursor",
|
||||||
"insert-date-and-time-to-text": "Insertar fecha y hora actuales en el texto",
|
"insert-date-and-time-to-text": "Insertar fecha y hora actuales en el texto",
|
||||||
"paste-markdown-into-text": "Pega Markdown del portapapeles en la nota de texto",
|
"paste-markdown-into-text": "Pega Markdown del portapapeles en la nota de texto",
|
||||||
"cut-into-note": "Corta la selección de la nota actual y crea una subnota con el texto seleccionado",
|
"cut-into-note": "Corta la selección de la nota actual y crea una subnota con el texto seleccionado",
|
||||||
"add-include-note-to-text": "Abre el cuadro de diálogo para incluir una nota",
|
"add-include-note-to-text": "Abre el cuadro de diálogo para incluir una nota",
|
||||||
"edit-readonly-note": "Editar una nota de sólo lectura",
|
"edit-readonly-note": "Editar una nota de sólo lectura",
|
||||||
"attributes-labels-and-relations": "Atributos (etiquetas y relaciones)",
|
"attributes-labels-and-relations": "Atributos (etiquetas y relaciones)",
|
||||||
"add-new-label": "Crear nueva etiqueta",
|
"add-new-label": "Crear nueva etiqueta",
|
||||||
"create-new-relation": "Crear nueva relación",
|
"create-new-relation": "Crear nueva relación",
|
||||||
"ribbon-tabs": "Pestañas de cinta",
|
"ribbon-tabs": "Pestañas de cinta",
|
||||||
"toggle-basic-properties": "Alternar propiedades básicas",
|
"toggle-basic-properties": "Alternar propiedades básicas",
|
||||||
"toggle-file-properties": "Alternar propiedades de archivo",
|
"toggle-file-properties": "Alternar propiedades de archivo",
|
||||||
"toggle-image-properties": "Alternar propiedades de imagen",
|
"toggle-image-properties": "Alternar propiedades de imagen",
|
||||||
"toggle-owned-attributes": "Alternar atributos de propiedad",
|
"toggle-owned-attributes": "Alternar atributos de propiedad",
|
||||||
"toggle-inherited-attributes": "Alternar atributos heredados",
|
"toggle-inherited-attributes": "Alternar atributos heredados",
|
||||||
"toggle-promoted-attributes": "Alternar atributos promocionados",
|
"toggle-promoted-attributes": "Alternar atributos promocionados",
|
||||||
"toggle-link-map": "Alternar mapa de enlaces",
|
"toggle-link-map": "Alternar mapa de enlaces",
|
||||||
"toggle-note-info": "Alternar información de nota",
|
"toggle-note-info": "Alternar información de nota",
|
||||||
"toggle-note-paths": "Alternar rutas de notas",
|
"toggle-note-paths": "Alternar rutas de notas",
|
||||||
"toggle-similar-notes": "Alternar notas similares",
|
"toggle-similar-notes": "Alternar notas similares",
|
||||||
"other": "Otro",
|
"other": "Otro",
|
||||||
"toggle-right-pane": "Alternar la visualización del panel derecho, que incluye la tabla de contenidos y aspectos destacados",
|
"toggle-right-pane": "Alternar la visualización del panel derecho, que incluye la tabla de contenidos y aspectos destacados",
|
||||||
"print-active-note": "Imprimir nota activa",
|
"print-active-note": "Imprimir nota activa",
|
||||||
"open-note-externally": "Abrir nota como un archivo con la aplicación predeterminada",
|
"open-note-externally": "Abrir nota como un archivo con la aplicación predeterminada",
|
||||||
"render-active-note": "Renderizar (volver a renderizar) nota activa",
|
"render-active-note": "Renderizar (volver a renderizar) nota activa",
|
||||||
"run-active-note": "Ejecutar nota de código JavaScript activa (frontend/backend)",
|
"run-active-note": "Ejecutar nota de código JavaScript activa (frontend/backend)",
|
||||||
"toggle-note-hoisting": "Alterna la elevación de la nota activa",
|
"toggle-note-hoisting": "Alterna la elevación de la nota activa",
|
||||||
"unhoist": "Bajar desde cualquier lugar",
|
"unhoist": "Bajar desde cualquier lugar",
|
||||||
"reload-frontend-app": "Recargar frontend de la aplicación",
|
"reload-frontend-app": "Recargar frontend de la aplicación",
|
||||||
"open-dev-tools": "Abrir herramientas de desarrollo",
|
"open-dev-tools": "Abrir herramientas de desarrollo",
|
||||||
"toggle-left-note-tree-panel": "Alternar panel izquierdo (árbol de notas)",
|
"toggle-left-note-tree-panel": "Alternar panel izquierdo (árbol de notas)",
|
||||||
"toggle-full-screen": "Alternar pantalla completa",
|
"toggle-full-screen": "Alternar pantalla completa",
|
||||||
"zoom-out": "Alejar",
|
"zoom-out": "Alejar",
|
||||||
"zoom-in": "Acercar",
|
"zoom-in": "Acercar",
|
||||||
"note-navigation": "Navegación de notas",
|
"note-navigation": "Navegación de notas",
|
||||||
"reset-zoom-level": "Restablecer nivel de zoom",
|
"reset-zoom-level": "Restablecer nivel de zoom",
|
||||||
"copy-without-formatting": "Copiar el texto seleccionado sin formatear",
|
"copy-without-formatting": "Copiar el texto seleccionado sin formatear",
|
||||||
"force-save-revision": "Forzar la creación/guardado de una nueva revisión de nota de la nota activa",
|
"force-save-revision": "Forzar la creación/guardado de una nueva revisión de nota de la nota activa",
|
||||||
"show-help": "Muestra ayuda/hoja de referencia integrada",
|
"show-help": "Muestra ayuda/hoja de referencia integrada",
|
||||||
"toggle-book-properties": "Alternar propiedades del libro"
|
"toggle-book-properties": "Alternar propiedades del libro"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Iniciar sesión",
|
"title": "Iniciar sesión",
|
||||||
"heading": "Iniciar sesión en Trillium",
|
"heading": "Iniciar sesión en Trillium",
|
||||||
"incorrect-password": "La contraseña es incorrecta. Por favor inténtalo de nuevo.",
|
"incorrect-password": "La contraseña es incorrecta. Por favor inténtalo de nuevo.",
|
||||||
"password": "Contraseña",
|
"password": "Contraseña",
|
||||||
"remember-me": "Recordarme",
|
"remember-me": "Recordarme",
|
||||||
"button": "Iniciar sesión"
|
"button": "Iniciar sesión"
|
||||||
},
|
},
|
||||||
"set_password": {
|
"set_password": {
|
||||||
"heading": "Establecer contraseña",
|
"heading": "Establecer contraseña",
|
||||||
"description": "Antes de poder comenzar a usar Trilium desde la web, primero debe establecer una contraseña. Luego utilizará esta contraseña para iniciar sesión.",
|
"description": "Antes de poder comenzar a usar Trilium desde la web, primero debe establecer una contraseña. Luego utilizará esta contraseña para iniciar sesión.",
|
||||||
"password": "Contraseña",
|
"password": "Contraseña",
|
||||||
"password-confirmation": "Confirmación de contraseña",
|
"password-confirmation": "Confirmación de contraseña",
|
||||||
"button": "Establecer contraseña"
|
"button": "Establecer contraseña"
|
||||||
},
|
},
|
||||||
"javascript-required": "Trilium requiere que JavaScript esté habilitado.",
|
"javascript-required": "Trilium requiere que JavaScript esté habilitado.",
|
||||||
"setup": {
|
"setup": {
|
||||||
"heading": "Configuración de TrilliumNext Notes",
|
"heading": "Configuración de TrilliumNext Notes",
|
||||||
"new-document": "Soy un usuario nuevo y quiero crear un nuevo documento de Trilium para mis notas",
|
"new-document": "Soy un usuario nuevo y quiero crear un nuevo documento de Trilium para mis notas",
|
||||||
"sync-from-desktop": "Ya tengo una instancia de escritorio y quiero configurar la sincronización con ella",
|
"sync-from-desktop": "Ya tengo una instancia de escritorio y quiero configurar la sincronización con ella",
|
||||||
"sync-from-server": "Ya tengo una instancia de servidor y quiero configurar la sincronización con ella",
|
"sync-from-server": "Ya tengo una instancia de servidor y quiero configurar la sincronización con ella",
|
||||||
"next": "Siguiente",
|
"next": "Siguiente",
|
||||||
"init-in-progress": "Inicialización del documento en curso",
|
"init-in-progress": "Inicialización del documento en curso",
|
||||||
"redirecting": "En breve será redirigido a la aplicación.",
|
"redirecting": "En breve será redirigido a la aplicación.",
|
||||||
"title": "Configuración"
|
"title": "Configuración"
|
||||||
},
|
},
|
||||||
"setup_sync-from-desktop": {
|
"setup_sync-from-desktop": {
|
||||||
"heading": "Sincronizar desde el escritorio",
|
"heading": "Sincronizar desde el escritorio",
|
||||||
"description": "Esta configuración debe iniciarse desde la instancia de escritorio:",
|
"description": "Esta configuración debe iniciarse desde la instancia de escritorio:",
|
||||||
"step1": "Abra su instancia de escritorio de TriliumNext Notes.",
|
"step1": "Abra su instancia de escritorio de TriliumNext Notes.",
|
||||||
"step2": "En el menú Trilium, dé clic en Opciones.",
|
"step2": "En el menú Trilium, dé clic en Opciones.",
|
||||||
"step3": "Dé clic en la categoría Sincronizar.",
|
"step3": "Dé clic en la categoría Sincronizar.",
|
||||||
"step4": "Cambie la dirección de la instancia del servidor a: {{- host}} y dé clic en Guardar.",
|
"step4": "Cambie la dirección de la instancia del servidor a: {{- host}} y dé clic en Guardar.",
|
||||||
"step5": "Dé clic en el botón \"Probar sincronización\" para verificar que la conexión fue exitosa.",
|
"step5": "Dé clic en el botón \"Probar sincronización\" para verificar que la conexión fue exitosa.",
|
||||||
"step6": "Una vez que haya completado estos pasos, dé clic en {{- link}}.",
|
"step6": "Una vez que haya completado estos pasos, dé clic en {{- link}}.",
|
||||||
"step6-here": "aquí"
|
"step6-here": "aquí"
|
||||||
},
|
},
|
||||||
"setup_sync-from-server": {
|
"setup_sync-from-server": {
|
||||||
"heading": "Sincronización desde el servidor",
|
"heading": "Sincronización desde el servidor",
|
||||||
"instructions": "Por favor, ingrese la dirección y las credenciales del servidor Trilium a continuación. Esto descargará todo el documento de Trilium desde el servidor y configurará la sincronización. Dependiendo del tamaño del documento y de la velocidad de su conexión, esto puede tardar un poco.",
|
"instructions": "Por favor, ingrese la dirección y las credenciales del servidor Trilium a continuación. Esto descargará todo el documento de Trilium desde el servidor y configurará la sincronización. Dependiendo del tamaño del documento y de la velocidad de su conexión, esto puede tardar un poco.",
|
||||||
"server-host": "Dirección del servidor Trilium",
|
"server-host": "Dirección del servidor Trilium",
|
||||||
"server-host-placeholder": "https://<hostname>:<port>",
|
"server-host-placeholder": "https://<hostname>:<port>",
|
||||||
"proxy-server": "Servidor proxy (opcional)",
|
"proxy-server": "Servidor proxy (opcional)",
|
||||||
"proxy-server-placeholder": "https://<hostname>:<port>",
|
"proxy-server-placeholder": "https://<hostname>:<port>",
|
||||||
"note": "Nota:",
|
"note": "Nota:",
|
||||||
"proxy-instruction": "Si deja la configuración de proxy en blanco, se utilizará el proxy del sistema (aplica únicamente a la aplicación de escritorio)",
|
"proxy-instruction": "Si deja la configuración de proxy en blanco, se utilizará el proxy del sistema (aplica únicamente a la aplicación de escritorio)",
|
||||||
"password": "Contraseña",
|
"password": "Contraseña",
|
||||||
"password-placeholder": "Contraseña",
|
"password-placeholder": "Contraseña",
|
||||||
"back": "Atrás",
|
"back": "Atrás",
|
||||||
"finish-setup": "Finalizar la configuración"
|
"finish-setup": "Finalizar la configuración"
|
||||||
},
|
},
|
||||||
"setup_sync-in-progress": {
|
"setup_sync-in-progress": {
|
||||||
"heading": "Sincronización en progreso",
|
"heading": "Sincronización en progreso",
|
||||||
"successful": "La sincronización se ha configurado correctamente. La sincronización inicial tardará algún tiempo en finalizar. Una vez hecho esto, será redirigido a la página de inicio de sesión.",
|
"successful": "La sincronización se ha configurado correctamente. La sincronización inicial tardará algún tiempo en finalizar. Una vez hecho esto, será redirigido a la página de inicio de sesión.",
|
||||||
"outstanding-items": "Elementos de sincronización destacados:",
|
"outstanding-items": "Elementos de sincronización destacados:",
|
||||||
"outstanding-items-default": "N/A"
|
"outstanding-items-default": "N/A"
|
||||||
},
|
},
|
||||||
"share_404": {
|
"share_404": {
|
||||||
"title": "No encontrado",
|
"title": "No encontrado",
|
||||||
"heading": "No encontrado"
|
"heading": "No encontrado"
|
||||||
},
|
},
|
||||||
"share_page": {
|
"share_page": {
|
||||||
"parent": "padre:",
|
"parent": "padre:",
|
||||||
"clipped-from": "Esta nota fue recortada originalmente de {{- url}}",
|
"clipped-from": "Esta nota fue recortada originalmente de {{- url}}",
|
||||||
"child-notes": "Notas hijo:",
|
"child-notes": "Subnotas:",
|
||||||
"no-content": "Esta nota no tiene contenido."
|
"no-content": "Esta nota no tiene contenido."
|
||||||
}
|
},
|
||||||
|
"weekdays": {
|
||||||
|
"monday": "Lunes",
|
||||||
|
"tuesday": "Martes",
|
||||||
|
"wednesday": "Miércoles",
|
||||||
|
"thursday": "Jueves",
|
||||||
|
"friday": "Viernes",
|
||||||
|
"saturday": "Sábado",
|
||||||
|
"sunday": "Domingo"
|
||||||
|
},
|
||||||
|
"months": {
|
||||||
|
"january": "Enero",
|
||||||
|
"february": "Febrero",
|
||||||
|
"march": "Marzo",
|
||||||
|
"april": "Abril",
|
||||||
|
"may": "Mayo",
|
||||||
|
"june": "Junio",
|
||||||
|
"july": "Julio",
|
||||||
|
"august": "Agosto",
|
||||||
|
"september": "Septiembre",
|
||||||
|
"october": "Octubre",
|
||||||
|
"november": "Noviembre",
|
||||||
|
"december": "Diciembre"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,5 +157,31 @@
|
|||||||
"clipped-from": "Această notiță a fost decupată inițial de pe {{- url}}",
|
"clipped-from": "Această notiță a fost decupată inițial de pe {{- url}}",
|
||||||
"no-content": "Această notiță nu are conținut.",
|
"no-content": "Această notiță nu are conținut.",
|
||||||
"parent": "părinte:"
|
"parent": "părinte:"
|
||||||
|
},
|
||||||
|
"weekdays": {
|
||||||
|
"monday": "Luni",
|
||||||
|
"tuesday": "Marți",
|
||||||
|
"wednesday": "Miercuri",
|
||||||
|
"thursday": "Joi",
|
||||||
|
"friday": "Vineri",
|
||||||
|
"saturday": "Sâmbătă",
|
||||||
|
"sunday": "Duminică"
|
||||||
|
},
|
||||||
|
"months": {
|
||||||
|
"january": "Ianuarie",
|
||||||
|
"february": "Februarie",
|
||||||
|
"march": "Martie",
|
||||||
|
"april": "Aprilie",
|
||||||
|
"may": "Mai",
|
||||||
|
"june": "Iunie",
|
||||||
|
"july": "Iulie",
|
||||||
|
"august": "August",
|
||||||
|
"september": "Septembrie",
|
||||||
|
"october": "Octombrie",
|
||||||
|
"november": "Noiembrie",
|
||||||
|
"december": "Decembrie"
|
||||||
|
},
|
||||||
|
"special_notes": {
|
||||||
|
"search_prefix": "Căutare:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user