mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
refactored all mentions of "history" to "revision"
This commit is contained in:
parent
a69d8737ce
commit
47eb1e3e02
@ -0,0 +1 @@
|
|||||||
|
UPDATE options SET name = 'note_revision_snapshot_time_interval' WHERE name = 'history_snapshot_time_interval';
|
@ -1,72 +0,0 @@
|
|||||||
import noteDetailService from '../services/note_detail.js';
|
|
||||||
import utils from '../services/utils.js';
|
|
||||||
import server from '../services/server.js';
|
|
||||||
|
|
||||||
const $dialog = $("#note-history-dialog");
|
|
||||||
const $list = $("#note-history-list");
|
|
||||||
const $content = $("#note-history-content");
|
|
||||||
const $title = $("#note-history-title");
|
|
||||||
|
|
||||||
let historyItems = [];
|
|
||||||
|
|
||||||
async function showCurrentNoteHistory() {
|
|
||||||
await showNoteHistoryDialog(noteDetailService.getCurrentNoteId());
|
|
||||||
}
|
|
||||||
|
|
||||||
async function showNoteHistoryDialog(noteId, noteRevisionId) {
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.dialog({
|
|
||||||
modal: true,
|
|
||||||
width: 800,
|
|
||||||
height: 700
|
|
||||||
});
|
|
||||||
|
|
||||||
$list.empty();
|
|
||||||
$content.empty();
|
|
||||||
|
|
||||||
historyItems = await server.get('notes-history/' + noteId);
|
|
||||||
|
|
||||||
for (const item of historyItems) {
|
|
||||||
const dateModified = utils.parseDate(item.dateModifiedFrom);
|
|
||||||
|
|
||||||
$list.append($('<option>', {
|
|
||||||
value: item.noteRevisionId,
|
|
||||||
text: utils.formatDateTime(dateModified)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (historyItems.length > 0) {
|
|
||||||
if (!noteRevisionId) {
|
|
||||||
noteRevisionId = $list.find("option:first").val();
|
|
||||||
}
|
|
||||||
|
|
||||||
$list.val(noteRevisionId).trigger('change');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$title.text("No history for this note yet...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$list.on('change', () => {
|
|
||||||
const optVal = $list.find(":selected").val();
|
|
||||||
|
|
||||||
const historyItem = historyItems.find(r => r.noteRevisionId === optVal);
|
|
||||||
|
|
||||||
$title.html(historyItem.title);
|
|
||||||
$content.html(historyItem.content);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', "a[action='note-history']", event => {
|
|
||||||
const linkEl = $(event.target);
|
|
||||||
const noteId = linkEl.attr('note-path');
|
|
||||||
const noteRevisionId = linkEl.attr('note-history-id');
|
|
||||||
|
|
||||||
showNoteHistoryDialog(noteId, noteRevisionId);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
showCurrentNoteHistory
|
|
||||||
};
|
|
72
src/public/javascripts/dialogs/note_revisions.js
Normal file
72
src/public/javascripts/dialogs/note_revisions.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import noteDetailService from '../services/note_detail.js';
|
||||||
|
import utils from '../services/utils.js';
|
||||||
|
import server from '../services/server.js';
|
||||||
|
|
||||||
|
const $dialog = $("#note-revisions-dialog");
|
||||||
|
const $list = $("#note-revision-list");
|
||||||
|
const $content = $("#note-revision-content");
|
||||||
|
const $title = $("#note-revision-title");
|
||||||
|
|
||||||
|
let revisionItems = [];
|
||||||
|
|
||||||
|
async function showCurrentNoteRevisions() {
|
||||||
|
await showNoteRevisionsDialog(noteDetailService.getCurrentNoteId());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function showNoteRevisionsDialog(noteId, noteRevisionId) {
|
||||||
|
glob.activeDialog = $dialog;
|
||||||
|
|
||||||
|
$dialog.dialog({
|
||||||
|
modal: true,
|
||||||
|
width: 800,
|
||||||
|
height: 700
|
||||||
|
});
|
||||||
|
|
||||||
|
$list.empty();
|
||||||
|
$content.empty();
|
||||||
|
|
||||||
|
revisionItems = await server.get('notes-revisions/' + noteId);
|
||||||
|
|
||||||
|
for (const item of revisionItems) {
|
||||||
|
const dateModified = utils.parseDate(item.dateModifiedFrom);
|
||||||
|
|
||||||
|
$list.append($('<option>', {
|
||||||
|
value: item.noteRevisionId,
|
||||||
|
text: utils.formatDateTime(dateModified)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (revisionItems.length > 0) {
|
||||||
|
if (!noteRevisionId) {
|
||||||
|
noteRevisionId = $list.find("option:first").val();
|
||||||
|
}
|
||||||
|
|
||||||
|
$list.val(noteRevisionId).trigger('change');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$title.text("No revisions for this note yet...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$list.on('change', () => {
|
||||||
|
const optVal = $list.find(":selected").val();
|
||||||
|
|
||||||
|
const revisionItem = revisionItems.find(r => r.noteRevisionId === optVal);
|
||||||
|
|
||||||
|
$title.html(revisionItem.title);
|
||||||
|
$content.html(revisionItem.content);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', "a[action='note-revision']", event => {
|
||||||
|
const linkEl = $(event.target);
|
||||||
|
const noteId = linkEl.attr('note-path');
|
||||||
|
const noteRevisionId = linkEl.attr('note-revision-id');
|
||||||
|
|
||||||
|
showNoteRevisionsDialog(noteId, noteRevisionId);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
export default {
|
||||||
|
showCurrentNoteRevisions
|
||||||
|
};
|
@ -30,9 +30,9 @@ async function showDialog() {
|
|||||||
const revLink = $("<a>", {
|
const revLink = $("<a>", {
|
||||||
href: 'javascript:',
|
href: 'javascript:',
|
||||||
text: 'rev'
|
text: 'rev'
|
||||||
}).attr('action', 'note-history')
|
}).attr('action', 'note-revision')
|
||||||
.attr('note-path', change.noteId)
|
.attr('note-path', change.noteId)
|
||||||
.attr('note-history-id', change.noteRevisionId);
|
.attr('note-revision-id', change.noteRevisionId);
|
||||||
|
|
||||||
let noteLink;
|
let noteLink;
|
||||||
|
|
||||||
|
@ -117,9 +117,9 @@ addModule((function() {
|
|||||||
})());
|
})());
|
||||||
|
|
||||||
addModule((function () {
|
addModule((function () {
|
||||||
const $form = $("#history-snapshot-time-interval-form");
|
const $form = $("#note-revision-snapshot-time-interval-form");
|
||||||
const $timeInterval = $("#history-snapshot-time-interval-in-seconds");
|
const $timeInterval = $("#note-revision-snapshot-time-interval-in-seconds");
|
||||||
const settingName = 'history_snapshot_time_interval';
|
const settingName = 'note_revision_snapshot_time_interval';
|
||||||
|
|
||||||
function settingsLoaded(settings) {
|
function settingsLoaded(settings) {
|
||||||
$timeInterval.val(settings[settingName]);
|
$timeInterval.val(settings[settingName]);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
"use strict";
|
import server from './services/server.js';
|
||||||
|
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
server.get('migration').then(result => {
|
server.get('migration').then(result => {
|
||||||
|
4
src/public/javascripts/services/bootstrap.js
vendored
4
src/public/javascripts/services/bootstrap.js
vendored
@ -1,7 +1,7 @@
|
|||||||
import addLinkDialog from '../dialogs/add_link.js';
|
import addLinkDialog from '../dialogs/add_link.js';
|
||||||
import jumpToNoteDialog from '../dialogs/jump_to_note.js';
|
import jumpToNoteDialog from '../dialogs/jump_to_note.js';
|
||||||
import labelsDialog from '../dialogs/labels.js';
|
import labelsDialog from '../dialogs/labels.js';
|
||||||
import noteRevisionsDialog from '../dialogs/note_history.js';
|
import noteRevisionsDialog from '../dialogs/note_revisions.js';
|
||||||
import noteSourceDialog from '../dialogs/note_source.js';
|
import noteSourceDialog from '../dialogs/note_source.js';
|
||||||
import recentChangesDialog from '../dialogs/recent_changes.js';
|
import recentChangesDialog from '../dialogs/recent_changes.js';
|
||||||
import recentNotesDialog from '../dialogs/recent_notes.js';
|
import recentNotesDialog from '../dialogs/recent_notes.js';
|
||||||
@ -43,7 +43,7 @@ utils.bindShortcut('ctrl+l', addLinkDialog.showDialog);
|
|||||||
$("#jump-to-note-button").click(jumpToNoteDialog.showDialog);
|
$("#jump-to-note-button").click(jumpToNoteDialog.showDialog);
|
||||||
utils.bindShortcut('ctrl+j', jumpToNoteDialog.showDialog);
|
utils.bindShortcut('ctrl+j', jumpToNoteDialog.showDialog);
|
||||||
|
|
||||||
$("#show-history-button").click(noteRevisionsDialog.showCurrentNoteHistory);
|
$("#show-note-revisions-button").click(noteRevisionsDialog.showCurrentNoteRevisions);
|
||||||
|
|
||||||
$("#show-source-button").click(noteSourceDialog.showDialog);
|
$("#show-source-button").click(noteSourceDialog.showDialog);
|
||||||
utils.bindShortcut('ctrl+u', noteSourceDialog.showDialog);
|
utils.bindShortcut('ctrl+u', noteSourceDialog.showDialog);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import linkService from './link.js';
|
//import messagingService from './messaging.js';
|
||||||
import messagingService from './messaging.js';
|
//import ScriptContext from './script_context.js';
|
||||||
import ScriptContext from './script_context.js';
|
|
||||||
|
|
||||||
function reloadApp() {
|
function reloadApp() {
|
||||||
window.location.reload(true);
|
window.location.reload(true);
|
||||||
@ -189,7 +188,7 @@ async function requireScript(url) {
|
|||||||
|
|
||||||
async function requireCss(url) {
|
async function requireCss(url) {
|
||||||
const css = Array
|
const css = Array
|
||||||
.from(document.querySelectorAll('linkService'))
|
.from(document.querySelectorAll('link'))
|
||||||
.map(scr => scr.href);
|
.map(scr => scr.href);
|
||||||
|
|
||||||
if (!css.includes(url)) {
|
if (!css.includes(url)) {
|
||||||
|
@ -10,10 +10,10 @@ const wrap = require('express-promise-wrap').wrap;
|
|||||||
|
|
||||||
router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const history = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? order by dateModifiedTo desc", [noteId]);
|
const revisions = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? order by dateModifiedTo desc", [noteId]);
|
||||||
protected_session.decryptNoteHistoryRows(req, history);
|
protected_session.decryptNoteRevisions(req, revisions);
|
||||||
|
|
||||||
res.send(history);
|
res.send(revisions);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
router.put('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
router.put('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||||
@ -22,7 +22,7 @@ router.put('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
|||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
await sql.replace("note_revisions", req.body);
|
await sql.replace("note_revisions", req.body);
|
||||||
|
|
||||||
await sync_table.addNoteHistorySync(req.body.noteRevisionId, sourceId);
|
await sync_table.addNoteRevisionSync(req.body.noteRevisionId, sourceId);
|
||||||
});
|
});
|
||||||
|
|
||||||
res.send();
|
res.send();
|
@ -8,7 +8,7 @@ const auth = require('../../services/auth');
|
|||||||
const wrap = require('express-promise-wrap').wrap;
|
const wrap = require('express-promise-wrap').wrap;
|
||||||
|
|
||||||
// options allowed to be updated directly in settings dialog
|
// options allowed to be updated directly in settings dialog
|
||||||
const ALLOWED_OPTIONS = ['protected_session_timeout', 'history_snapshot_time_interval'];
|
const ALLOWED_OPTIONS = ['protected_session_timeout', 'note_revision_snapshot_time_interval'];
|
||||||
|
|
||||||
router.get('/all', auth.checkApiAuth, wrap(async (req, res, next) => {
|
router.get('/all', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||||
const settings = await sql.getMap("SELECT name, value FROM options");
|
const settings = await sql.getMap("SELECT name, value FROM options");
|
||||||
|
@ -59,7 +59,7 @@ router.post('/force-note-sync/:noteId', auth.checkApiAuth, wrap(async (req, res,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const noteRevisionId of await sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) {
|
for (const noteRevisionId of await sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) {
|
||||||
await sync_table.addNoteHistorySync(noteRevisionId);
|
await sync_table.addNoteRevisionsSync(noteRevisionId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ router.put('/branches', auth.checkApiAuth, wrap(async (req, res, next) => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
router.put('/note_revisions', auth.checkApiAuth, wrap(async (req, res, next) => {
|
router.put('/note_revisions', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||||
await syncUpdate.updateNoteHistory(req.body.entity, req.body.sourceId);
|
await syncUpdate.updateNoteRevision(req.body.entity, req.body.sourceId);
|
||||||
|
|
||||||
res.send({});
|
res.send({});
|
||||||
}));
|
}));
|
||||||
|
@ -9,7 +9,7 @@ const treeApiRoute = require('./api/tree');
|
|||||||
const notesApiRoute = require('./api/notes');
|
const notesApiRoute = require('./api/notes');
|
||||||
const treeChangesApiRoute = require('./api/tree_changes');
|
const treeChangesApiRoute = require('./api/tree_changes');
|
||||||
const cloningApiRoute = require('./api/cloning');
|
const cloningApiRoute = require('./api/cloning');
|
||||||
const noteHistoryApiRoute = require('./api/note_history');
|
const noteRevisionsApiRoute = require('./api/note_revisions');
|
||||||
const recentChangesApiRoute = require('./api/recent_changes');
|
const recentChangesApiRoute = require('./api/recent_changes');
|
||||||
const settingsApiRoute = require('./api/settings');
|
const settingsApiRoute = require('./api/settings');
|
||||||
const passwordApiRoute = require('./api/password');
|
const passwordApiRoute = require('./api/password');
|
||||||
@ -44,7 +44,7 @@ function register(app) {
|
|||||||
app.use('/api/tree', treeChangesApiRoute);
|
app.use('/api/tree', treeChangesApiRoute);
|
||||||
app.use('/api/notes', cloningApiRoute);
|
app.use('/api/notes', cloningApiRoute);
|
||||||
app.use('/api', labelsRoute);
|
app.use('/api', labelsRoute);
|
||||||
app.use('/api/notes-history', noteHistoryApiRoute);
|
app.use('/api/notes-revisions', noteRevisionsApiRoute);
|
||||||
app.use('/api/recent-changes', recentChangesApiRoute);
|
app.use('/api/recent-changes', recentChangesApiRoute);
|
||||||
app.use('/api/settings', settingsApiRoute);
|
app.use('/api/settings', settingsApiRoute);
|
||||||
app.use('/api/password', passwordApiRoute);
|
app.use('/api/password', passwordApiRoute);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
const build = require('./build');
|
const build = require('./build');
|
||||||
const packageJson = require('../../package');
|
const packageJson = require('../../package');
|
||||||
|
|
||||||
const APP_DB_VERSION = 80;
|
const APP_DB_VERSION = 81;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
app_version: packageJson.version,
|
app_version: packageJson.version,
|
||||||
|
@ -161,7 +161,7 @@ async function runAllChecks() {
|
|||||||
note_revisions LEFT JOIN notes USING(noteId)
|
note_revisions LEFT JOIN notes USING(noteId)
|
||||||
WHERE
|
WHERE
|
||||||
notes.noteId IS NULL`,
|
notes.noteId IS NULL`,
|
||||||
"Missing notes records for following note history ID > note ID", errorList);
|
"Missing notes records for following note revision ID > note ID", errorList);
|
||||||
|
|
||||||
await runCheck(`
|
await runCheck(`
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -154,32 +154,32 @@ async function protectNote(note, dataKey, protect, sourceId) {
|
|||||||
await sync_table.addNoteSync(note.noteId, sourceId);
|
await sync_table.addNoteSync(note.noteId, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await protectNoteHistory(note.noteId, dataKey, protect, sourceId);
|
await protectNoteRevisions(note.noteId, dataKey, protect, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function protectNoteHistory(noteId, dataKey, protect, sourceId) {
|
async function protectNoteRevisions(noteId, dataKey, protect, sourceId) {
|
||||||
const historyToChange = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? AND isProtected != ?", [noteId, protect]);
|
const revisionsToChange = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? AND isProtected != ?", [noteId, protect]);
|
||||||
|
|
||||||
for (const history of historyToChange) {
|
for (const revision of revisionsToChange) {
|
||||||
if (protect) {
|
if (protect) {
|
||||||
protected_session.encryptNoteHistoryRow(dataKey, history);
|
protected_session.encryptNoteRevision(dataKey, revision);
|
||||||
|
|
||||||
history.isProtected = true;
|
revision.isProtected = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
protected_session.decryptNoteHistoryRow(dataKey, history);
|
protected_session.decryptNoteRevision(dataKey, revision);
|
||||||
|
|
||||||
history.isProtected = false;
|
revision.isProtected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await sql.execute("UPDATE note_revisions SET title = ?, content = ?, isProtected = ? WHERE noteRevisionId = ?",
|
await sql.execute("UPDATE note_revisions SET title = ?, content = ?, isProtected = ? WHERE noteRevisionId = ?",
|
||||||
[history.title, history.content, history.isProtected, history.noteRevisionId]);
|
[revision.title, revision.content, revision.isProtected, revision.noteRevisionId]);
|
||||||
|
|
||||||
await sync_table.addNoteHistorySync(history.noteRevisionId, sourceId);
|
await sync_table.addNoteRevisionSync(revision.noteRevisionId, sourceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveNoteHistory(noteId, dataKey, sourceId, nowStr) {
|
async function saveNoteRevision(noteId, dataKey, sourceId, nowStr) {
|
||||||
const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||||
|
|
||||||
if (oldNote.type === 'file') {
|
if (oldNote.type === 'file') {
|
||||||
@ -200,12 +200,12 @@ async function saveNoteHistory(noteId, dataKey, sourceId, nowStr) {
|
|||||||
// title and text should be decrypted now
|
// title and text should be decrypted now
|
||||||
title: oldNote.title,
|
title: oldNote.title,
|
||||||
content: oldNote.content,
|
content: oldNote.content,
|
||||||
isProtected: 0, // will be fixed in the protectNoteHistory() call
|
isProtected: 0, // will be fixed in the protectNoteRevisions() call
|
||||||
dateModifiedFrom: oldNote.dateModified,
|
dateModifiedFrom: oldNote.dateModified,
|
||||||
dateModifiedTo: nowStr
|
dateModifiedTo: nowStr
|
||||||
});
|
});
|
||||||
|
|
||||||
await sync_table.addNoteHistorySync(newNoteRevisionId, sourceId);
|
await sync_table.addNoteRevisionSync(newNoteRevisionId, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveNoteImages(noteId, noteText, sourceId) {
|
async function saveNoteImages(noteId, noteText, sourceId) {
|
||||||
@ -279,26 +279,26 @@ async function updateNote(noteId, newNote, dataKey, sourceId) {
|
|||||||
const now = new Date();
|
const now = new Date();
|
||||||
const nowStr = utils.nowDate();
|
const nowStr = utils.nowDate();
|
||||||
|
|
||||||
const historySnapshotTimeInterval = parseInt(await options.getOption('history_snapshot_time_interval'));
|
const noteRevisionSnapshotTimeInterval = parseInt(await options.getOption('note_revision_snapshot_time_interval'));
|
||||||
|
|
||||||
const historyCutoff = utils.dateStr(new Date(now.getTime() - historySnapshotTimeInterval * 1000));
|
const revisionCutoff = utils.dateStr(new Date(now.getTime() - noteRevisionSnapshotTimeInterval * 1000));
|
||||||
|
|
||||||
const existingnoteRevisionId = await sql.getValue(
|
const existingnoteRevisionId = await sql.getValue(
|
||||||
"SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND dateModifiedTo >= ?", [noteId, historyCutoff]);
|
"SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND dateModifiedTo >= ?", [noteId, revisionCutoff]);
|
||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
const msSinceDateCreated = now.getTime() - utils.parseDateTime(newNote.detail.dateCreated).getTime();
|
const msSinceDateCreated = now.getTime() - utils.parseDateTime(newNote.detail.dateCreated).getTime();
|
||||||
|
|
||||||
if (labelsMap.disable_versioning !== 'true'
|
if (labelsMap.disable_versioning !== 'true'
|
||||||
&& !existingnoteRevisionId
|
&& !existingnoteRevisionId
|
||||||
&& msSinceDateCreated >= historySnapshotTimeInterval * 1000) {
|
&& msSinceDateCreated >= noteRevisionSnapshotTimeInterval * 1000) {
|
||||||
|
|
||||||
await saveNoteHistory(noteId, dataKey, sourceId, nowStr);
|
await saveNoteRevision(noteId, dataKey, sourceId, nowStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
await saveNoteImages(noteId, newNote.detail.content, sourceId);
|
await saveNoteImages(noteId, newNote.detail.content, sourceId);
|
||||||
|
|
||||||
await protectNoteHistory(noteId, dataKey, newNote.detail.isProtected);
|
await protectNoteRevisions(noteId, dataKey, newNote.detail.isProtected);
|
||||||
|
|
||||||
await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [
|
await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [
|
||||||
newNote.detail.title,
|
newNote.detail.title,
|
||||||
|
@ -76,7 +76,7 @@ async function initOptions(startNotePath) {
|
|||||||
|
|
||||||
await createOption('start_note_path', startNotePath, false);
|
await createOption('start_note_path', startNotePath, false);
|
||||||
await createOption('protected_session_timeout', 600, true);
|
await createOption('protected_session_timeout', 600, true);
|
||||||
await createOption('history_snapshot_time_interval', 600, true);
|
await createOption('note_revision_snapshot_time_interval', 600, true);
|
||||||
await createOption('last_backup_date', utils.nowDate(), false);
|
await createOption('last_backup_date', utils.nowDate(), false);
|
||||||
await createOption('db_version', app_info.db_version, false);
|
await createOption('db_version', app_info.db_version, false);
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ function decryptNotes(dataKey, notes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptNoteHistoryRow(dataKey, hist) {
|
function decryptNoteRevision(dataKey, hist) {
|
||||||
dataKey = getDataKey(dataKey);
|
dataKey = getDataKey(dataKey);
|
||||||
|
|
||||||
if (!hist.isProtected) {
|
if (!hist.isProtected) {
|
||||||
@ -91,11 +91,11 @@ function decryptNoteHistoryRow(dataKey, hist) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptNoteHistoryRows(dataKey, historyRows) {
|
function decryptNoteRevisions(dataKey, noteRevisions) {
|
||||||
dataKey = getDataKey(dataKey);
|
dataKey = getDataKey(dataKey);
|
||||||
|
|
||||||
for (const hist of historyRows) {
|
for (const revision of noteRevisions) {
|
||||||
decryptNoteHistoryRow(dataKey, hist);
|
decryptNoteRevision(dataKey, revision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,11 +106,11 @@ function encryptNote(dataKey, note) {
|
|||||||
note.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(note.noteId), note.content);
|
note.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(note.noteId), note.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
function encryptNoteHistoryRow(dataKey, history) {
|
function encryptNoteRevision(dataKey, revision) {
|
||||||
dataKey = getDataKey(dataKey);
|
dataKey = getDataKey(dataKey);
|
||||||
|
|
||||||
history.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(history.noteRevisionId), history.title);
|
revision.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(revision.noteRevisionId), revision.title);
|
||||||
history.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(history.noteRevisionId), history.content);
|
revision.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(revision.noteRevisionId), revision.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -120,8 +120,8 @@ module.exports = {
|
|||||||
isProtectedSessionAvailable,
|
isProtectedSessionAvailable,
|
||||||
decryptNote,
|
decryptNote,
|
||||||
decryptNotes,
|
decryptNotes,
|
||||||
decryptNoteHistoryRow,
|
decryptNoteRevision,
|
||||||
decryptNoteHistoryRows,
|
decryptNoteRevisions,
|
||||||
encryptNote,
|
encryptNote,
|
||||||
encryptNoteHistoryRow
|
encryptNoteRevision
|
||||||
};
|
};
|
@ -129,7 +129,7 @@ async function pullSync(syncContext) {
|
|||||||
await syncUpdate.updateBranch(resp, syncContext.sourceId);
|
await syncUpdate.updateBranch(resp, syncContext.sourceId);
|
||||||
}
|
}
|
||||||
else if (sync.entityName === 'note_revisions') {
|
else if (sync.entityName === 'note_revisions') {
|
||||||
await syncUpdate.updateNoteHistory(resp, syncContext.sourceId);
|
await syncUpdate.updateNoteRevision(resp, syncContext.sourceId);
|
||||||
}
|
}
|
||||||
else if (sync.entityName === 'note_reordering') {
|
else if (sync.entityName === 'note_reordering') {
|
||||||
await syncUpdate.updateNoteReordering(resp, syncContext.sourceId);
|
await syncUpdate.updateNoteReordering(resp, syncContext.sourceId);
|
||||||
|
@ -16,7 +16,7 @@ async function addNoteReorderingSync(parentNoteId, sourceId) {
|
|||||||
await addEntitySync("note_reordering", parentNoteId, sourceId)
|
await addEntitySync("note_reordering", parentNoteId, sourceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addNoteHistorySync(noteRevisionId, sourceId) {
|
async function addNoteRevisionSync(noteRevisionId, sourceId) {
|
||||||
await addEntitySync("note_revisions", noteRevisionId, sourceId);
|
await addEntitySync("note_revisions", noteRevisionId, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ module.exports = {
|
|||||||
addNoteSync,
|
addNoteSync,
|
||||||
addBranchSync,
|
addBranchSync,
|
||||||
addNoteReorderingSync,
|
addNoteReorderingSync,
|
||||||
addNoteHistorySync,
|
addNoteRevisionSync,
|
||||||
addOptionsSync,
|
addOptionsSync,
|
||||||
addRecentNoteSync,
|
addRecentNoteSync,
|
||||||
addImageSync,
|
addImageSync,
|
||||||
|
@ -42,18 +42,18 @@ async function updateBranch(entity, sourceId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateNoteHistory(entity, sourceId) {
|
async function updateNoteRevision(entity, sourceId) {
|
||||||
const orig = await sql.getRowOrNull("SELECT * FROM note_revisions WHERE noteRevisionId = ?", [entity.noteRevisionId]);
|
const orig = await sql.getRowOrNull("SELECT * FROM note_revisions WHERE noteRevisionId = ?", [entity.noteRevisionId]);
|
||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
// we update note history even if date modified to is the same because the only thing which might have changed
|
// we update note revision even if date modified to is the same because the only thing which might have changed
|
||||||
// is the protected status (and correnspondingly title and content) which doesn't affect the dateModifiedTo
|
// is the protected status (and correnspondingly title and content) which doesn't affect the dateModifiedTo
|
||||||
if (orig === null || orig.dateModifiedTo <= entity.dateModifiedTo) {
|
if (orig === null || orig.dateModifiedTo <= entity.dateModifiedTo) {
|
||||||
await sql.replace('note_revisions', entity);
|
await sql.replace('note_revisions', entity);
|
||||||
|
|
||||||
await sync_table.addNoteHistorySync(entity.noteRevisionId, sourceId);
|
await sync_table.addNoteRevisionSync(entity.noteRevisionId, sourceId);
|
||||||
|
|
||||||
log.info("Update/sync note history " + entity.noteRevisionId);
|
log.info("Update/sync note revision " + entity.noteRevisionId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -161,7 +161,7 @@ async function updateApiToken(entity, sourceId) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
updateNote,
|
updateNote,
|
||||||
updateBranch,
|
updateBranch,
|
||||||
updateNoteHistory,
|
updateNoteRevision,
|
||||||
updateNoteReordering,
|
updateNoteReordering,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
updateRecentNotes,
|
updateRecentNotes,
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dLabel">
|
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dLabel">
|
||||||
<li><a id="show-history-button"><kbd>Alt+H</kbd> History</a></li>
|
<li><a id="show-note-revisions-button">Note revisions</a></li>
|
||||||
<li><a class="show-labels-button"><kbd>Alt+L</kbd> Labels</a></li>
|
<li><a class="show-labels-button"><kbd>Alt+L</kbd> Labels</a></li>
|
||||||
<li><a id="show-source-button"><kbd>Ctrl+U</kbd> HTML source</a></li>
|
<li><a id="show-source-button"><kbd>Ctrl+U</kbd> HTML source</a></li>
|
||||||
<li><a id="upload-attachment-button">Upload attachment</a></li>
|
<li><a id="upload-attachment-button">Upload attachment</a></li>
|
||||||
@ -277,7 +277,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a href="#change-password">Change password</a></li>
|
<li><a href="#change-password">Change password</a></li>
|
||||||
<li><a href="#protected-session-timeout">Protected session</a></li>
|
<li><a href="#protected-session-timeout">Protected session</a></li>
|
||||||
<li><a href="#history-snapshot-time-interval">History snapshots</a></li>
|
<li><a href="#note-revision-snapshot-time-interval">Note revisions</a></li>
|
||||||
<li><a href="#advanced">Advanced</a></li>
|
<li><a href="#advanced">Advanced</a></li>
|
||||||
<li><a href="#about">About Trilium</a></li>
|
<li><a href="#about">About Trilium</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -314,13 +314,13 @@
|
|||||||
<button class="btn btn-sm">Save</button>
|
<button class="btn btn-sm">Save</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="history-snapshot-time-interval">
|
<div id="note-revision-snapshot-time-interval">
|
||||||
<p>History snapshot time interval is time in seconds after which new history record will be created for the note.</p>
|
<p>Note revision snapshot time interval is time in seconds after which new note revision will be created for the note.</p>
|
||||||
|
|
||||||
<form id="history-snapshot-time-interval-form">
|
<form id="note-revision-snapshot-time-interval-form">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="history-snapshot-time-interval-in-seconds">History snapshot time interval (in seconds)</label>
|
<label for="note-revision-snapshot-time-interval-in-seconds">Note revision snapshot time interval (in seconds)</label>
|
||||||
<input class="form-control" id="history-snapshot-time-interval-in-seconds" type="number">
|
<input class="form-control" id="note-revision-snapshot-time-interval-in-seconds" type="number">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-sm">Save</button>
|
<button class="btn btn-sm">Save</button>
|
||||||
@ -346,7 +346,7 @@
|
|||||||
|
|
||||||
<p>This will remove all image data of images not used in any current version of note from the database (metadata will remain).
|
<p>This will remove all image data of images not used in any current version of note from the database (metadata will remain).
|
||||||
|
|
||||||
This means that some images can disappear from note history.</p>
|
This means that some images can disappear from note revisions.</p>
|
||||||
|
|
||||||
<button id="cleanup-unused-images-button" class="btn btn-warning btn-sm">Permanently cleanup unused images</button>
|
<button id="cleanup-unused-images-button" class="btn btn-warning btn-sm">Permanently cleanup unused images</button>
|
||||||
|
|
||||||
@ -389,15 +389,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="note-history-dialog" title="Note history" style="display: none;">
|
<div id="note-revisions-dialog" title="Note revisions" style="display: none;">
|
||||||
<div style="display: flex;">
|
<div style="display: flex;">
|
||||||
<select id="note-history-list" size="25" style="width: 150px; height: 630px;">
|
<select id="note-revision-list" size="25" style="width: 150px; height: 630px;">
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<div id="note-history-content-wrapper" style="flex-grow: 1; margin-left: 20px;">
|
<div id="note-revision-content-wrapper" style="flex-grow: 1; margin-left: 20px;">
|
||||||
<h3 id="note-history-title" style="margin: 3px;"></h3>
|
<h3 id="note-revision-title" style="margin: 3px;"></h3>
|
||||||
|
|
||||||
<div id="note-history-content" style="height: 600px; width: 600px; overflow: auto;"></div>
|
<div id="note-revision-content" style="height: 600px; width: 600px; overflow: auto;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -67,8 +67,6 @@
|
|||||||
<link href="libraries/bootstrap/css/bootstrap.css" rel="stylesheet">
|
<link href="libraries/bootstrap/css/bootstrap.css" rel="stylesheet">
|
||||||
<script src="libraries/bootstrap/js/bootstrap.js"></script>
|
<script src="libraries/bootstrap/js/bootstrap.js"></script>
|
||||||
|
|
||||||
<script src="javascripts/migration.js"></script>
|
<script src="javascripts/migration.js" type="module"></script>
|
||||||
<script src="javascripts/utils.js"></script>
|
|
||||||
<script src="javascripts/server.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user