mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Merge branch 'beta'
This commit is contained in:
commit
6f16b4caec
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "trilium",
|
||||
"version": "0.60.1-beta",
|
||||
"version": "0.60.2-beta",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "trilium",
|
||||
"version": "0.60.1-beta",
|
||||
"version": "0.60.2-beta",
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "trilium",
|
||||
"productName": "Trilium Notes",
|
||||
"description": "Trilium Notes",
|
||||
"version": "0.60.1-beta",
|
||||
"version": "0.60.2-beta",
|
||||
"license": "AGPL-3.0-only",
|
||||
"main": "electron.js",
|
||||
"bin": {
|
||||
|
14
src/etapi/backup.js
Normal file
14
src/etapi/backup.js
Normal file
@ -0,0 +1,14 @@
|
||||
const eu = require("./etapi_utils");
|
||||
const backupService = require("../services/backup");
|
||||
|
||||
function register(router) {
|
||||
eu.route(router, 'put', '/etapi/backup/:backupName', async (req, res, next) => {
|
||||
await backupService.backupNow(req.params.backupName);
|
||||
|
||||
res.sendStatus(204);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
register
|
||||
};
|
@ -700,7 +700,26 @@ paths:
|
||||
application/json; charset=utf-8:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/backup/{backupName}:
|
||||
parameters:
|
||||
- name: backupName
|
||||
in: path
|
||||
required: true
|
||||
description: If the backupName is e.g. "now", then the backup will be written to "backup-now.db" file
|
||||
schema:
|
||||
$ref: '#/components/schemas/StringId'
|
||||
put:
|
||||
description: Create a database backup under a given name
|
||||
operationId: createBackup
|
||||
responses:
|
||||
'204':
|
||||
description: backup has been created
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json; charset=utf-8:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
components:
|
||||
securitySchemes:
|
||||
EtapiTokenAuth:
|
||||
@ -880,6 +899,10 @@ components:
|
||||
type: string
|
||||
pattern: '[a-zA-Z0-9_]{4,32}'
|
||||
example: evnnmvHTCgIn
|
||||
StringId:
|
||||
type: string
|
||||
pattern: '[a-zA-Z0-9_]{1,32}'
|
||||
example: my_ID
|
||||
EntityIdList:
|
||||
type: array
|
||||
items:
|
||||
|
@ -148,6 +148,9 @@ const TPL = `
|
||||
|
||||
const MAX_SEARCH_RESULTS_IN_TREE = 100;
|
||||
|
||||
// this has to be hanged on the actual elements to effectively intercept and stop click event
|
||||
const cancelClickPropagation = e => e.stopPropagation();
|
||||
|
||||
export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
constructor() {
|
||||
super();
|
||||
@ -559,7 +562,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
const isHoistedNote = activeNoteContext && activeNoteContext.hoistedNoteId === note.noteId && note.noteId !== 'root';
|
||||
|
||||
if (isHoistedNote) {
|
||||
const $unhoistButton = $('<span class="tree-item-button unhoist-button bx bx-door-open" title="Unhoist"></span>');
|
||||
const $unhoistButton = $('<span class="tree-item-button unhoist-button bx bx-door-open" title="Unhoist"></span>')
|
||||
.on("click", cancelClickPropagation);
|
||||
|
||||
// unhoist button is prepended since compared to other buttons this is not just convenience
|
||||
// on the mobile interface - it's the only way to unhoist
|
||||
@ -567,19 +571,22 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
if (note.hasLabel('workspace') && !isHoistedNote) {
|
||||
const $enterWorkspaceButton = $('<span class="tree-item-button enter-workspace-button bx bx-door-open" title="Hoist this note (workspace)"></span>');
|
||||
const $enterWorkspaceButton = $('<span class="tree-item-button enter-workspace-button bx bx-door-open" title="Hoist this note (workspace)"></span>')
|
||||
.on("click", cancelClickPropagation);
|
||||
|
||||
$span.append($enterWorkspaceButton);
|
||||
}
|
||||
|
||||
if (note.type === 'search') {
|
||||
const $refreshSearchButton = $('<span class="tree-item-button refresh-search-button bx bx-refresh" title="Refresh saved search results"></span>');
|
||||
const $refreshSearchButton = $('<span class="tree-item-button refresh-search-button bx bx-refresh" title="Refresh saved search results"></span>')
|
||||
.on("click", cancelClickPropagation);
|
||||
|
||||
$span.append($refreshSearchButton);
|
||||
}
|
||||
|
||||
if (!['search', 'launcher'].includes(note.type) && !note.isOptions() && !note.isLaunchBarConfig()) {
|
||||
const $createChildNoteButton = $('<span class="tree-item-button add-note-button bx bx-plus" title="Create child note"></span>');
|
||||
const $createChildNoteButton = $('<span class="tree-item-button add-note-button bx bx-plus" title="Create child note"></span>')
|
||||
.on("click", cancelClickPropagation);
|
||||
|
||||
$span.append($createChildNoteButton);
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ function getRecentChanges(req) {
|
||||
for (const noteRevisionRow of noteRevisionRows) {
|
||||
const note = becca.getNote(noteRevisionRow.noteId);
|
||||
|
||||
if (note?.hasAncestor(ancestorNoteId)) {
|
||||
// for deleted notes, the becca note is null, and it's not possible to (easily) determine if it belongs to a subtree
|
||||
if (ancestorNoteId === 'root' || note?.hasAncestor(ancestorNoteId)) {
|
||||
recentChanges.push(noteRevisionRow);
|
||||
}
|
||||
}
|
||||
@ -43,8 +44,8 @@ function getRecentChanges(req) {
|
||||
notes.title AS current_title,
|
||||
notes.isProtected AS current_isProtected,
|
||||
notes.title,
|
||||
notes.utcDateCreated AS utcDate,
|
||||
notes.dateCreated AS date
|
||||
notes.utcDateCreated AS utcDate, -- different from the second SELECT
|
||||
notes.dateCreated AS date -- different from the second SELECT
|
||||
FROM notes
|
||||
UNION ALL
|
||||
SELECT
|
||||
@ -54,15 +55,16 @@ function getRecentChanges(req) {
|
||||
notes.title AS current_title,
|
||||
notes.isProtected AS current_isProtected,
|
||||
notes.title,
|
||||
notes.utcDateModified AS utcDate,
|
||||
notes.dateModified AS date
|
||||
notes.utcDateModified AS utcDate, -- different from the first SELECT
|
||||
notes.dateModified AS date -- different from the first SELECT
|
||||
FROM notes
|
||||
WHERE notes.isDeleted = 1`);
|
||||
|
||||
for (const noteRow of noteRows) {
|
||||
const note = becca.getNote(noteRow.noteId);
|
||||
|
||||
if (note?.hasAncestor(ancestorNoteId)) {
|
||||
// for deleted notes, the becca note is null, and it's not possible to (easily) determine if it belongs to a subtree
|
||||
if (ancestorNoteId === 'root' || note?.hasAncestor(ancestorNoteId)) {
|
||||
recentChanges.push(noteRow);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ function execute(req) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (query.toLowerCase().startsWith('select')) {
|
||||
if (query.toLowerCase().startsWith('select') || query.toLowerCase().startsWith('with')) {
|
||||
results.push(sql.getRows(query));
|
||||
}
|
||||
else {
|
||||
|
@ -65,6 +65,7 @@ const etapiBranchRoutes = require('../etapi/branches');
|
||||
const etapiNoteRoutes = require('../etapi/notes');
|
||||
const etapiSpecialNoteRoutes = require('../etapi/special_notes');
|
||||
const etapiSpecRoute = require('../etapi/spec');
|
||||
const etapiBackupRoute = require('../etapi/backup');
|
||||
|
||||
const csrfMiddleware = csurf({
|
||||
cookie: true,
|
||||
@ -315,6 +316,7 @@ function register(app) {
|
||||
etapiNoteRoutes.register(router);
|
||||
etapiSpecialNoteRoutes.register(router);
|
||||
etapiSpecRoute.register(router);
|
||||
etapiBackupRoute.register(router);
|
||||
|
||||
app.use('', router);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
module.exports = { buildDate:"2023-05-26T23:11:53+02:00", buildRevision: "82efc924136c5b215e39f2108f00dd2bf075271c" };
|
||||
module.exports = { buildDate:"2023-06-08T22:46:52+02:00", buildRevision: "6e69cafe5419e8efcc6f652647f9227dbcfa1e18" };
|
||||
|
4
test-etapi/create-backup.http
Normal file
4
test-etapi/create-backup.http
Normal file
@ -0,0 +1,4 @@
|
||||
PUT {{triliumHost}}/etapi/backup/etapi_test
|
||||
Authorization: {{authToken}}
|
||||
|
||||
> {% client.assert(response.status === 201); %}
|
Loading…
x
Reference in New Issue
Block a user