Merge remote-tracking branch 'upstream-next/develop' into feature/i18n-part2

This commit is contained in:
Nriver 2024-08-15 11:04:14 +08:00
commit cc98ae0ea4
15 changed files with 91 additions and 14 deletions

Binary file not shown.

View File

@ -0,0 +1,18 @@
import test, { expect } from "@playwright/test";
test("Renders on desktop", async ({ page, context }) => {
await page.goto('http://localhost:8082');
await expect(page.locator('.tree')).toContainText('Trilium Integration Test');
});
test("Renders on mobile", async ({ page, context }) => {
await context.addCookies([
{
url: "http://localhost:8082",
name: "trilium-device",
value: "mobile"
}
]);
await page.goto('http://localhost:8082');
await expect(page.locator('.tree')).toContainText('Trilium Integration Test');
});

View File

@ -4,6 +4,10 @@
display: none;
}
.ck-content li p {
margin: 0 !important;
}
/*
* CKEditor 5 (v41.0.0) content styles.
* Generated on Fri, 26 Jan 2024 10:23:49 GMT.

View File

@ -31,6 +31,14 @@ export default defineConfig({
trace: 'on-first-retry',
},
webServer: {
command: "npm run integration-mem-db",
url: "http://127.0.0.1:8082",
reuseExistingServer: true,
stdout: "ignore",
stderr: "pipe"
},
/* Configure projects for major browsers */
projects: [
{

View File

@ -11,7 +11,6 @@ export async function initLocale() {
.init({
lng: locale,
fallbackLng: "en",
debug: true,
backend: {
loadPath: `/${window.glob.assetPath}/translations/{{lng}}/{{ns}}.json`
}

View File

@ -135,7 +135,11 @@ function ajax(url, method, data, headers, silentNotFound) {
});
},
error: async jqXhr => {
if (silentNotFound && jqXhr.status === 404) {
if (jqXhr.status === 0) {
// don't report requests that are rejected by the browser, usually when the user is refreshing or going to a different page.
rej("rejected by browser");
return;
} else if (silentNotFound && jqXhr.status === 404) {
// report nothing
} else {
await reportError(method, url, jqXhr.status, jqXhr.responseText);

View File

@ -57,7 +57,17 @@ class NoteContextAwareWidget extends BasicWidget {
async refresh() {
if (this.isEnabled()) {
this.toggleInt(true);
await this.refreshWithNote(this.note);
try {
await this.refreshWithNote(this.note);
} catch (e) {
// Ignore errors when user is refreshing or navigating away.
if (e === "rejected by browser") {
return;
}
throw e;
}
}
else {
this.toggleInt(false);

View File

@ -199,7 +199,7 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget {
this.$actionList.append(
$('<a class="dropdown-item" href="#">')
.attr('data-action-add', action.actionName)
.text(t(`${action.actionTitle}`))
.text(action.actionTitle)
);
}
}

View File

@ -29,6 +29,8 @@ export default class LocalizationOptions extends OptionsWidget {
async optionsLoaded(options) {
const availableLocales = await server.get("options/locales");
this.$localeSelect.empty();
for (const locale of availableLocales) {
this.$localeSelect.append($("<option>")
.attr("value", locale.id)

View File

@ -623,6 +623,10 @@ div[data-notify="container"] {
background-color: var(--accented-background-color) !important;
}
.ck-content li p {
margin: 0 !important;
}
#options-dialog input[type=number] {
text-align: right;
}

View File

@ -7,6 +7,8 @@ import anonymizationService from "../../services/anonymization.js";
import consistencyChecksService from "../../services/consistency_checks.js";
import { Request } from 'express';
import ValidationError from "../../errors/validation_error.js";
import sql_init from "../../services/sql_init.js";
import becca_loader from "../../becca/becca_loader.js";
function getExistingBackups() {
return backupService.getExistingBackups();
@ -28,6 +30,12 @@ function findAndFixConsistencyIssues() {
consistencyChecksService.runOnDemandChecks(true);
}
async function rebuildIntegrationTestDatabase() {
sql.rebuildIntegrationTestDatabase();
sql_init.initializeDb();
becca_loader.load();
}
function getExistingAnonymizedDatabases() {
return anonymizationService.getExistingAnonymizedDatabases();
}
@ -54,6 +62,7 @@ export default {
backupDatabase,
vacuumDatabase,
findAndFixConsistencyIssues,
rebuildIntegrationTestDatabase,
getExistingAnonymizedDatabases,
anonymize,
checkIntegrity

View File

@ -23,6 +23,11 @@ function index(req: Request, res: Response) {
const csrfToken = req.csrfToken();
log.info(`Generated CSRF token ${csrfToken} with secret ${res.getHeader('set-cookie')}`);
// We force the page to not be cached since on mobile the CSRF token can be
// broken when closing the browser and coming back in to the page.
// The page is restored from cache, but the API call fail.
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
res.render(view, {
csrfToken: csrfToken,
themeCssUrl: getThemeCssUrl(options.theme),

View File

@ -299,6 +299,10 @@ function register(app: express.Application) {
route(PST, '/api/database/anonymize/:type', [auth.checkApiAuthOrElectron, csrfMiddleware], databaseRoute.anonymize, apiResultHandler, false);
apiRoute(GET, '/api/database/anonymized-databases', databaseRoute.getExistingAnonymizedDatabases);
if (process.env.TRILIUM_INTEGRATION_TEST === "memory") {
route(PST, '/api/database/rebuild/', [auth.checkApiAuthOrElectron], databaseRoute.rebuildIntegrationTestDatabase, apiResultHandler, false);
}
// backup requires execution outside of transaction
route(PST, '/api/database/backup-database', [auth.checkApiAuthOrElectron, csrfMiddleware], databaseRoute.backupDatabase, apiResultHandler, false);
apiRoute(GET, '/api/database/backups', databaseRoute.getExistingBackups);

View File

@ -14,17 +14,28 @@ import ws from "./ws.js";
import becca_loader from "../becca/becca_loader.js";
import entity_changes from "./entity_changes.js";
function buildDatabase(path: string) {
let dbConnection: DatabaseType = buildDatabase();
let statementCache: Record<string, Statement> = {};
function buildDatabase() {
if (process.env.TRILIUM_INTEGRATION_TEST === "memory") {
// This allows a database that is read normally but is kept in memory and discards all modifications.
const dbBuffer = fs.readFileSync(path);
return new Database(dbBuffer);
return buildIntegrationTestDatabase();
}
return new Database(dataDir.DOCUMENT_PATH);
}
const dbConnection: DatabaseType = buildDatabase(dataDir.DOCUMENT_PATH);
function buildIntegrationTestDatabase() {
const dbBuffer = fs.readFileSync(dataDir.DOCUMENT_PATH);
return new Database(dbBuffer);
}
function rebuildIntegrationTestDatabase() {
// This allows a database that is read normally but is kept in memory and discards all modifications.
dbConnection = buildIntegrationTestDatabase();
statementCache = {};
}
if (!process.env.TRILIUM_INTEGRATION_TEST) {
dbConnection.pragma('journal_mode = WAL');
@ -96,8 +107,6 @@ function upsert<T extends {}>(tableName: string, primaryKey: string, rec: T) {
execute(query, rec);
}
const statementCache: Record<string, Statement> = {};
function stmt(sql: string) {
if (!(sql in statementCache)) {
statementCache[sql] = dbConnection.prepare(sql);
@ -302,7 +311,7 @@ function fillParamList(paramIds: string[] | Set<string>, truncate = true) {
paramIds = paramIds.slice(0, 30000);
}
// doing it manually to avoid this showing up on the sloq query list
// doing it manually to avoid this showing up on the slow query list
const s = stmt(`INSERT INTO param_list VALUES ${paramIds.map(paramId => `(?)`).join(',')}`);
s.run(paramIds);
@ -403,5 +412,6 @@ export default {
upsert,
fillParamList,
copyDatabase,
disableSlowQueryLogging
disableSlowQueryLogging,
rebuildIntegrationTestDatabase
};

View File

@ -128,7 +128,7 @@
<script src="<%= assetPath %>/node_modules/dayjs/dayjs.min.js"></script>
<link href="<%= assetPath %>/stylesheets/tree.css" rel="stylesheet">
<script src="<%= assetPath %>/libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
<script src="<%= assetPath %>/node_modules/jquery.fancytree/dist/jquery.fancytree-all-deps.min.js"></script>
<link href="<%= assetPath %>/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="<%= assetPath %>/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>