diff --git a/package-lock.json b/package-lock.json
index ef2d72d2d..ab50152f5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "trilium",
- "version": "0.42.0-beta",
+ "version": "0.42.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1263,7 +1263,7 @@
"dependencies": {
"file-type": {
"version": "3.9.0",
- "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
}
}
@@ -1539,7 +1539,7 @@
},
"uuid": {
"version": "2.0.3",
- "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
"integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho="
}
}
@@ -1573,7 +1573,7 @@
"dependencies": {
"semver": {
"version": "4.3.6",
- "resolved": "http://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
"integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto="
}
}
@@ -1593,7 +1593,7 @@
},
"bl": {
"version": "1.2.2",
- "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"requires": {
"readable-stream": "^2.3.5",
@@ -1853,12 +1853,12 @@
"dependencies": {
"file-type": {
"version": "3.9.0",
- "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
},
"uuid": {
"version": "2.0.3",
- "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
"integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho="
}
}
@@ -1973,7 +1973,7 @@
},
"readable-stream": {
"version": "1.1.14",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
@@ -2148,7 +2148,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
@@ -2465,7 +2465,7 @@
},
"commander": {
"version": "2.8.1",
- "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
"requires": {
"graceful-readlink": ">= 1.0.0"
@@ -3128,7 +3128,7 @@
},
"readable-stream": {
"version": "1.1.14",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
@@ -4957,7 +4957,7 @@
},
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
"getpass": {
@@ -5221,7 +5221,7 @@
},
"got": {
"version": "5.7.1",
- "resolved": "http://registry.npmjs.org/got/-/got-5.7.1.tgz",
+ "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz",
"integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=",
"requires": {
"create-error-class": "^3.0.1",
@@ -5869,7 +5869,7 @@
},
"into-stream": {
"version": "3.1.0",
- "resolved": "http://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
"integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
"requires": {
"from2": "^2.1.1",
@@ -6021,7 +6021,7 @@
},
"is-obj": {
"version": "1.0.1",
- "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
},
"is-object": {
@@ -6621,7 +6621,7 @@
},
"load-json-file": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"requires": {
"graceful-fs": "^4.1.2",
@@ -7130,7 +7130,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"minipass": {
@@ -7230,7 +7230,7 @@
},
"mkdirp": {
"version": "0.5.1",
- "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"requires": {
"minimist": "0.0.8"
@@ -7238,7 +7238,7 @@
"dependencies": {
"minimist": {
"version": "0.0.8",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
}
}
@@ -7432,7 +7432,7 @@
},
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
"got": {
@@ -7468,7 +7468,7 @@
},
"p-cancelable": {
"version": "0.4.1",
- "resolved": "http://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
"integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ=="
},
"p-event": {
@@ -7592,7 +7592,7 @@
"dependencies": {
"file-type": {
"version": "3.9.0",
- "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
}
}
@@ -7617,7 +7617,7 @@
"dependencies": {
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
"pify": {
@@ -7674,7 +7674,7 @@
},
"get-stream": {
"version": "2.3.1",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
"integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
"requires": {
"object-assign": "^4.0.1",
@@ -7704,7 +7704,7 @@
"dependencies": {
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
}
}
@@ -7744,7 +7744,7 @@
},
"pify": {
"version": "2.3.0",
- "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
},
"prepend-http": {
@@ -7849,7 +7849,7 @@
},
"readable-stream": {
"version": "1.1.14",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
@@ -8227,7 +8227,7 @@
},
"onetime": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k="
},
"open": {
@@ -8379,7 +8379,7 @@
},
"p-is-promise": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
"integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4="
},
"p-limit": {
@@ -8860,7 +8860,7 @@
},
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
}
}
@@ -9144,7 +9144,7 @@
"dependencies": {
"file-type": {
"version": "3.9.0",
- "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
}
}
@@ -9169,7 +9169,7 @@
"dependencies": {
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
"pify": {
@@ -9207,7 +9207,7 @@
},
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
}
}
@@ -9259,7 +9259,7 @@
},
"get-stream": {
"version": "2.3.1",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
"integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
"requires": {
"object-assign": "^4.0.1",
@@ -9289,7 +9289,7 @@
"dependencies": {
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
}
}
@@ -9477,7 +9477,7 @@
},
"query-string": {
"version": "5.1.1",
- "resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
"requires": {
"decode-uri-component": "^0.2.0",
@@ -9616,7 +9616,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -10484,7 +10484,7 @@
},
"strip-ansi": {
"version": "3.0.1",
- "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
@@ -10509,7 +10509,7 @@
},
"strip-dirs": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz",
"integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=",
"requires": {
"chalk": "^1.0.0",
@@ -10767,7 +10767,7 @@
},
"through": {
"version": "2.3.8",
- "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"through2": {
@@ -10786,7 +10786,7 @@
},
"readable-stream": {
"version": "1.0.34",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"requires": {
"core-util-is": "~1.0.0",
diff --git a/src/public/app/dialogs/note_revisions.js b/src/public/app/dialogs/note_revisions.js
index 7f5f45903..ad2e1c45f 100644
--- a/src/public/app/dialogs/note_revisions.js
+++ b/src/public/app/dialogs/note_revisions.js
@@ -37,15 +37,18 @@ export async function showNoteRevisionsDialog(noteId, noteRevisionId) {
async function loadNoteRevisions(noteId, noteRevId) {
$list.empty();
$content.empty();
+ $titleButtons.empty();
note = appContext.tabManager.getActiveTabNote();
revisionItems = await server.get(`notes/${noteId}/revisions`);
for (const item of revisionItems) {
- $list.append($('')
- .text(item.dateLastEdited.substr(0, 16) + ` (${item.contentLength} bytes)`)
- .attr('data-note-revision-id', item.noteRevisionId))
- .attr('title', 'This revision was last edited on ' + item.dateLastEdited);
+ $list.append(
+ $('')
+ .text(item.dateLastEdited.substr(0, 16) + ` (${item.contentLength} bytes)`)
+ .attr('data-note-revision-id', item.noteRevisionId)
+ .attr('title', 'This revision was last edited on ' + item.dateLastEdited)
+ );
}
$listDropdown.dropdown('show');
@@ -60,6 +63,8 @@ async function loadNoteRevisions(noteId, noteRevId) {
$title.text("No revisions for this note yet...");
noteRevisionId = null;
}
+
+ $eraseAllRevisionsButton.toggle(revisionItems.length > 0);
}
$dialog.on('shown.bs.modal', () => {
@@ -77,6 +82,21 @@ async function setContentPane() {
$title.html(revisionItem.title);
+ const $restoreRevisionButton = $('');
+
+ $restoreRevisionButton.on('click', async () => {
+ const confirmDialog = await import('../dialogs/confirm.js');
+ const text = 'Do you want to restore this revision? This will overwrite current title/content of the note with this revision.';
+
+ if (await confirmDialog.confirm(text)) {
+ await server.put(`notes/${revisionItem.noteId}/restore-revision/${revisionItem.noteRevisionId}`);
+
+ $dialog.modal('hide');
+
+ toastService.showMessage('Note revision has been restored.');
+ }
+ });
+
const $eraseRevisionButton = $('');
$eraseRevisionButton.on('click', async () => {
@@ -93,6 +113,8 @@ async function setContentPane() {
});
$titleButtons
+ .append($restoreRevisionButton)
+ .append(' ')
.append($eraseRevisionButton)
.append(' ');
diff --git a/src/public/app/widgets/collapsible_widgets/note_info.js b/src/public/app/widgets/collapsible_widgets/note_info.js
index dad298d44..e0cb8aaac 100644
--- a/src/public/app/widgets/collapsible_widgets/note_info.js
+++ b/src/public/app/widgets/collapsible_widgets/note_info.js
@@ -22,15 +22,15 @@ const TPL = `
Note ID: |
- |
+ |
Created: |
- |
+ |
Modified: |
- |
+ |
Type: |
@@ -60,11 +60,11 @@ export default class NoteInfoWidget extends CollapsibleWidget {
this.$noteId.text(note.noteId);
this.$dateCreated
- .text(noteComplement.dateCreated)
+ .text(noteComplement.dateCreated.substr(0, 16))
.attr("title", noteComplement.dateCreated);
this.$dateModified
- .text(noteComplement.dateModified)
+ .text(noteComplement.dateModified.substr(0, 16))
.attr("title", noteComplement.dateCreated);
this.$type.text(note.type);
diff --git a/src/routes/api/note_revisions.js b/src/routes/api/note_revisions.js
index 11131b83b..023ba30ee 100644
--- a/src/routes/api/note_revisions.js
+++ b/src/routes/api/note_revisions.js
@@ -3,6 +3,7 @@
const repository = require('../../services/repository');
const noteCacheService = require('../../services/note_cache');
const protectedSessionService = require('../../services/protected_session');
+const noteRevisionService = require('../../services/note_revisions');
const utils = require('../../services/utils');
const path = require('path');
@@ -109,6 +110,20 @@ async function eraseNoteRevision(req) {
}
}
+async function restoreNoteRevision(req) {
+ const noteRevision = await repository.getNoteRevision(req.params.noteRevisionId);
+
+ if (noteRevision && !noteRevision.isErased) {
+ const note = await noteRevision.getNote();
+
+ await noteRevisionService.createNoteRevision(note);
+
+ note.title = noteRevision.title;
+ await note.setContent(await noteRevision.getContent());
+ await note.save();
+ }
+}
+
async function getEditedNotesOnDate(req) {
const date = utils.sanitizeSql(req.params.date);
@@ -141,5 +156,6 @@ module.exports = {
downloadNoteRevision,
getEditedNotesOnDate,
eraseAllNoteRevisions,
- eraseNoteRevision
+ eraseNoteRevision,
+ restoreNoteRevision
};
\ No newline at end of file
diff --git a/src/routes/routes.js b/src/routes/routes.js
index 439ae1201..1de0a7e29 100644
--- a/src/routes/routes.js
+++ b/src/routes/routes.js
@@ -145,6 +145,7 @@ function register(app) {
apiRoute(GET, '/api/notes/:noteId/revisions/:noteRevisionId', noteRevisionsApiRoute.getNoteRevision);
apiRoute(DELETE, '/api/notes/:noteId/revisions/:noteRevisionId', noteRevisionsApiRoute.eraseNoteRevision);
route(GET, '/api/notes/:noteId/revisions/:noteRevisionId/download', [auth.checkApiAuthOrElectron], noteRevisionsApiRoute.downloadNoteRevision);
+ apiRoute(PUT, '/api/notes/:noteId/restore-revision/:noteRevisionId', noteRevisionsApiRoute.restoreNoteRevision);
apiRoute(POST, '/api/notes/relation-map', notesApiRoute.getRelationMap);
apiRoute(PUT, '/api/notes/:noteId/change-title', notesApiRoute.changeTitle);
apiRoute(POST, '/api/notes/:noteId/duplicate/:parentNoteId', notesApiRoute.duplicateNote);