mirror of
https://github.com/zadam/trilium.git
synced 2025-11-09 06:45:49 +01:00
moved all sources to src directory
This commit is contained in:
137
src/public/javascripts/dialogs/add_link.js
Normal file
137
src/public/javascripts/dialogs/add_link.js
Normal file
@@ -0,0 +1,137 @@
|
||||
"use strict";
|
||||
|
||||
const addLink = (function() {
|
||||
const dialogEl = $("#add-link-dialog");
|
||||
const formEl = $("#add-link-form");
|
||||
const autoCompleteEl = $("#note-autocomplete");
|
||||
const linkTitleEl = $("#link-title");
|
||||
const clonePrefixEl = $("#clone-prefix");
|
||||
const linkTitleFormGroup = $("#add-link-title-form-group");
|
||||
const prefixFormGroup = $("#add-link-prefix-form-group");
|
||||
const linkTypeEls = $("input[name='add-link-type']");
|
||||
const linkTypeHtmlEl = linkTypeEls.filter('input[value="html"]');
|
||||
|
||||
function setLinkType(linkType) {
|
||||
linkTypeEls.each(function () {
|
||||
$(this).prop('checked', $(this).val() === linkType);
|
||||
});
|
||||
|
||||
linkTypeChanged();
|
||||
}
|
||||
|
||||
function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
if (noteEditor.getCurrentNoteType() === 'text') {
|
||||
linkTypeHtmlEl.prop('disabled', false);
|
||||
|
||||
setLinkType('html');
|
||||
}
|
||||
else {
|
||||
linkTypeHtmlEl.prop('disabled', true);
|
||||
|
||||
setLinkType('selected-to-current');
|
||||
}
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 700
|
||||
});
|
||||
|
||||
autoCompleteEl.val('').focus();
|
||||
clonePrefixEl.val('');
|
||||
linkTitleEl.val('');
|
||||
|
||||
function setDefaultLinkTitle(noteId) {
|
||||
const noteTitle = noteTree.getNoteTitle(noteId);
|
||||
|
||||
linkTitleEl.val(noteTitle);
|
||||
}
|
||||
|
||||
autoCompleteEl.autocomplete({
|
||||
source: noteTree.getAutocompleteItems(),
|
||||
minLength: 0,
|
||||
change: () => {
|
||||
const val = autoCompleteEl.val();
|
||||
const notePath = link.getNodePathFromLabel(val);
|
||||
if (!notePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
|
||||
|
||||
if (noteId) {
|
||||
setDefaultLinkTitle(noteId);
|
||||
}
|
||||
},
|
||||
// this is called when user goes through autocomplete list with keyboard
|
||||
// at this point the item isn't selected yet so we use supplied ui.item to see WHERE the cursor is
|
||||
focus: (event, ui) => {
|
||||
const notePath = link.getNodePathFromLabel(ui.item.value);
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
|
||||
|
||||
setDefaultLinkTitle(noteId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
formEl.submit(() => {
|
||||
const value = autoCompleteEl.val();
|
||||
|
||||
const notePath = link.getNodePathFromLabel(value);
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
|
||||
|
||||
if (notePath) {
|
||||
const linkType = $("input[name='add-link-type']:checked").val();
|
||||
|
||||
if (linkType === 'html') {
|
||||
const linkTitle = linkTitleEl.val();
|
||||
|
||||
dialogEl.dialog("close");
|
||||
|
||||
link.addLinkToEditor(linkTitle, '#' + notePath);
|
||||
}
|
||||
else if (linkType === 'selected-to-current') {
|
||||
const prefix = clonePrefixEl.val();
|
||||
|
||||
cloning.cloneNoteTo(noteId, noteEditor.getCurrentNoteId(), prefix);
|
||||
|
||||
dialogEl.dialog("close");
|
||||
}
|
||||
else if (linkType === 'current-to-selected') {
|
||||
const prefix = clonePrefixEl.val();
|
||||
|
||||
cloning.cloneNoteTo(noteEditor.getCurrentNoteId(), noteId, prefix);
|
||||
|
||||
dialogEl.dialog("close");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
function linkTypeChanged() {
|
||||
const value = linkTypeEls.filter(":checked").val();
|
||||
|
||||
if (value === 'html') {
|
||||
linkTitleFormGroup.show();
|
||||
prefixFormGroup.hide();
|
||||
}
|
||||
else {
|
||||
linkTitleFormGroup.hide();
|
||||
prefixFormGroup.show();
|
||||
}
|
||||
}
|
||||
|
||||
linkTypeEls.change(linkTypeChanged);
|
||||
|
||||
$(document).bind('keydown', 'ctrl+l', e => {
|
||||
showDialog();
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
return {
|
||||
showDialog
|
||||
};
|
||||
})();
|
||||
62
src/public/javascripts/dialogs/attributes.js
Normal file
62
src/public/javascripts/dialogs/attributes.js
Normal file
@@ -0,0 +1,62 @@
|
||||
"use strict";
|
||||
|
||||
const attributesDialog = (function() {
|
||||
const dialogEl = $("#attributes-dialog");
|
||||
const attributesModel = new AttributesModel();
|
||||
|
||||
function AttributesModel() {
|
||||
const self = this;
|
||||
|
||||
this.attributes = ko.observableArray();
|
||||
|
||||
this.loadAttributes = async function() {
|
||||
const noteId = noteEditor.getCurrentNoteId();
|
||||
|
||||
const attributes = await server.get('notes/' + noteId + '/attributes');
|
||||
|
||||
this.attributes(attributes);
|
||||
};
|
||||
|
||||
this.addNewRow = function() {
|
||||
self.attributes.push({
|
||||
attributeId: '',
|
||||
name: '',
|
||||
value: ''
|
||||
});
|
||||
};
|
||||
|
||||
this.save = async function() {
|
||||
const noteId = noteEditor.getCurrentNoteId();
|
||||
|
||||
const attributes = await server.put('notes/' + noteId + '/attributes', this.attributes());
|
||||
|
||||
self.attributes(attributes);
|
||||
|
||||
showMessage("Attributes have been saved.");
|
||||
};
|
||||
}
|
||||
|
||||
async function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
height: 700
|
||||
});
|
||||
|
||||
attributesModel.loadAttributes();
|
||||
}
|
||||
|
||||
$(document).bind('keydown', 'alt+a', e => {
|
||||
showDialog();
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
ko.applyBindings(attributesModel, document.getElementById('attributes-dialog'));
|
||||
|
||||
return {
|
||||
showDialog
|
||||
};
|
||||
})();
|
||||
45
src/public/javascripts/dialogs/edit_tree_prefix.js
Normal file
45
src/public/javascripts/dialogs/edit_tree_prefix.js
Normal file
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
|
||||
const editTreePrefix = (function() {
|
||||
const dialogEl = $("#edit-tree-prefix-dialog");
|
||||
const formEl = $("#edit-tree-prefix-form");
|
||||
const treePrefixInputEl = $("#tree-prefix-input");
|
||||
const noteTitleEl = $('#tree-prefix-note-title');
|
||||
|
||||
let noteTreeId;
|
||||
|
||||
async function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
await dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 500
|
||||
});
|
||||
|
||||
const currentNode = noteTree.getCurrentNode();
|
||||
|
||||
noteTreeId = currentNode.data.noteTreeId;
|
||||
|
||||
treePrefixInputEl.val(currentNode.data.prefix).focus();
|
||||
|
||||
const noteTitle = noteTree.getNoteTitle(currentNode.data.noteId);
|
||||
|
||||
noteTitleEl.html(noteTitle);
|
||||
}
|
||||
|
||||
formEl.submit(() => {
|
||||
const prefix = treePrefixInputEl.val();
|
||||
|
||||
server.put('tree/' + noteTreeId + '/set-prefix', {
|
||||
prefix: prefix
|
||||
}).then(() => noteTree.setPrefix(noteTreeId, prefix));
|
||||
|
||||
dialogEl.dialog("close");
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return {
|
||||
showDialog
|
||||
};
|
||||
})();
|
||||
38
src/public/javascripts/dialogs/event_log.js
Normal file
38
src/public/javascripts/dialogs/event_log.js
Normal file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
|
||||
const eventLog = (function() {
|
||||
const dialogEl = $("#event-log-dialog");
|
||||
const listEl = $("#event-log-list");
|
||||
|
||||
async function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
height: 700
|
||||
});
|
||||
|
||||
const result = await server.get('event-log');
|
||||
|
||||
listEl.html('');
|
||||
|
||||
for (const event of result) {
|
||||
const dateTime = formatDateTime(parseDate(event.dateAdded));
|
||||
|
||||
if (event.noteId) {
|
||||
const noteLink = link.createNoteLink(event.noteId).prop('outerHTML');
|
||||
|
||||
event.comment = event.comment.replace('<note>', noteLink);
|
||||
}
|
||||
|
||||
const eventEl = $('<li>').html(dateTime + " - " + event.comment);
|
||||
|
||||
listEl.append(eventEl);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
showDialog
|
||||
};
|
||||
})();
|
||||
56
src/public/javascripts/dialogs/jump_to_note.js
Normal file
56
src/public/javascripts/dialogs/jump_to_note.js
Normal file
@@ -0,0 +1,56 @@
|
||||
"use strict";
|
||||
|
||||
const jumpToNote = (function() {
|
||||
const dialogEl = $("#jump-to-note-dialog");
|
||||
const autoCompleteEl = $("#jump-to-note-autocomplete");
|
||||
const formEl = $("#jump-to-note-form");
|
||||
|
||||
async function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
autoCompleteEl.val('');
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 800
|
||||
});
|
||||
|
||||
await autoCompleteEl.autocomplete({
|
||||
source: await stopWatch("building autocomplete", noteTree.getAutocompleteItems),
|
||||
minLength: 0
|
||||
});
|
||||
}
|
||||
|
||||
function getSelectedNotePath() {
|
||||
const val = autoCompleteEl.val();
|
||||
return link.getNodePathFromLabel(val);
|
||||
}
|
||||
|
||||
function goToNote() {
|
||||
const notePath = getSelectedNotePath();
|
||||
|
||||
if (notePath) {
|
||||
noteTree.activateNode(notePath);
|
||||
|
||||
dialogEl.dialog('close');
|
||||
}
|
||||
}
|
||||
|
||||
$(document).bind('keydown', 'ctrl+j', e => {
|
||||
showDialog();
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
formEl.submit(() => {
|
||||
const action = dialogEl.find("button:focus").val();
|
||||
|
||||
goToNote();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return {
|
||||
showDialog
|
||||
};
|
||||
})();
|
||||
78
src/public/javascripts/dialogs/note_history.js
Normal file
78
src/public/javascripts/dialogs/note_history.js
Normal file
@@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
|
||||
const noteHistory = (function() {
|
||||
const dialogEl = $("#note-history-dialog");
|
||||
const listEl = $("#note-history-list");
|
||||
const contentEl = $("#note-history-content");
|
||||
const titleEl = $("#note-history-title");
|
||||
|
||||
let historyItems = [];
|
||||
|
||||
async function showCurrentNoteHistory() {
|
||||
await showNoteHistoryDialog(noteEditor.getCurrentNoteId());
|
||||
}
|
||||
|
||||
async function showNoteHistoryDialog(noteId, noteRevisionId) {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
height: 700
|
||||
});
|
||||
|
||||
listEl.empty();
|
||||
contentEl.empty();
|
||||
|
||||
historyItems = await server.get('notes-history/' + noteId);
|
||||
|
||||
for (const item of historyItems) {
|
||||
const dateModified = parseDate(item.dateModifiedFrom);
|
||||
|
||||
listEl.append($('<option>', {
|
||||
value: item.noteRevisionId,
|
||||
text: formatDateTime(dateModified)
|
||||
}));
|
||||
}
|
||||
|
||||
if (historyItems.length > 0) {
|
||||
if (!noteRevisionId) {
|
||||
noteRevisionId = listEl.find("option:first").val();
|
||||
}
|
||||
|
||||
listEl.val(noteRevisionId).trigger('change');
|
||||
}
|
||||
else {
|
||||
titleEl.text("No history for this note yet...");
|
||||
}
|
||||
}
|
||||
|
||||
$(document).bind('keydown', 'alt+h', e => {
|
||||
showCurrentNoteHistory();
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
listEl.on('change', () => {
|
||||
const optVal = listEl.find(":selected").val();
|
||||
|
||||
const historyItem = historyItems.find(r => r.noteRevisionId === optVal);
|
||||
|
||||
titleEl.html(historyItem.title);
|
||||
contentEl.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;
|
||||
});
|
||||
|
||||
return {
|
||||
showCurrentNoteHistory
|
||||
};
|
||||
})();
|
||||
57
src/public/javascripts/dialogs/note_source.js
Normal file
57
src/public/javascripts/dialogs/note_source.js
Normal file
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
|
||||
const noteSource = (function() {
|
||||
const dialogEl = $("#note-source-dialog");
|
||||
const noteSourceEl = $("#note-source");
|
||||
|
||||
function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
height: 500
|
||||
});
|
||||
|
||||
const noteText = noteEditor.getCurrentNote().detail.content;
|
||||
|
||||
noteSourceEl.text(formatHtml(noteText));
|
||||
}
|
||||
|
||||
function formatHtml(str) {
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = str.trim();
|
||||
|
||||
return formatNode(div, 0).innerHTML.trim();
|
||||
}
|
||||
|
||||
function formatNode(node, level) {
|
||||
const indentBefore = new Array(level++ + 1).join(' ');
|
||||
const indentAfter = new Array(level - 1).join(' ');
|
||||
let textNode;
|
||||
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
textNode = document.createTextNode('\n' + indentBefore);
|
||||
node.insertBefore(textNode, node.children[i]);
|
||||
|
||||
formatNode(node.children[i], level);
|
||||
|
||||
if (node.lastElementChild === node.children[i]) {
|
||||
textNode = document.createTextNode('\n' + indentAfter);
|
||||
node.appendChild(textNode);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
$(document).bind('keydown', 'ctrl+u', e => {
|
||||
showDialog();
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
return {
|
||||
showDialog
|
||||
};
|
||||
})();
|
||||
89
src/public/javascripts/dialogs/recent_changes.js
Normal file
89
src/public/javascripts/dialogs/recent_changes.js
Normal file
@@ -0,0 +1,89 @@
|
||||
"use strict";
|
||||
|
||||
const recentChanges = (function() {
|
||||
const dialogEl = $("#recent-changes-dialog");
|
||||
|
||||
async function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
height: 700
|
||||
});
|
||||
|
||||
const result = await server.get('recent-changes/');
|
||||
|
||||
dialogEl.html('');
|
||||
|
||||
const groupedByDate = groupByDate(result);
|
||||
|
||||
for (const [dateDay, dayChanges] of groupedByDate) {
|
||||
const changesListEl = $('<ul>');
|
||||
|
||||
const dayEl = $('<div>').append($('<b>').html(formatDate(dateDay))).append(changesListEl);
|
||||
|
||||
for (const change of dayChanges) {
|
||||
const formattedTime = formatTime(parseDate(change.dateModifiedTo));
|
||||
|
||||
const revLink = $("<a>", {
|
||||
href: 'javascript:',
|
||||
text: 'rev'
|
||||
}).attr('action', 'note-history')
|
||||
.attr('note-path', change.noteId)
|
||||
.attr('note-history-id', change.noteRevisionId);
|
||||
|
||||
let noteLink;
|
||||
|
||||
if (change.current_isDeleted) {
|
||||
noteLink = change.current_title;
|
||||
}
|
||||
else {
|
||||
noteLink = link.createNoteLink(change.noteId, change.title);
|
||||
}
|
||||
|
||||
changesListEl.append($('<li>')
|
||||
.append(formattedTime + ' - ')
|
||||
.append(noteLink)
|
||||
.append(' (').append(revLink).append(')'));
|
||||
}
|
||||
|
||||
dialogEl.append(dayEl);
|
||||
}
|
||||
}
|
||||
|
||||
function groupByDate(result) {
|
||||
const groupedByDate = new Map();
|
||||
const dayCache = {};
|
||||
|
||||
for (const row of result) {
|
||||
let dateDay = parseDate(row.dateModifiedTo);
|
||||
dateDay.setHours(0);
|
||||
dateDay.setMinutes(0);
|
||||
dateDay.setSeconds(0);
|
||||
dateDay.setMilliseconds(0);
|
||||
|
||||
// this stupidity is to make sure that we always use the same day object because Map uses only
|
||||
// reference equality
|
||||
if (dayCache[dateDay]) {
|
||||
dateDay = dayCache[dateDay];
|
||||
}
|
||||
else {
|
||||
dayCache[dateDay] = dateDay;
|
||||
}
|
||||
|
||||
if (!groupedByDate.has(dateDay)) {
|
||||
groupedByDate.set(dateDay, []);
|
||||
}
|
||||
|
||||
groupedByDate.get(dateDay).push(row);
|
||||
}
|
||||
return groupedByDate;
|
||||
}
|
||||
|
||||
$(document).bind('keydown', 'alt+r', showDialog);
|
||||
|
||||
return {
|
||||
showDialog
|
||||
};
|
||||
})();
|
||||
146
src/public/javascripts/dialogs/recent_notes.js
Normal file
146
src/public/javascripts/dialogs/recent_notes.js
Normal file
@@ -0,0 +1,146 @@
|
||||
"use strict";
|
||||
|
||||
const recentNotes = (function() {
|
||||
const dialogEl = $("#recent-notes-dialog");
|
||||
const selectBoxEl = $('#recent-notes-select-box');
|
||||
const jumpToButtonEl = $('#recent-notes-jump-to');
|
||||
const addLinkButtonEl = $('#recent-notes-add-link');
|
||||
const addCurrentAsChildEl = $("#recent-notes-add-current-as-child");
|
||||
const addRecentAsChildEl = $("#recent-notes-add-recent-as-child");
|
||||
const noteDetailEl = $('#note-detail');
|
||||
// list of recent note paths
|
||||
let list = [];
|
||||
|
||||
async function reload() {
|
||||
const result = await server.get('recent-notes');
|
||||
|
||||
list = result.map(r => r.notePath);
|
||||
}
|
||||
|
||||
function addRecentNote(noteTreeId, notePath) {
|
||||
setTimeout(async () => {
|
||||
// we include the note into recent list only if the user stayed on the note at least 5 seconds
|
||||
if (notePath && notePath === noteTree.getCurrentNotePath()) {
|
||||
const result = await server.put('recent-notes/' + noteTreeId + '/' + encodeURIComponent(notePath));
|
||||
|
||||
list = result.map(r => r.notePath);
|
||||
}
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 800
|
||||
});
|
||||
|
||||
selectBoxEl.find('option').remove();
|
||||
|
||||
// remove the current note
|
||||
const recNotes = list.filter(note => note !== noteTree.getCurrentNotePath());
|
||||
|
||||
$.each(recNotes, (key, valueNotePath) => {
|
||||
const noteTitle = noteTree.getNotePathTitle(valueNotePath);
|
||||
|
||||
const option = $("<option></option>")
|
||||
.attr("value", valueNotePath)
|
||||
.text(noteTitle);
|
||||
|
||||
// select the first one (most recent one) by default
|
||||
if (key === 0) {
|
||||
option.attr("selected", "selected");
|
||||
}
|
||||
|
||||
selectBoxEl.append(option);
|
||||
});
|
||||
}
|
||||
|
||||
function getSelectedNotePath() {
|
||||
return selectBoxEl.find("option:selected").val();
|
||||
}
|
||||
|
||||
function getSelectedNoteId() {
|
||||
const notePath = getSelectedNotePath();
|
||||
return treeUtils.getNoteIdFromNotePath(notePath);
|
||||
}
|
||||
|
||||
function setActiveNoteBasedOnRecentNotes() {
|
||||
const notePath = getSelectedNotePath();
|
||||
|
||||
noteTree.activateNode(notePath);
|
||||
|
||||
dialogEl.dialog('close');
|
||||
}
|
||||
|
||||
function addLinkBasedOnRecentNotes() {
|
||||
const notePath = getSelectedNotePath();
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
|
||||
|
||||
const linkTitle = noteTree.getNoteTitle(noteId);
|
||||
|
||||
dialogEl.dialog("close");
|
||||
|
||||
link.addLinkToEditor(linkTitle, '#' + notePath);
|
||||
}
|
||||
|
||||
async function addCurrentAsChild() {
|
||||
await cloning.cloneNoteTo(noteEditor.getCurrentNoteId(), getSelectedNoteId());
|
||||
|
||||
dialogEl.dialog("close");
|
||||
}
|
||||
|
||||
async function addRecentAsChild() {
|
||||
await cloning.cloneNoteTo(getSelectedNoteId(), noteEditor.getCurrentNoteId());
|
||||
|
||||
dialogEl.dialog("close");
|
||||
}
|
||||
|
||||
selectBoxEl.keydown(e => {
|
||||
const key = e.which;
|
||||
|
||||
// to get keycodes use http://keycode.info/
|
||||
if (key === 13)// the enter key code
|
||||
{
|
||||
setActiveNoteBasedOnRecentNotes();
|
||||
}
|
||||
else if (key === 76 /* l */) {
|
||||
addLinkBasedOnRecentNotes();
|
||||
}
|
||||
else if (key === 67 /* c */) {
|
||||
addCurrentAsChild();
|
||||
}
|
||||
else if (key === 82 /* r */) {
|
||||
addRecentAsChild()
|
||||
}
|
||||
else {
|
||||
return; // avoid prevent default
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
reload();
|
||||
|
||||
$(document).bind('keydown', 'ctrl+e', e => {
|
||||
showDialog();
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
selectBoxEl.dblclick(e => {
|
||||
setActiveNoteBasedOnRecentNotes();
|
||||
});
|
||||
|
||||
jumpToButtonEl.click(setActiveNoteBasedOnRecentNotes);
|
||||
addLinkButtonEl.click(addLinkBasedOnRecentNotes);
|
||||
addCurrentAsChildEl.click(addCurrentAsChild);
|
||||
addRecentAsChildEl.click(addRecentAsChild);
|
||||
|
||||
return {
|
||||
showDialog,
|
||||
addRecentNote,
|
||||
reload
|
||||
};
|
||||
})();
|
||||
205
src/public/javascripts/dialogs/settings.js
Normal file
205
src/public/javascripts/dialogs/settings.js
Normal file
@@ -0,0 +1,205 @@
|
||||
"use strict";
|
||||
|
||||
const settings = (function() {
|
||||
const dialogEl = $("#settings-dialog");
|
||||
const tabsEl = $("#settings-tabs");
|
||||
|
||||
const settingModules = [];
|
||||
|
||||
function addModule(module) {
|
||||
settingModules.push(module);
|
||||
}
|
||||
|
||||
async function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
const settings = await server.get('settings');
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: 900
|
||||
});
|
||||
|
||||
tabsEl.tabs();
|
||||
|
||||
for (const module of settingModules) {
|
||||
if (module.settingsLoaded) {
|
||||
module.settingsLoaded(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function saveSettings(settingName, settingValue) {
|
||||
await server.post('settings', {
|
||||
name: settingName,
|
||||
value: settingValue
|
||||
});
|
||||
|
||||
showMessage("Settings change have been saved.");
|
||||
}
|
||||
|
||||
return {
|
||||
showDialog,
|
||||
saveSettings,
|
||||
addModule
|
||||
};
|
||||
})();
|
||||
|
||||
settings.addModule((function() {
|
||||
const formEl = $("#change-password-form");
|
||||
const oldPasswordEl = $("#old-password");
|
||||
const newPassword1El = $("#new-password1");
|
||||
const newPassword2El = $("#new-password2");
|
||||
|
||||
function settingsLoaded(settings) {
|
||||
}
|
||||
|
||||
formEl.submit(() => {
|
||||
const oldPassword = oldPasswordEl.val();
|
||||
const newPassword1 = newPassword1El.val();
|
||||
const newPassword2 = newPassword2El.val();
|
||||
|
||||
oldPasswordEl.val('');
|
||||
newPassword1El.val('');
|
||||
newPassword2El.val('');
|
||||
|
||||
if (newPassword1 !== newPassword2) {
|
||||
alert("New passwords are not the same.");
|
||||
return false;
|
||||
}
|
||||
|
||||
server.post('password/change', {
|
||||
'current_password': oldPassword,
|
||||
'new_password': newPassword1
|
||||
}).then(result => {
|
||||
if (result.success) {
|
||||
alert("Password has been changed. Trilium will be reloaded after you press OK.");
|
||||
|
||||
// password changed so current protected session is invalid and needs to be cleared
|
||||
protected_session.resetProtectedSession();
|
||||
}
|
||||
else {
|
||||
showError(result.message);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return {
|
||||
settingsLoaded
|
||||
};
|
||||
})());
|
||||
|
||||
settings.addModule((function() {
|
||||
const formEl = $("#protected-session-timeout-form");
|
||||
const protectedSessionTimeoutEl = $("#protected-session-timeout-in-seconds");
|
||||
const settingName = 'protected_session_timeout';
|
||||
|
||||
function settingsLoaded(settings) {
|
||||
protectedSessionTimeoutEl.val(settings[settingName]);
|
||||
}
|
||||
|
||||
formEl.submit(() => {
|
||||
const protectedSessionTimeout = protectedSessionTimeoutEl.val();
|
||||
|
||||
settings.saveSettings(settingName, protectedSessionTimeout).then(() => {
|
||||
protected_session.setProtectedSessionTimeout(protectedSessionTimeout);
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return {
|
||||
settingsLoaded
|
||||
};
|
||||
})());
|
||||
|
||||
settings.addModule((function () {
|
||||
const formEl = $("#history-snapshot-time-interval-form");
|
||||
const timeIntervalEl = $("#history-snapshot-time-interval-in-seconds");
|
||||
const settingName = 'history_snapshot_time_interval';
|
||||
|
||||
function settingsLoaded(settings) {
|
||||
timeIntervalEl.val(settings[settingName]);
|
||||
}
|
||||
|
||||
formEl.submit(() => {
|
||||
settings.saveSettings(settingName, timeIntervalEl.val());
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return {
|
||||
settingsLoaded
|
||||
};
|
||||
})());
|
||||
|
||||
settings.addModule((async function () {
|
||||
const appVersionEl = $("#app-version");
|
||||
const dbVersionEl = $("#db-version");
|
||||
const buildDateEl = $("#build-date");
|
||||
const buildRevisionEl = $("#build-revision");
|
||||
|
||||
const appInfo = await server.get('app-info');
|
||||
|
||||
appVersionEl.html(appInfo.app_version);
|
||||
dbVersionEl.html(appInfo.db_version);
|
||||
buildDateEl.html(appInfo.build_date);
|
||||
buildRevisionEl.html(appInfo.build_revision);
|
||||
buildRevisionEl.attr('href', 'https://github.com/zadam/trilium/commit/' + appInfo.build_revision);
|
||||
|
||||
return {};
|
||||
})());
|
||||
|
||||
settings.addModule((async function () {
|
||||
const forceFullSyncButton = $("#force-full-sync-button");
|
||||
const fillSyncRowsButton = $("#fill-sync-rows-button");
|
||||
const anonymizeButton = $("#anonymize-button");
|
||||
const cleanupSoftDeletedButton = $("#cleanup-soft-deleted-items-button");
|
||||
const cleanupUnusedImagesButton = $("#cleanup-unused-images-button");
|
||||
const vacuumDatabaseButton = $("#vacuum-database-button");
|
||||
|
||||
forceFullSyncButton.click(async () => {
|
||||
await server.post('sync/force-full-sync');
|
||||
|
||||
showMessage("Full sync triggered");
|
||||
});
|
||||
|
||||
fillSyncRowsButton.click(async () => {
|
||||
await server.post('sync/fill-sync-rows');
|
||||
|
||||
showMessage("Sync rows filled successfully");
|
||||
});
|
||||
|
||||
|
||||
anonymizeButton.click(async () => {
|
||||
await server.post('anonymization/anonymize');
|
||||
|
||||
showMessage("Created anonymized database");
|
||||
});
|
||||
|
||||
cleanupSoftDeletedButton.click(async () => {
|
||||
if (confirm("Do you really want to clean up soft-deleted items?")) {
|
||||
await server.post('cleanup/cleanup-soft-deleted-items');
|
||||
|
||||
showMessage("Soft deleted items have been cleaned up");
|
||||
}
|
||||
});
|
||||
|
||||
cleanupUnusedImagesButton.click(async () => {
|
||||
if (confirm("Do you really want to clean up unused images?")) {
|
||||
await server.post('cleanup/cleanup-unused-images');
|
||||
|
||||
showMessage("Unused images have been cleaned up");
|
||||
}
|
||||
});
|
||||
|
||||
vacuumDatabaseButton.click(async () => {
|
||||
await server.post('cleanup/vacuum-database');
|
||||
|
||||
showMessage("Database has been vacuumed");
|
||||
});
|
||||
|
||||
return {};
|
||||
})());
|
||||
71
src/public/javascripts/dialogs/sql_console.js
Normal file
71
src/public/javascripts/dialogs/sql_console.js
Normal file
@@ -0,0 +1,71 @@
|
||||
"use strict";
|
||||
|
||||
const sqlConsole = (function() {
|
||||
const dialogEl = $("#sql-console-dialog");
|
||||
const queryEl = $('#sql-console-query');
|
||||
const executeButton = $('#sql-console-execute');
|
||||
const resultHeadEl = $('#sql-console-results thead');
|
||||
const resultBodyEl = $('#sql-console-results tbody');
|
||||
|
||||
function showDialog() {
|
||||
glob.activeDialog = dialogEl;
|
||||
|
||||
dialogEl.dialog({
|
||||
modal: true,
|
||||
width: $(window).width(),
|
||||
height: $(window).height()
|
||||
});
|
||||
}
|
||||
|
||||
async function execute() {
|
||||
const sqlQuery = queryEl.val();
|
||||
|
||||
const result = await server.post("sql/execute", {
|
||||
query: sqlQuery
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
showError(result.error);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
showMessage("Query was executed successfully.");
|
||||
}
|
||||
|
||||
const rows = result.rows;
|
||||
|
||||
resultHeadEl.empty();
|
||||
resultBodyEl.empty();
|
||||
|
||||
if (rows.length > 0) {
|
||||
const result = rows[0];
|
||||
const rowEl = $("<tr>");
|
||||
|
||||
for (const key in result) {
|
||||
rowEl.append($("<th>").html(key));
|
||||
}
|
||||
|
||||
resultHeadEl.append(rowEl);
|
||||
}
|
||||
|
||||
for (const result of rows) {
|
||||
const rowEl = $("<tr>");
|
||||
|
||||
for (const key in result) {
|
||||
rowEl.append($("<td>").html(result[key]));
|
||||
}
|
||||
|
||||
resultBodyEl.append(rowEl);
|
||||
}
|
||||
}
|
||||
|
||||
$(document).bind('keydown', 'alt+o', showDialog);
|
||||
|
||||
queryEl.bind('keydown', 'ctrl+return', execute);
|
||||
|
||||
executeButton.click(execute);
|
||||
|
||||
return {
|
||||
showDialog
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user