refactored all mentions of "history" to "revision"

This commit is contained in:
azivner 2018-03-25 20:52:38 -04:00
parent a69d8737ce
commit 47eb1e3e02
22 changed files with 147 additions and 149 deletions

View File

@ -0,0 +1 @@
UPDATE options SET name = 'note_revision_snapshot_time_interval' WHERE name = 'history_snapshot_time_interval';

View File

@ -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
};

View 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
};

View File

@ -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;

View File

@ -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]);

View File

@ -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 => {

View File

@ -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);

View File

@ -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)) {

View File

@ -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();

View File

@ -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");

View File

@ -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({});
})); }));

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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
}; };

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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>

View File

@ -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>