mirror of
https://github.com/zadam/trilium.git
synced 2025-10-19 22:58:52 +02:00
Merge branch 'develop' into calendar
This commit is contained in:
commit
bf70b949a6
44
.dprint.json
44
.dprint.json
@ -1,44 +0,0 @@
|
||||
{
|
||||
"typescript": {
|
||||
"indentWidth": 4,
|
||||
"quoteStyle": "preferDouble",
|
||||
"semiColons": "prefer",
|
||||
"quoteProps": "asNeeded",
|
||||
"newLineKind": "lf",
|
||||
"lineWidth": 200,
|
||||
"trailingCommas": "never",
|
||||
"arrayPattern.spaceAround": true,
|
||||
"arrayExpression.spaceAround": true
|
||||
},
|
||||
"json": {
|
||||
},
|
||||
"markdown": {
|
||||
},
|
||||
"dockerfile": {
|
||||
},
|
||||
"malva": {
|
||||
},
|
||||
"markup": {
|
||||
},
|
||||
"yaml": {
|
||||
},
|
||||
"excludes": [
|
||||
"**/node_modules",
|
||||
"**/*-lock.json",
|
||||
"*.html",
|
||||
"*.md",
|
||||
"*.yml",
|
||||
"libraries/*",
|
||||
"docs/*",
|
||||
"src/public/app/doc_notes"
|
||||
],
|
||||
"plugins": [
|
||||
"https://plugins.dprint.dev/typescript-0.94.0.wasm",
|
||||
"https://plugins.dprint.dev/json-0.20.0.wasm",
|
||||
"https://plugins.dprint.dev/markdown-0.18.0.wasm",
|
||||
"https://plugins.dprint.dev/dockerfile-0.3.2.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/malva-v0.11.1.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/markup_fmt-v0.19.0.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm"
|
||||
]
|
||||
}
|
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -4,6 +4,7 @@
|
||||
"editorconfig.editorconfig",
|
||||
"vitest.explorer",
|
||||
"ms-playwright.playwright",
|
||||
"tobermory.es6-string-html"
|
||||
"tobermory.es6-string-html",
|
||||
"dbaeumer.vscode-eslint"
|
||||
]
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"formatVersion": 2,
|
||||
"appVersion": "0.92.4",
|
||||
"appVersion": "0.92.5-beta",
|
||||
"files": [
|
||||
{
|
||||
"isClone": false,
|
||||
@ -1433,28 +1433,28 @@
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BlN9DFI679QC",
|
||||
"value": "vZWERwf8U3nx",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "vZWERwf8U3nx",
|
||||
"value": "4FahAwuGTAwC",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "4FahAwuGTAwC",
|
||||
"value": "0vhv7lsOLy82",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "0vhv7lsOLy82",
|
||||
"value": "BlN9DFI679QC",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
@ -3058,6 +3058,20 @@
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "QxEyIjRBizuC",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "UYuUB1ZekNQU",
|
||||
"isInheritable": false,
|
||||
"position": 70
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
@ -3085,20 +3099,6 @@
|
||||
"value": "",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "UYuUB1ZekNQU",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "QxEyIjRBizuC",
|
||||
"isInheritable": false,
|
||||
"position": 70
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -3231,14 +3231,14 @@
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "QxEyIjRBizuC",
|
||||
"value": "6f9hih2hXXZk",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "6f9hih2hXXZk",
|
||||
"value": "QxEyIjRBizuC",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
@ -3324,44 +3324,44 @@
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "6f9hih2hXXZk",
|
||||
"value": "QxEyIjRBizuC",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "4TIF1oA4VQRO",
|
||||
"value": "6f9hih2hXXZk",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "nRhnJkTT8cPs",
|
||||
"value": "4TIF1oA4VQRO",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "s8alTXmpFR61",
|
||||
"value": "nRhnJkTT8cPs",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "s8alTXmpFR61",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bx-code",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "QxEyIjRBizuC",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -4091,48 +4091,62 @@
|
||||
"type": "text",
|
||||
"mime": "text/markdown",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "zEY4DaJG4YT5",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "OFXdgB2nNk1F",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "wX4HbRucYSDD",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "imageLink",
|
||||
"value": "EH6qNioOHeyT",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "imageLink",
|
||||
"value": "xeZPrfi77XPu",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "imageLink",
|
||||
"value": "N98UhifxrVpZ",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BFs8mudNFgCS",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "zEY4DaJG4YT5",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "OFXdgB2nNk1F",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "wX4HbRucYSDD",
|
||||
"isInheritable": false,
|
||||
"position": 70
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BCkXAVs63Ttv",
|
||||
"isInheritable": false,
|
||||
"position": 80
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
@ -4146,20 +4160,6 @@
|
||||
"value": "bx bxs-network-chart",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BFs8mudNFgCS",
|
||||
"isInheritable": false,
|
||||
"position": 80
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BCkXAVs63Ttv",
|
||||
"isInheritable": false,
|
||||
"position": 90
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -4190,19 +4190,19 @@
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BCkXAVs63Ttv",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bxs-network-chart",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BCkXAVs63Ttv",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -5916,23 +5916,23 @@
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "iRwzGnHPzonm",
|
||||
"value": "bdUJEHsAPYQR",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "iRwzGnHPzonm",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
"value": "note-map",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "bdUJEHsAPYQR",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -6887,21 +6887,21 @@
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "KSZ04uQ2D1St",
|
||||
"value": "_optionsTextNotes",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "_optionsTextNotes",
|
||||
"value": "_optionsCodeNotes",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "_optionsCodeNotes",
|
||||
"value": "KSZ04uQ2D1St",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
@ -6929,21 +6929,21 @@
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "gBbsAeiuUxI5",
|
||||
"value": "H0mM1lTxF9JI",
|
||||
"isInheritable": false,
|
||||
"position": 70
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "N4IDkixaDG9C",
|
||||
"value": "gBbsAeiuUxI5",
|
||||
"isInheritable": false,
|
||||
"position": 80
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "H0mM1lTxF9JI",
|
||||
"value": "N4IDkixaDG9C",
|
||||
"isInheritable": false,
|
||||
"position": 90
|
||||
},
|
||||
|
@ -35,7 +35,7 @@ Basic Auth is meant to be used with tools which support only basic auth.
|
||||
|
||||
It is possible to write simple Bash scripts to interact with Trilium. As an example, here's how to obtain the HTML content of a note:
|
||||
|
||||
```sh
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Configuration
|
||||
|
@ -15,7 +15,7 @@ Note that some information is also stored as [Attachments](../Attachments). For
|
||||
|
||||
Here's part of the HTML representation of this note, as it's stored in the database (but prettified).
|
||||
|
||||
```html
|
||||
```
|
||||
<h2>
|
||||
Understanding the source code of the different notes
|
||||
</h2>
|
||||
|
@ -21,7 +21,7 @@ Trilium makes use of such features:
|
||||
|
||||
* The math feature is added by a version of [isaul32/ckeditor5-math: Math feature for CKEditor 5.](https://github.com/isaul32/ckeditor5-math) modified by us to fit our needs.
|
||||
* We also make use of modified upstream plugins such as [ckeditor/ckeditor5-mermaid](https://github.com/ckeditor/ckeditor5-mermaid) to allow inline Mermaid code.
|
||||
* [mlewand/ckeditor5-keyboard-marker: Plugin adds support for the keyboard input element (<kbd>) to CKEditor 5.](https://github.com/mlewand/ckeditor5-keyboard-marker)
|
||||
* [mlewand/ckeditor5-keyboard-marker: Plugin adds support for the keyboard input element (`<kbd>`) to CKEditor 5.](https://github.com/mlewand/ckeditor5-keyboard-marker)
|
||||
* A modified version of [ThomasAitken/ckeditor5-footnotes: Footnotes plugin for CKEditor5](https://github.com/ThomasAitken/ckeditor5-footnotes) to allow footnotes.
|
||||
|
||||
Apart from that, Trilium also has its own set of specific plugins such as:
|
||||
|
@ -25,3 +25,40 @@ test("Complete help in search", async ({ page, context }) => {
|
||||
const popup = await popupPromise;
|
||||
expect(popup.url()).toBe("https://triliumnext.github.io/Docs/Wiki/search.html");
|
||||
});
|
||||
|
||||
test("In-app-help works in English", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
|
||||
await app.currentNoteSplit.press("F1");
|
||||
const title = "User Guide";
|
||||
await expect(app.noteTreeHoistedNote).toContainText(title);
|
||||
await expect(app.currentNoteSplitTitle).toHaveValue(title);
|
||||
|
||||
app.noteTree.getByText("Troubleshooting").click();
|
||||
await expect(app.currentNoteSplitTitle).toHaveValue("Troubleshooting");
|
||||
await app.currentNoteSplitContent.locator("p").first().waitFor({ state: "visible" });
|
||||
expect(await app.currentNoteSplitContent.locator("p").count()).toBeGreaterThan(10);
|
||||
});
|
||||
|
||||
test("In-app-help works in other languages", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
try {
|
||||
await app.goto();
|
||||
await app.setOption("locale", "cn");
|
||||
await app.goto();
|
||||
|
||||
await app.currentNoteSplit.press("F1");
|
||||
const title = "用户指南";
|
||||
await expect(app.noteTreeHoistedNote).toContainText(title);
|
||||
await expect(app.currentNoteSplitTitle).toHaveValue(title);
|
||||
|
||||
app.noteTree.getByText("Troubleshooting").click();
|
||||
await expect(app.currentNoteSplitTitle).toHaveValue("Troubleshooting");
|
||||
await app.currentNoteSplitContent.locator("p").first().waitFor({ state: "visible" });
|
||||
expect(await app.currentNoteSplitContent.locator("p").count()).toBeGreaterThan(10);
|
||||
} finally {
|
||||
// Ensure English is set after each locale change to avoid any leaks to other tests.
|
||||
await app.setOption("locale", "en");
|
||||
}
|
||||
});
|
||||
|
@ -57,3 +57,46 @@ test("Can drag tab to new window", async ({ page, context }) => {
|
||||
const popupApp = new App(popup, context);
|
||||
await expect(popupApp.getActiveTab()).toHaveText(NOTE_TITLE);
|
||||
});
|
||||
|
||||
test("Tabs are restored in right order", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
|
||||
// Open three tabs.
|
||||
await app.closeAllTabs();
|
||||
await app.goToNoteInNewTab("Code notes");
|
||||
await app.addNewTab();
|
||||
await app.goToNoteInNewTab("Text notes");
|
||||
await app.addNewTab();
|
||||
await app.goToNoteInNewTab("Mermaid");
|
||||
|
||||
// Select the mid one.
|
||||
await app.getTab(1).click();
|
||||
|
||||
// Refresh the page and check the order.
|
||||
await app.goto( { preserveTabs: true });
|
||||
await expect(app.getTab(0)).toContainText("Code notes");
|
||||
await expect(app.getTab(1)).toContainText("Text notes");
|
||||
await expect(app.getTab(2)).toContainText("Mermaid");
|
||||
|
||||
// Check the note tree has the right active node.
|
||||
await expect(app.noteTreeActiveNote).toContainText("Text notes");
|
||||
});
|
||||
|
||||
test("Empty tabs are cleared out", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
|
||||
// Open three tabs.
|
||||
await app.closeAllTabs();
|
||||
await app.addNewTab();
|
||||
await app.goToNoteInNewTab("Code notes");
|
||||
await app.addNewTab();
|
||||
await app.addNewTab();
|
||||
|
||||
// Refresh the page and check the order.
|
||||
await app.goto({ preserveTabs: true });
|
||||
|
||||
// Expect no empty tabs.
|
||||
expect(await app.tabBar.locator(".note-tab-wrapper").count()).toBe(1);
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import type { BrowserContext } from "@playwright/test";
|
||||
interface GotoOpts {
|
||||
url?: string;
|
||||
isMobile?: boolean;
|
||||
preserveTabs?: boolean;
|
||||
}
|
||||
|
||||
const BASE_URL = "http://127.0.0.1:8082";
|
||||
@ -14,8 +15,12 @@ export default class App {
|
||||
|
||||
readonly tabBar: Locator;
|
||||
readonly noteTree: Locator;
|
||||
readonly noteTreeActiveNote: Locator;
|
||||
readonly noteTreeHoistedNote: Locator;
|
||||
readonly launcherBar: Locator;
|
||||
readonly currentNoteSplit: Locator;
|
||||
readonly currentNoteSplitTitle: Locator;
|
||||
readonly currentNoteSplitContent: Locator;
|
||||
readonly sidebar: Locator;
|
||||
|
||||
constructor(page: Page, context: BrowserContext) {
|
||||
@ -24,12 +29,16 @@ export default class App {
|
||||
|
||||
this.tabBar = page.locator(".tab-row-widget-container");
|
||||
this.noteTree = page.locator(".tree-wrapper");
|
||||
this.noteTreeActiveNote = this.noteTree.locator(".fancytree-node.fancytree-active");
|
||||
this.noteTreeHoistedNote = this.noteTree.locator(".fancytree-node", { has: page.locator(".unhoist-button") });
|
||||
this.launcherBar = page.locator("#launcher-container");
|
||||
this.currentNoteSplit = page.locator(".note-split:not(.hidden-ext)");
|
||||
this.currentNoteSplitTitle = this.currentNoteSplit.locator(".note-title");
|
||||
this.currentNoteSplitContent = this.currentNoteSplit.locator(".note-detail-printable.visible");
|
||||
this.sidebar = page.locator("#right-pane");
|
||||
}
|
||||
|
||||
async goto({ url, isMobile }: GotoOpts = {}) {
|
||||
async goto({ url, isMobile, preserveTabs }: GotoOpts = {}) {
|
||||
await this.context.addCookies([
|
||||
{
|
||||
url: BASE_URL,
|
||||
@ -47,7 +56,9 @@ export default class App {
|
||||
// Wait for the page to load.
|
||||
if (url === "/") {
|
||||
await expect(this.page.locator(".tree")).toContainText("Trilium Integration Test");
|
||||
await this.closeAllTabs();
|
||||
if (!preserveTabs) {
|
||||
await this.closeAllTabs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { initializeTranslations } from "./src/services/i18n.js";
|
||||
import archiver, { type Archiver } from "archiver";
|
||||
import type { WriteStream } from "fs";
|
||||
import debounce from "./src/public/app/services/debounce.js";
|
||||
import { extractZip, importData, initializeDatabase, startElectron } from "./electron-utils.js";
|
||||
import { extractZip, initializeDatabase, startElectron } from "./electron-utils.js";
|
||||
|
||||
const NOTE_ID_USER_GUIDE = "pOsGYCXsbNQG";
|
||||
const markdownPath = path.join("docs", "User Guide");
|
||||
@ -16,8 +16,7 @@ const htmlPath = path.join("src", "public", "app", "doc_notes", "en", "User Guid
|
||||
async function main() {
|
||||
await initializeTranslations();
|
||||
const zipBuffer = await createImportZip();
|
||||
await initializeDatabase();
|
||||
await importData(zipBuffer, NOTE_ID_USER_GUIDE, "User Guide", "The sub-children of this note are automatically synced.");
|
||||
await initializeDatabase(zipBuffer);
|
||||
await startElectron();
|
||||
await registerHandlers();
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ import fs from "fs/promises";
|
||||
import fsExtra from "fs-extra";
|
||||
import path from "path";
|
||||
|
||||
export async function initializeDatabase() {
|
||||
export async function initializeDatabase(customDbBuffer?: Buffer) {
|
||||
const sqlInit = (await import("./src/services/sql_init.js")).default;
|
||||
|
||||
cls.init(() => {
|
||||
if (!sqlInit.isDbInitialized()) {
|
||||
sqlInit.createInitialDatabase(true);
|
||||
sqlInit.createInitialDatabase(true, customDbBuffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -17,48 +17,6 @@ export async function startElectron() {
|
||||
await import("./electron-main.js");
|
||||
}
|
||||
|
||||
export function importData(input: Buffer, rootId: string, rootTitle: string, rootContent: string) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
cls.init(async () => {
|
||||
const beccaLoader = ((await import("./src/becca/becca_loader.js")).default);
|
||||
const notes = ((await import("./src/services/notes.js")).default);
|
||||
beccaLoader.load();
|
||||
const becca = ((await import("./src/becca/becca.js")).default);
|
||||
const utils = ((await import("./src/services/utils.js")).default);
|
||||
const eraseService = ((await import("./src/services/erase.js")).default);
|
||||
const deleteId = utils.randomString(10);
|
||||
|
||||
const existingNote = becca.getNote(rootId);
|
||||
if (existingNote) {
|
||||
existingNote.deleteNote(deleteId);
|
||||
}
|
||||
eraseService.eraseNotesWithDeleteId(deleteId);
|
||||
|
||||
const { note } = notes.createNewNoteWithTarget("into", "none_root", {
|
||||
parentNoteId: "root",
|
||||
noteId: rootId,
|
||||
title: rootTitle,
|
||||
content: rootContent,
|
||||
type: "text"
|
||||
});
|
||||
|
||||
const TaskContext = (await import("./src/services/task_context.js")).default;
|
||||
const { importZip } = ((await import("./src/services/import/zip.js")).default);
|
||||
const context = new TaskContext("no-report");
|
||||
await importZip(context, input, note, { preserveIds: true });
|
||||
|
||||
const { runOnDemandChecks } = (await import("./src/services/consistency_checks.js")).default;
|
||||
await runOnDemandChecks(true);
|
||||
|
||||
becca.reset();
|
||||
beccaLoader.load();
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export async function extractZip(zipFilePath: string, outputPath: string) {
|
||||
const deferred = (await import("./src/services/utils.js")).deferred;
|
||||
|
||||
|
@ -24,10 +24,11 @@ export default tseslint.config(
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"argsIgnorePattern": "^_",
|
||||
"varsIgnorePattern": "^_",
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_"
|
||||
}
|
||||
]
|
||||
],
|
||||
"sort-imports": [ "error", { ignoreCase: false } ]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -35,6 +36,7 @@ export default tseslint.config(
|
||||
"build/*",
|
||||
"dist/*",
|
||||
"docs/*",
|
||||
"demo/*",
|
||||
"libraries/*",
|
||||
"src/public/app-dist/*",
|
||||
"src/public/app/doc_notes/*"
|
||||
|
48
eslint.format.config.js
Normal file
48
eslint.format.config.js
Normal file
@ -0,0 +1,48 @@
|
||||
import stylistic from "@stylistic/eslint-plugin";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
|
||||
// eslint config just for formatting rules
|
||||
// potentially to be merged with the linting rules into one single config,
|
||||
// once we have fixed the majority of lint errors
|
||||
|
||||
// Go to https://eslint.style/rules/default/${rule_without_prefix} to check the rule details
|
||||
export const stylisticRules = {
|
||||
"@stylistic/indent": [ "error", 4 ],
|
||||
"@stylistic/quotes": [ "error", "double", { avoidEscape: true, allowTemplateLiterals: "always" } ],
|
||||
"@stylistic/semi": [ "error", "always" ],
|
||||
"@stylistic/quote-props": [ "error", "consistent-as-needed" ],
|
||||
"@stylistic/max-len": [ "error", { code: 100 } ],
|
||||
"@stylistic/comma-dangle": [ "error", "never" ],
|
||||
"@stylistic/linebreak-style": [ "error", "unix" ],
|
||||
"@stylistic/array-bracket-spacing": [ "error", "always" ],
|
||||
"@stylistic/object-curly-spacing": [ "error", "always" ],
|
||||
"@stylistic/padded-blocks": [ "error", { classes: "always" } ]
|
||||
};
|
||||
|
||||
export default [
|
||||
{
|
||||
files: [ "**/*.{js,ts,mjs,cjs}" ],
|
||||
languageOptions: {
|
||||
parser: tsParser
|
||||
},
|
||||
plugins: {
|
||||
"@stylistic": stylistic
|
||||
},
|
||||
rules: {
|
||||
...stylisticRules
|
||||
}
|
||||
},
|
||||
{
|
||||
ignores: [
|
||||
"build/*",
|
||||
"dist/*",
|
||||
"docs/*",
|
||||
"demo/*",
|
||||
"libraries/*",
|
||||
// TriliumNextTODO: check if we want to format packages here as well - for now skipping it
|
||||
"packages/*",
|
||||
"src/public/app-dist/*",
|
||||
"src/public/app/doc_notes/*"
|
||||
]
|
||||
}
|
||||
];
|
176
package-lock.json
generated
176
package-lock.json
generated
@ -117,6 +117,7 @@
|
||||
"@mind-elixir/node-menu": "1.0.5",
|
||||
"@playwright/test": "1.51.1",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@stylistic/eslint-plugin": "4.2.0",
|
||||
"@types/archiver": "6.0.3",
|
||||
"@types/better-sqlite3": "7.6.12",
|
||||
"@types/bootstrap": "5.2.10",
|
||||
@ -201,8 +202,7 @@
|
||||
"webpack-dev-middleware": "7.4.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"appdmg": "0.6.6",
|
||||
"dprint": "0.49.1"
|
||||
"appdmg": "0.6.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
@ -574,123 +574,6 @@
|
||||
"node": ">=14.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@dprint/darwin-arm64": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.49.1.tgz",
|
||||
"integrity": "sha512-ib6KcJWo/M5RJWXOQKhP664FG1hAvG7nrbkh+j8n+oXdzmbyDdXTP+zW+aM3/sIQUkGaZky1xy1j2VeScMEEHQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@dprint/darwin-x64": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.49.1.tgz",
|
||||
"integrity": "sha512-vIVgnYxV7YYa1d6Uyz707RbgB9rwefGPam+rzaueFNPQjdOxPOTQDuMEJDS+Z3BlI00MfeoupIfIUGsXoM4dpQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@dprint/linux-arm64-glibc": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.49.1.tgz",
|
||||
"integrity": "sha512-ZeIh6qMPWLBBifDtU0XadpK36b4WoaTqCOt0rWKfoTjq1RAt78EgqETWp43Dbr6et/HvTgYdoWF0ZNEu2FJFFA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@dprint/linux-arm64-musl": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.49.1.tgz",
|
||||
"integrity": "sha512-/nuRyx+TykN6MqhlSCRs/t3o1XXlikiwTc9emWdzMeLGllYvJrcht9gRJ1/q1SqwCFhzgnD9H7roxxfji1tc+Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@dprint/linux-riscv64-glibc": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/linux-riscv64-glibc/-/linux-riscv64-glibc-0.49.1.tgz",
|
||||
"integrity": "sha512-RHBqrnvGO+xW4Oh0QuToBqWtkXMcfjqa1TqbBFF03yopFzZA2oRKX83PhjTWgd/IglaOns0BgmaLJy/JBSxOfQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@dprint/linux-x64-glibc": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.49.1.tgz",
|
||||
"integrity": "sha512-MjFE894mIQXOKBencuakKyzAI4KcDe/p0Y9lRp9YSw/FneR4QWH9VBH90h8fRxcIlWMArjFFJJAtsBnn5qgxeg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@dprint/linux-x64-musl": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.49.1.tgz",
|
||||
"integrity": "sha512-CvGBWOksHgrL1uzYqtPFvZz0+E82BzgoCIEHJeuYaveEn37qWZS5jqoCm/vz6BfoivE1dVuyyOT78Begj9KxkQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@dprint/win32-arm64": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/win32-arm64/-/win32-arm64-0.49.1.tgz",
|
||||
"integrity": "sha512-gQa4s82lMcXjfdxjWBQun6IJlXdPZZaIj2/2cqXWVEOYPKxAZ/JvGzt2pPG+i73h9KHjNLIV8M9ckqEH3oHufg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@dprint/win32-x64": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.49.1.tgz",
|
||||
"integrity": "sha512-nPU6+hoVze5JJlgET7woYWElBw0IUaB/9XKTaglknQuUUfsmD75D9pkgJTxdIxl9Bg/i5O7c9wb3Nj4XNiTIfw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@electron-forge/cli": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.8.0.tgz",
|
||||
@ -4554,6 +4437,39 @@
|
||||
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@stylistic/eslint-plugin": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.2.0.tgz",
|
||||
"integrity": "sha512-8hXezgz7jexGHdo5WN6JBEIPHCSFyyU4vgbxevu4YLVS5vl+sxqAAGyXSzfNDyR6xMNSH5H1x67nsXcYMOHtZA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/utils": "^8.23.0",
|
||||
"eslint-visitor-keys": "^4.2.0",
|
||||
"espree": "^10.3.0",
|
||||
"estraverse": "^5.3.0",
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@stylistic/eslint-plugin/node_modules/picomatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/@szmarczak/http-timer": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
|
||||
@ -9507,28 +9423,6 @@
|
||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dprint": {
|
||||
"version": "0.49.1",
|
||||
"resolved": "https://registry.npmjs.org/dprint/-/dprint-0.49.1.tgz",
|
||||
"integrity": "sha512-pO9XH79SyXybj2Vhc9ITZMEI8cJkdlQQRoD8oEfPH6Jjpp/7WX5kIgECVd3DBOjjAdCSiW6R47v3gJBx/qZVkw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"dprint": "bin.js"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@dprint/darwin-arm64": "0.49.1",
|
||||
"@dprint/darwin-x64": "0.49.1",
|
||||
"@dprint/linux-arm64-glibc": "0.49.1",
|
||||
"@dprint/linux-arm64-musl": "0.49.1",
|
||||
"@dprint/linux-riscv64-glibc": "0.49.1",
|
||||
"@dprint/linux-x64-glibc": "0.49.1",
|
||||
"@dprint/linux-x64-musl": "0.49.1",
|
||||
"@dprint/win32-arm64": "0.49.1",
|
||||
"@dprint/win32-x64": "0.49.1"
|
||||
}
|
||||
},
|
||||
"node_modules/draggabilly": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/draggabilly/-/draggabilly-3.0.0.tgz",
|
||||
|
12
package.json
12
package.json
@ -36,8 +36,8 @@
|
||||
"electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
|
||||
"electron:qstart": "npm run electron:switch && npm run electron:start",
|
||||
"electron:switch": "electron-rebuild",
|
||||
"docs:edit": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-docs TRILIUM_ENV=dev TRILIUM_PORT=37741 electron ./electron-docs-main.ts .",
|
||||
"docs:edit-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-docs TRILIUM_PORT=37741 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-docs-main.ts .\"",
|
||||
"docs:edit": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-docs TRILIUM_ENV=dev TRILIUM_INTEGRATION_TEST=memory-no-store TRILIUM_PORT=37741 electron ./electron-docs-main.ts .",
|
||||
"docs:edit-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-docs TRILIUM_PORT=37741 TRILIUM_ENV=dev TRILIUM_INTEGRATION_TEST=memory-no-store nix-shell -p electron_33 --run \"electron ./electron-docs-main.ts .\"",
|
||||
"demo:edit": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-demo TRILIUM_ENV=dev TRILIUM_INTEGRATION_TEST=memory-no-store TRILIUM_PORT=37741 electron ./electron-edit-demo.ts .",
|
||||
"electron-forge:start": "npm run build:prepare-dist && cd ./build && electron-forge start",
|
||||
"electron-forge:make": "npm run build:prepare-dist && cross-env DEBUG=electron-windows-installer:* electron-forge make ./build",
|
||||
@ -59,8 +59,8 @@
|
||||
"test:integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||
"test:integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||
"dev:watch-dist": "tsx ./bin/watch-dist.ts",
|
||||
"dev:format-check": "dprint check",
|
||||
"dev:format-fix": "dprint fmt",
|
||||
"dev:format-check": "eslint -c eslint.format.config.js .",
|
||||
"dev:format-fix": "eslint -c eslint.format.config.js . --fix",
|
||||
"dev:linter-check": "eslint .",
|
||||
"dev:linter-fix": "eslint . --fix",
|
||||
"chore:update-build-info": "tsx bin/update-build-info.ts",
|
||||
@ -174,6 +174,7 @@
|
||||
"@mind-elixir/node-menu": "1.0.5",
|
||||
"@playwright/test": "1.51.1",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@stylistic/eslint-plugin": "4.2.0",
|
||||
"@types/archiver": "6.0.3",
|
||||
"@types/better-sqlite3": "7.6.12",
|
||||
"@types/bootstrap": "5.2.10",
|
||||
@ -258,7 +259,6 @@
|
||||
"webpack-dev-middleware": "7.4.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"appdmg": "0.6.6",
|
||||
"dprint": "0.49.1"
|
||||
"appdmg": "0.6.6"
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ export default class TabManager extends Component {
|
||||
|
||||
const filteredNoteContexts = noteContextsToOpen.filter((openTab: NoteContextState) => {
|
||||
const noteId = treeService.getNoteIdFromUrl(openTab.notePath);
|
||||
if (noteId && !(noteId in froca.notes)) {
|
||||
if (!noteId || !(noteId in froca.notes)) {
|
||||
// note doesn't exist so don't try to open tab for it
|
||||
return false;
|
||||
}
|
||||
|
@ -14,8 +14,10 @@ export default function renderDoc(note: FNote) {
|
||||
// fallback to english doc if no translation available
|
||||
if (status === "error") {
|
||||
const fallbackUrl = getUrl(docName, "en");
|
||||
$content.load(fallbackUrl, () => processContent(fallbackUrl, $content));
|
||||
resolve($content);
|
||||
$content.load(fallbackUrl, () => {
|
||||
processContent(fallbackUrl, $content)
|
||||
resolve($content);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import "../stylesheets/bootstrap.scss";
|
||||
import "../stylesheets/auth.css";
|
||||
|
||||
// @TriliumNextTODO: is this even needed anymore?
|
||||
// @ts-ignore - module = undefined
|
||||
|
@ -11,6 +11,7 @@ const TPL = /*html*/`
|
||||
.global-menu {
|
||||
width: 53px;
|
||||
height: 53px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.global-menu .dropdown-menu {
|
||||
|
@ -11,7 +11,19 @@ export default class LauncherContainer extends FlexContainer<LauncherWidget> {
|
||||
super(isHorizontalLayout ? "row" : "column");
|
||||
|
||||
this.id("launcher-container");
|
||||
this.css(isHorizontalLayout ? "width" : "height", "100%");
|
||||
|
||||
if (isHorizontalLayout) {
|
||||
this.css("width", "100%");
|
||||
this.css("height", "100%");
|
||||
this.css("overflow-x", "auto");
|
||||
this.css("overflow-y", "hidden");
|
||||
} else {
|
||||
this.css("height", "100%");
|
||||
this.css("overflow-x", "hidden");
|
||||
this.css("overflow-y", "auto");
|
||||
}
|
||||
|
||||
this.css("scrollbar-gutter", "stable both-edges");
|
||||
this.filling();
|
||||
this.isHorizontalLayout = isHorizontalLayout;
|
||||
|
||||
|
@ -16,7 +16,7 @@ const TPL = /*html*/`
|
||||
<form class="protected-session-password-form">
|
||||
<div class="modal-body">
|
||||
<label for="protected-session-password" class="col-form-label">${t("protected_session_password.form_label")}</label>
|
||||
<input id="protected-session-password" class="form-control protected-session-password" type="password">
|
||||
<input id="protected-session-password" class="form-control protected-session-password" type="password" autocomplete="current-password">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary">${t("protected_session_password.start_button")}</button>
|
||||
|
@ -82,7 +82,6 @@ class NoteContextAwareWidget extends BasicWidget {
|
||||
async refreshWithNote(note: FNote | null | undefined) {}
|
||||
|
||||
async noteSwitchedEvent({ noteContext, notePath }: EventData<"noteSwitched">) {
|
||||
this.noteContext = noteContext;
|
||||
// if notePath does not match, then the noteContext has been switched to another note in the meantime
|
||||
if (noteContext.notePath === notePath) {
|
||||
await this.noteSwitched();
|
||||
|
@ -20,7 +20,7 @@ const TPL = /*html*/`
|
||||
<form class="protected-session-password-form">
|
||||
<div class="form-group">
|
||||
<label for="protected-session-password-in-detail">${t("protected_session.enter_password_instruction")}</label>
|
||||
<input id="protected-session-password-in-detail" class="form-control protected-session-password" type="password" autofocus>
|
||||
<input id="protected-session-password-in-detail" class="form-control protected-session-password" type="password" autofocus autocomplete="current-password">
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary">${t("protected_session.start_session_button")}</button>
|
||||
|
3
src/public/stylesheets/auth.css
Normal file
3
src/public/stylesheets/auth.css
Normal file
@ -0,0 +1,3 @@
|
||||
.set-password .form-group {
|
||||
margin-bottom: 1rem;
|
||||
}
|
@ -1177,6 +1177,10 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
|
||||
left: calc(-100% + 10px);
|
||||
}
|
||||
|
||||
.right-dropdown-widget {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#launcher-pane.horizontal .right-dropdown-widget {
|
||||
width: 53px;
|
||||
}
|
||||
@ -1288,6 +1292,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
|
||||
border: none;
|
||||
color: var(--launcher-pane-text-color);
|
||||
background-color: var(--launcher-pane-background-color);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#launcher-pane.vertical .launcher-button {
|
||||
@ -1302,6 +1307,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
|
||||
|
||||
#launcher-pane.horizontal .quick-search {
|
||||
width: 350px;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
#launcher-pane .icon-action:hover {
|
||||
|
@ -7,7 +7,7 @@ function setRecoveryCodes(req: Request) {
|
||||
return { success: success, message: 'Recovery codes set!' };
|
||||
}
|
||||
|
||||
function veryifyRecoveryCode(req: Request) {
|
||||
function verifyRecoveryCode(req: Request) {
|
||||
const success = recovery_codes.verifyRecoveryCode(req.body.recovery_code_guess);
|
||||
|
||||
return { success: success };
|
||||
@ -59,7 +59,7 @@ function getUsedRecoveryCodes() {
|
||||
export default {
|
||||
setRecoveryCodes,
|
||||
generateRecoveryCodes,
|
||||
veryifyRecoveryCode,
|
||||
verifyRecoveryCode,
|
||||
checkForRecoveryKeys,
|
||||
getUsedRecoveryCodes
|
||||
};
|
@ -124,7 +124,7 @@ function register(app: express.Application) {
|
||||
apiRoute(GET, '/api/oauth/validate', openID.isTokenValid);
|
||||
|
||||
apiRoute(PST, '/api/totp_recovery/set', recoveryCodes.setRecoveryCodes);
|
||||
apiRoute(PST, '/api/totp_recovery/verify', recoveryCodes.veryifyRecoveryCode);
|
||||
apiRoute(PST, '/api/totp_recovery/verify', recoveryCodes.verifyRecoveryCode);
|
||||
apiRoute(GET, '/api/totp_recovery/generate', recoveryCodes.generateRecoveryCodes);
|
||||
apiRoute(GET, '/api/totp_recovery/enabled', recoveryCodes.checkForRecoveryKeys);
|
||||
apiRoute(GET, '/api/totp_recovery/used', recoveryCodes.getUsedRecoveryCodes);
|
||||
|
@ -127,4 +127,10 @@ second line 2</code></pre><ul><li>Hello</li><li>world</li></ul><ol><li>Hello</li
|
||||
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
it("does not escape unneeded characters", () => {
|
||||
const input = `It's important to note that these examples are not natively supported by Trilium out of the box; instead, they demonstrate what you can build within Trilium.`;
|
||||
const expected = `<p>It's important to note that these examples are not natively supported by Trilium out of the box; instead, they demonstrate what you can build within Trilium.</p>`;
|
||||
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -82,7 +82,7 @@ function renderToHtml(content: string, title: string) {
|
||||
|
||||
// h1 handling needs to come before sanitization
|
||||
html = importUtils.handleH1(html, title);
|
||||
// html = htmlSanitizer.sanitize(html);
|
||||
html = htmlSanitizer.sanitize(html);
|
||||
|
||||
// Remove slash for self-closing tags to match CKEditor's approach.
|
||||
html = html.replace(/<(\w+)([^>]*)\s+\/>/g, "<$1$2>");
|
||||
|
@ -64,13 +64,19 @@ async function initDbConnection() {
|
||||
dbReady.resolve();
|
||||
}
|
||||
|
||||
async function createInitialDatabase(preserveIds?: boolean) {
|
||||
/**
|
||||
* Applies the database schema, creating the necessary tables and importing the demo content.
|
||||
*
|
||||
* @param preserveIds `true` if the note IDs from the meta file should be preserved, or `false` to generate new ones (normal behaviour).
|
||||
* @param customDbBuffer a custom database buffer to use, otherwise the default demo one is going to be used.
|
||||
*/
|
||||
async function createInitialDatabase(preserveIds?: boolean, customDbBuffer?: Buffer) {
|
||||
if (isDbInitialized()) {
|
||||
throw new Error("DB is already initialized");
|
||||
}
|
||||
|
||||
const schema = fs.readFileSync(`${resourceDir.DB_INIT_DIR}/schema.sql`, "utf-8");
|
||||
const demoFile = fs.readFileSync(`${resourceDir.DB_INIT_DIR}/demo.zip`);
|
||||
const demoFile = customDbBuffer ?? fs.readFileSync(`${resourceDir.DB_INIT_DIR}/demo.zip`);
|
||||
|
||||
let rootNote!: BNote;
|
||||
|
||||
|
@ -3,8 +3,8 @@ import options from './options.js';
|
||||
import totpEncryptionService from './encryption/totp_encryption.js';
|
||||
|
||||
function isTotpEnabled(): boolean {
|
||||
return options.getOption('mfaEnabled') === "true" &&
|
||||
options.getOption('mfaMethod') === "totp" &&
|
||||
return options.getOptionOrNull('mfaEnabled') === "true" &&
|
||||
options.getOptionOrNull('mfaMethod') === "totp" &&
|
||||
totpEncryptionService.isTotpSecretSet();
|
||||
}
|
||||
|
||||
|
@ -156,6 +156,8 @@ async function createMainWindow(app: App) {
|
||||
y: mainWindowState.y,
|
||||
width: mainWindowState.width,
|
||||
height: mainWindowState.height,
|
||||
minWidth: 500,
|
||||
minHeight: 400,
|
||||
title: "TriliumNext Notes",
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
@ -255,9 +257,12 @@ function getIcon() {
|
||||
|
||||
async function createSetupWindow() {
|
||||
const { BrowserWindow } = await import("electron"); // should not be statically imported
|
||||
const width = 750;
|
||||
const height = 650;
|
||||
setupWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 800,
|
||||
width,
|
||||
height,
|
||||
resizable: false,
|
||||
title: "TriliumNext Notes Setup",
|
||||
icon: getIcon(),
|
||||
webPreferences: {
|
||||
|
@ -34,14 +34,14 @@
|
||||
<div class="form-group">
|
||||
<label for="password"><%= t("login.password") %></label>
|
||||
<div class="controls">
|
||||
<input id="password" name="password" placeholder="" class="form-control" type="password" autofocus>
|
||||
<input id="password" name="password" placeholder="" class="form-control" type="password" autocomplete="current-password" autofocus>
|
||||
</div>
|
||||
</div>
|
||||
<% if( totpEnabled ) { %>
|
||||
<div class="form-group">
|
||||
<label for="totpToken">TOTP Token</label>
|
||||
<div class="controls">
|
||||
<input id="totpToken" name="totpToken" placeholder="" class="form-control" type="text" required />
|
||||
<input id="totpToken" name="totpToken" placeholder="" class="form-control" type="text" autocomplete="one-time-code" required />
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<link rel="stylesheet" href="<%= assetPath %>/stylesheets/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="container set-password">
|
||||
<div class="col-xs-12 col-sm-10 col-md-6 col-lg-4 col-xl-4 mx-auto pt-4">
|
||||
<h1><%= t("set_password.heading") %></h1>
|
||||
|
||||
@ -29,13 +29,13 @@
|
||||
<div class="form-group">
|
||||
<label for="password1"><%= t("set_password.password") %></label>
|
||||
<div class="controls">
|
||||
<input id="password1" name="password1" placeholder="" class="form-control" type="password">
|
||||
<input id="password1" name="password1" placeholder="" class="form-control" type="password" autocomplete="new-password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password2"><%= t("set_password.password-confirmation") %></label>
|
||||
<div class="controls">
|
||||
<input id="password2" name="password2" placeholder="" class="form-control" type="password">
|
||||
<input id="password2" name="password2" placeholder="" class="form-control" type="password" autocomplete="new-password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
"esModuleInterop": true,
|
||||
"verbatimModuleSyntax": true
|
||||
},
|
||||
"include": ["./src/**/*.js", "./src/**/*.ts", "./*.ts", "./spec/**/*.ts"],
|
||||
"include": ["./src/**/*.js", "./src/**/*.ts", "./*.ts", "./*.js", "./spec/**/*.ts"],
|
||||
"exclude": ["./node_modules/**/*", "./spec-es6/**/*.ts"],
|
||||
"files": ["src/types.d.ts", "src/public/app/types.d.ts"]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user