mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
adding clone from recent notes dialog
This commit is contained in:
parent
00151beded
commit
3610926804
24
migrations/0042__remove_unique_index_on_note_id.sql
Normal file
24
migrations/0042__remove_unique_index_on_note_id.sql
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
CREATE TABLE "notes_tree_mig" (
|
||||||
|
[note_tree_id] VARCHAR(30) PRIMARY KEY NOT NULL,
|
||||||
|
[note_id] VARCHAR(30) NOT NULL,
|
||||||
|
[note_pid] VARCHAR(30) NOT NULL,
|
||||||
|
[note_pos] INTEGER NOT NULL,
|
||||||
|
[is_expanded] BOOLEAN NULL ,
|
||||||
|
date_modified INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_deleted INTEGER NOT NULL DEFAULT 0
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO notes_tree_mig (note_tree_id, note_id, note_pid, note_pos, is_expanded, date_modified, is_deleted)
|
||||||
|
SELECT note_tree_id, note_id, note_pid, note_pos, is_expanded, date_modified, is_deleted FROM notes_tree;
|
||||||
|
|
||||||
|
DROP TABLE notes_tree;
|
||||||
|
ALTER TABLE notes_tree_mig RENAME TO notes_tree;
|
||||||
|
|
||||||
|
CREATE INDEX `IDX_notes_tree_note_tree_id` ON `notes_tree` (
|
||||||
|
`note_tree_id`
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX `IDX_notes_tree_note_id_note_pid` ON `notes_tree` (
|
||||||
|
`note_id`,
|
||||||
|
`note_pid`
|
||||||
|
);
|
@ -5,6 +5,8 @@ const recentNotes = (function() {
|
|||||||
const selectBoxEl = $('#recent-notes-select-box');
|
const selectBoxEl = $('#recent-notes-select-box');
|
||||||
const jumpToButtonEl = $('#recentNotesJumpTo');
|
const jumpToButtonEl = $('#recentNotesJumpTo');
|
||||||
const addLinkButtonEl = $('#recentNotesAddLink');
|
const addLinkButtonEl = $('#recentNotesAddLink');
|
||||||
|
const addCurrentAsChildEl = $("#recent-notes-add-current-as-child");
|
||||||
|
const addRecentAsChildEl = $("#recent-notes-add-recent-as-child");
|
||||||
const noteDetailEl = $('#note-detail');
|
const noteDetailEl = $('#note-detail');
|
||||||
let list = [];
|
let list = [];
|
||||||
|
|
||||||
@ -31,9 +33,10 @@ const recentNotes = (function() {
|
|||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: this should be probably just refresh upon deletion, not explicit delete
|
||||||
function removeRecentNote(notePathIdToRemove) {
|
function removeRecentNote(notePathIdToRemove) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: baseApiUrl + 'recent-notes/' + notePathIdToRemove,
|
url: baseApiUrl + 'recent-notes/' + encodeURIComponent(notePathIdToRemove),
|
||||||
type: 'DELETE',
|
type: 'DELETE',
|
||||||
error: () => showError("Error removing note from recent notes.")
|
error: () => showError("Error removing note from recent notes.")
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
@ -72,12 +75,12 @@ const recentNotes = (function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectedNotePathFromRecentNotes() {
|
function getSelectedNotePath() {
|
||||||
return selectBoxEl.find("option:selected").val();
|
return selectBoxEl.find("option:selected").val();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setActiveNoteBasedOnRecentNotes() {
|
function setActiveNoteBasedOnRecentNotes() {
|
||||||
const notePath = getSelectedNotePathFromRecentNotes();
|
const notePath = getSelectedNotePath();
|
||||||
|
|
||||||
noteTree.activateNode(notePath);
|
noteTree.activateNode(notePath);
|
||||||
|
|
||||||
@ -85,9 +88,9 @@ const recentNotes = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addLinkBasedOnRecentNotes() {
|
function addLinkBasedOnRecentNotes() {
|
||||||
const notePath = getSelectedNotePathFromRecentNotes();
|
const notePath = getSelectedNotePath();
|
||||||
|
|
||||||
const linkTitle = treeUtils.getNoteTitle(notePath);
|
const linkTitle = noteTree.getNoteTitle(notePath);
|
||||||
|
|
||||||
dialogEl.dialog("close");
|
dialogEl.dialog("close");
|
||||||
|
|
||||||
@ -100,9 +103,33 @@ const recentNotes = (function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addAsChild(parentNotePath, childNotePath) {
|
||||||
|
const parentNoteId = treeUtils.getNoteIdFromNotePath(parentNotePath);
|
||||||
|
const childNoteId = treeUtils.getNoteIdFromNotePath(childNotePath);
|
||||||
|
|
||||||
|
await $.ajax({
|
||||||
|
url: baseApiUrl + 'tree/' + parentNoteId + '/addChild/' + childNoteId,
|
||||||
|
type: 'PUT',
|
||||||
|
error: () => showError("Error adding child.")
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogEl.dialog("close");
|
||||||
|
|
||||||
|
await noteTree.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addCurrentAsChild() {
|
||||||
|
await addAsChild(getSelectedNotePath(), noteTree.getCurrentNotePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addRecentAsChild() {
|
||||||
|
addAsChild(noteTree.getCurrentNotePath(), getSelectedNotePath());
|
||||||
|
}
|
||||||
|
|
||||||
selectBoxEl.keydown(e => {
|
selectBoxEl.keydown(e => {
|
||||||
const key = e.which;
|
const key = e.which;
|
||||||
|
|
||||||
|
// to get keycodes use http://keycode.info/
|
||||||
if (key === 13)// the enter key code
|
if (key === 13)// the enter key code
|
||||||
{
|
{
|
||||||
setActiveNoteBasedOnRecentNotes();
|
setActiveNoteBasedOnRecentNotes();
|
||||||
@ -110,6 +137,12 @@ const recentNotes = (function() {
|
|||||||
else if (key === 76 /* l */) {
|
else if (key === 76 /* l */) {
|
||||||
addLinkBasedOnRecentNotes();
|
addLinkBasedOnRecentNotes();
|
||||||
}
|
}
|
||||||
|
else if (key === 67 /* c */) {
|
||||||
|
addCurrentAsChild();
|
||||||
|
}
|
||||||
|
else if (key === 82 /* r */) {
|
||||||
|
addRecentAsChild()
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return; // avoid prevent default
|
return; // avoid prevent default
|
||||||
}
|
}
|
||||||
@ -125,6 +158,8 @@ const recentNotes = (function() {
|
|||||||
|
|
||||||
jumpToButtonEl.click(setActiveNoteBasedOnRecentNotes);
|
jumpToButtonEl.click(setActiveNoteBasedOnRecentNotes);
|
||||||
addLinkButtonEl.click(addLinkBasedOnRecentNotes);
|
addLinkButtonEl.click(addLinkBasedOnRecentNotes);
|
||||||
|
addCurrentAsChildEl.click(addCurrentAsChild);
|
||||||
|
addRecentAsChildEl.click(addRecentAsChild);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
showDialog,
|
showDialog,
|
||||||
|
@ -256,10 +256,12 @@ const noteTree = (function() {
|
|||||||
setExpandedToServer(getNoteTreeIdFromKey(data.node.key), false);
|
setExpandedToServer(getNoteTreeIdFromKey(data.node.key), false);
|
||||||
},
|
},
|
||||||
init: (event, data) => {
|
init: (event, data) => {
|
||||||
showAppIfHidden();
|
|
||||||
if (startNoteTreeId) {
|
if (startNoteTreeId) {
|
||||||
activateNode(startNoteTreeId);
|
activateNode(startNoteTreeId);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
showAppIfHidden();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
hotkeys: {
|
hotkeys: {
|
||||||
keydown: keybindings
|
keydown: keybindings
|
||||||
|
@ -6,10 +6,10 @@ const sql = require('../../services/sql');
|
|||||||
const options = require('../../services/options');
|
const options = require('../../services/options');
|
||||||
const utils = require('../../services/utils');
|
const utils = require('../../services/utils');
|
||||||
const auth = require('../../services/auth');
|
const auth = require('../../services/auth');
|
||||||
const log = require('../../services/log');
|
|
||||||
const protected_session = require('../../services/protected_session');
|
const protected_session = require('../../services/protected_session');
|
||||||
const data_encryption = require('../../services/data_encryption');
|
const data_encryption = require('../../services/data_encryption');
|
||||||
const notes = require('../../services/notes');
|
const notes = require('../../services/notes');
|
||||||
|
const sync_table = require('../../services/sync_table');
|
||||||
|
|
||||||
router.get('/', auth.checkApiAuth, async (req, res, next) => {
|
router.get('/', auth.checkApiAuth, async (req, res, next) => {
|
||||||
const notes = await sql.getResults("select "
|
const notes = await sql.getResults("select "
|
||||||
@ -48,4 +48,37 @@ router.put('/:noteId/protectSubTree/:isProtected', auth.checkApiAuth, async (req
|
|||||||
res.send({});
|
res.send({});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.put('/:parentNoteId/addChild/:childNoteId', auth.checkApiAuth, async (req, res, next) => {
|
||||||
|
const parentNoteId = req.params.parentNoteId;
|
||||||
|
const childNoteId = req.params.childNoteId;
|
||||||
|
|
||||||
|
const existing = await sql.getSingleValue('select * from notes_tree where note_id = ? and note_pid = ?', [childNoteId, parentNoteId]);
|
||||||
|
|
||||||
|
if (!existing) {
|
||||||
|
const maxNotePos = await sql.getSingleValue('select max(note_pos) from notes_tree where note_pid = ? and is_deleted = 0', [parentNoteId]);
|
||||||
|
const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
|
||||||
|
|
||||||
|
const noteTreeId = utils.newNoteTreeId();
|
||||||
|
|
||||||
|
await sql.doInTransaction(async () => {
|
||||||
|
await sync_table.addNoteTreeSync(noteTreeId);
|
||||||
|
|
||||||
|
await sql.insert("notes_tree", {
|
||||||
|
'note_tree_id': noteTreeId,
|
||||||
|
'note_id': childNoteId,
|
||||||
|
'note_pid': parentNoteId,
|
||||||
|
'note_pos': newNotePos,
|
||||||
|
'is_expanded': 0,
|
||||||
|
'date_modified': utils.nowTimestamp(),
|
||||||
|
'is_deleted': 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (existing && existing.is_deleted) {
|
||||||
|
await sql.execute("UPDATE notes_tree SET is_deleted = 0 WHERE note_tree_id = ?", [existing.note_tree_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({});
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -4,7 +4,7 @@ const options = require('./options');
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const log = require('./log');
|
const log = require('./log');
|
||||||
|
|
||||||
const APP_DB_VERSION = 41;
|
const APP_DB_VERSION = 42;
|
||||||
const MIGRATIONS_DIR = "migrations";
|
const MIGRATIONS_DIR = "migrations";
|
||||||
|
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
|
@ -13,8 +13,7 @@ async function createNewNote(parentNoteId, note, browserId) {
|
|||||||
let newNotePos = 0;
|
let newNotePos = 0;
|
||||||
|
|
||||||
if (note.target === 'into') {
|
if (note.target === 'into') {
|
||||||
const res = await sql.getSingleResult('select max(note_pos) as max_note_pos from notes_tree where note_pid = ? and is_deleted = 0', [parentNoteId]);
|
const maxNotePos = await sql.getSingleValue('select max(note_pos) from notes_tree where note_pid = ? and is_deleted = 0', [parentNoteId]);
|
||||||
const maxNotePos = res['max_note_pos'];
|
|
||||||
|
|
||||||
if (maxNotePos === null) // no children yet
|
if (maxNotePos === null) // no children yet
|
||||||
newNotePos = 0;
|
newNotePos = 0;
|
||||||
@ -36,7 +35,7 @@ async function createNewNote(parentNoteId, note, browserId) {
|
|||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
await sql.addAudit(audit_category.CREATE_NOTE, browserId, noteId);
|
await sql.addAudit(audit_category.CREATE_NOTE, browserId, noteId);
|
||||||
await sync_table.addNoteTreeSync(noteId);
|
await sync_table.addNoteTreeSync(noteTreeId);
|
||||||
await sync_table.addNoteSync(noteId);
|
await sync_table.addNoteSync(noteId);
|
||||||
|
|
||||||
const now = utils.nowTimestamp();
|
const now = utils.nowTimestamp();
|
||||||
@ -56,7 +55,7 @@ async function createNewNote(parentNoteId, note, browserId) {
|
|||||||
'note_pid': parentNoteId,
|
'note_pid': parentNoteId,
|
||||||
'note_pos': newNotePos,
|
'note_pos': newNotePos,
|
||||||
'is_expanded': 0,
|
'is_expanded': 0,
|
||||||
'date_modified': utils.nowTimestamp(),
|
'date_modified': now,
|
||||||
'is_deleted': 0
|
'is_deleted': 0
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -107,6 +107,10 @@
|
|||||||
<button class="btn btn-sm" id="recent-notes-jump-to">Jump to (enter)</button>
|
<button class="btn btn-sm" id="recent-notes-jump-to">Jump to (enter)</button>
|
||||||
|
|
||||||
<button class="btn btn-sm" id="recent-notes-add-link">Add link (l)</button>
|
<button class="btn btn-sm" id="recent-notes-add-link">Add link (l)</button>
|
||||||
|
|
||||||
|
<button class="btn btn-sm" id="recent-notes-add-current-as-child">Add current as child (c)</button>
|
||||||
|
|
||||||
|
<button class="btn btn-sm" id="recent-notes-add-recent-as-child">Add recent as child (r)</button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user