diff --git a/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml b/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml
index 0e12ce82d..953e5646b 100644
--- a/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml
+++ b/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml
@@ -10,10 +10,10 @@
), then just make it empty @@ -96,32 +98,32 @@ function updateNoteFromInputs(note) { content = ''; } - note.detail.content = content; + note.content = content; } - else if (note.detail.type === 'code') { - note.detail.content = codeEditor.getValue(); + else if (note.type === 'code') { + note.content = codeEditor.getValue(); } - else if (note.detail.type === 'search') { - note.detail.content = JSON.stringify({ + else if (note.type === 'search') { + note.content = JSON.stringify({ searchString: $searchString.val() }); } - else if (note.detail.type === 'render' || note.detail.type === 'file') { + else if (note.type === 'render' || note.type === 'file') { // nothing } else { - infoService.throwError("Unrecognized type: " + note.detail.type); + infoService.throwError("Unrecognized type: " + note.type); } const title = $noteTitle.val(); - note.detail.title = title; + note.title = title; - treeService.setNoteTitle(note.detail.noteId, title); + treeService.setNoteTitle(note.noteId, title); } async function saveNoteToServer(note) { - await server.put('notes/' + note.detail.noteId, note); + await server.put('notes/' + note.noteId, note); isNoteChanged = false; @@ -129,7 +131,7 @@ async function saveNoteToServer(note) { } function setNoteBackgroundIfProtected(note) { - const isProtected = !!note.detail.isProtected; + const isProtected = !!note.isProtected; $noteDetailWrapper.toggleClass("protected", isProtected); $protectButton.toggle(!isProtected); @@ -143,7 +145,7 @@ function newNoteCreated() { } async function setContent(content) { - if (currentNote.detail.type === 'text') { + if (currentNote.type === 'text') { if (!editor) { await utils.requireLibrary(utils.CKEDITOR); @@ -157,7 +159,7 @@ async function setContent(content) { $noteDetail.show(); } - else if (currentNote.detail.type === 'code') { + else if (currentNote.type === 'code') { if (!codeEditor) { await utils.requireLibrary(utils.CODE_MIRROR); @@ -186,7 +188,7 @@ async function setContent(content) { // this needs to happen after the element is shown, otherwise the editor won't be refresheds codeEditor.setValue(content); - const info = CodeMirror.findModeByMIME(currentNote.detail.mime); + const info = CodeMirror.findModeByMIME(currentNote.mime); if (info) { codeEditor.setOption("mode", info.mime); @@ -195,7 +197,7 @@ async function setContent(content) { codeEditor.refresh(); } - else if (currentNote.detail.type === 'search') { + else if (currentNote.type === 'search') { $noteDetailSearch.show(); try { @@ -223,9 +225,9 @@ async function loadNoteToEditor(noteId) { $noteIdDisplay.html(noteId); - await protectedSessionService.ensureProtectedSession(currentNote.detail.isProtected, false); + await protectedSessionService.ensureProtectedSession(currentNote.isProtected, false); - if (currentNote.detail.isProtected) { + if (currentNote.isProtected) { protectedSessionHolder.touchProtectedSession(); } @@ -237,10 +239,10 @@ async function loadNoteToEditor(noteId) { noteChangeDisabled = true; - $noteTitle.val(currentNote.detail.title); + $noteTitle.val(currentNote.title); - noteTypeService.setNoteType(currentNote.detail.type); - noteTypeService.setNoteMime(currentNote.detail.mime); + noteTypeService.setNoteType(currentNote.type); + noteTypeService.setNoteMime(currentNote.mime); $noteDetail.hide(); $noteDetailSearch.hide(); @@ -248,7 +250,7 @@ async function loadNoteToEditor(noteId) { $noteDetailRender.html('').hide(); $noteDetailAttachment.hide(); - if (currentNote.detail.type === 'render') { + if (currentNote.type === 'render') { $noteDetailRender.show(); const bundle = await server.get('script/bundle/' + getCurrentNoteId()); @@ -257,15 +259,18 @@ async function loadNoteToEditor(noteId) { bundleService.executeBundle(bundle); } - else if (currentNote.detail.type === 'file') { + else if (currentNote.type === 'file') { + const labels = await server.get('notes/' + currentNote.noteId + '/labels'); + const labelMap = utils.toObject(labels, l => [l.name, l.value]); + $noteDetailAttachment.show(); - $attachmentFileName.text(currentNote.labels.original_file_name); - $attachmentFileSize.text(currentNote.labels.file_size + " bytes"); - $attachmentFileType.text(currentNote.detail.mime); + $attachmentFileName.text(labelMap.original_file_name); + $attachmentFileSize.text(labelMap.file_size + " bytes"); + $attachmentFileType.text(currentNote.mime); } else { - await setContent(currentNote.detail.content); + await setContent(currentNote.content); } noteChangeDisabled = false; @@ -299,7 +304,9 @@ async function loadLabelList() { } async function loadNote(noteId) { - return await server.get('notes/' + noteId); + const row = await server.get('notes/' + noteId); + + return new NoteFull(treeCache, row); } function getEditor() { @@ -309,24 +316,24 @@ function getEditor() { function focus() { const note = getCurrentNote(); - if (note.detail.type === 'text') { + if (note.type === 'text') { $noteDetail.focus(); } - else if (note.detail.type === 'code') { + else if (note.type === 'code') { codeEditor.focus(); } - else if (note.detail.type === 'render' || note.detail.type === 'file' || note.detail.type === 'search') { + else if (note.type === 'render' || note.type === 'file' || note.type === 'search') { // do nothing } else { - infoService.throwError('Unrecognized type: ' + note.detail.type); + infoService.throwError('Unrecognized type: ' + note.type); } } function getCurrentNoteType() { const currentNote = getCurrentNote(); - return currentNote ? currentNote.detail.type : null; + return currentNote ? currentNote.type : null; } async function executeCurrentNote() { @@ -334,13 +341,13 @@ async function executeCurrentNote() { // make sure note is saved so we load latest changes await saveNoteIfChanged(); - if (currentNote.detail.mime.endsWith("env=frontend")) { + if (currentNote.mime.endsWith("env=frontend")) { const bundle = await server.get('script/bundle/' + getCurrentNoteId()); bundleService.executeBundle(bundle); } - if (currentNote.detail.mime.endsWith("env=backend")) { + if (currentNote.mime.endsWith("env=backend")) { await server.post('script/run/' + getCurrentNoteId()); } diff --git a/src/public/javascripts/services/note_type.js b/src/public/javascripts/services/note_type.js index 127de49c3..8ae1b2f47 100644 --- a/src/public/javascripts/services/note_type.js +++ b/src/public/javascripts/services/note_type.js @@ -1,6 +1,6 @@ import treeService from './tree.js'; import noteDetail from './note_detail.js'; -import utils from './utils.js'; +import server from './server.js'; import infoService from "./info.js"; const $executeScriptButton = $("#execute-script-button"); @@ -86,7 +86,7 @@ function NoteTypeModel() { async function save() { const note = noteDetail.getCurrentNote(); - await server.put('notes/' + note.detail.noteId + await server.put('notes/' + note.noteId + '/type/' + encodeURIComponent(self.type()) + '/mime/' + encodeURIComponent(self.mime())); diff --git a/src/public/javascripts/services/protected_session.js b/src/public/javascripts/services/protected_session.js index cddbe619d..9a1a9e007 100644 --- a/src/public/javascripts/services/protected_session.js +++ b/src/public/javascripts/services/protected_session.js @@ -94,11 +94,11 @@ async function protectNoteAndSendToServer() { noteDetail.updateNoteFromInputs(note); - note.detail.isProtected = true; + note.isProtected = true; await noteDetail.saveNoteToServer(note); - treeService.setProtected(note.detail.noteId, note.detail.isProtected); + treeService.setProtected(note.noteId, note.isProtected); noteDetail.setNoteBackgroundIfProtected(note); } @@ -110,11 +110,11 @@ async function unprotectNoteAndSendToServer() { noteDetail.updateNoteFromInputs(note); - note.detail.isProtected = false; + note.isProtected = false; await noteDetail.saveNoteToServer(note); - treeService.setProtected(note.detail.noteId, note.detail.isProtected); + treeService.setProtected(note.noteId, note.isProtected); noteDetail.setNoteBackgroundIfProtected(note); } diff --git a/src/public/javascripts/services/search_tree.js b/src/public/javascripts/services/search_tree.js index a141cc96e..8769279d5 100644 --- a/src/public/javascripts/services/search_tree.js +++ b/src/public/javascripts/services/search_tree.js @@ -1,4 +1,5 @@ import treeService from './tree.js'; +import server from './server.js'; const $tree = $("#tree"); const $searchInput = $("input[name='search-text']"); @@ -45,6 +46,8 @@ async function doSearch() { async function saveSearch() { const {noteId} = await server.post('search/' + encodeURIComponent($searchInput.val())); + resetSearch(); + await treeService.reload(); await treeService.activateNode(noteId); diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js index 5892f2456..43c1d5c67 100644 --- a/src/public/javascripts/services/tree.js +++ b/src/public/javascripts/services/tree.js @@ -12,6 +12,7 @@ import recentNotesDialog from '../dialogs/recent_notes.js'; import editTreePrefixDialog from '../dialogs/edit_tree_prefix.js'; import treeCache from './tree_cache.js'; import infoService from "./info.js"; +import Branch from '../entities/branch.js'; const $tree = $("#tree"); const $parentList = $("#parent-list"); @@ -615,25 +616,22 @@ function initFancyTree(branch) { } async function loadSearchNote(searchNoteId) { - const note = await server.get('notes/' + searchNoteId); - - const json = JSON.parse(note.detail.content); - - const noteIds = await server.get('search/' + encodeURIComponent(json.searchString)); + const searchNote = await noteDetailService.loadNote(searchNoteId); + const noteIds = await server.get('search/' + encodeURIComponent(searchNote.jsonContent.searchString)); for (const noteId of noteIds) { - const branchId = "virt" + utils.randomString(10); - - treeCache.addBranch({ - branchId: branchId, + const branch = new Branch(treeCache, { + branchId: "virt" + utils.randomString(10), noteId: noteId, parentNoteId: searchNoteId, prefix: '', virtual: true }); + + treeCache.addBranch(branch); } - return await prepareBranchInner(await treeCache.getNote(searchNoteId)); + return await prepareBranchInner(searchNote); } function getTree() { diff --git a/src/public/javascripts/services/utils.js b/src/public/javascripts/services/utils.js index 32e6a5a1d..fd1f33aa8 100644 --- a/src/public/javascripts/services/utils.js +++ b/src/public/javascripts/services/utils.js @@ -167,9 +167,9 @@ function toObject(array, fn) { const obj = {}; for (const item of array) { - const ret = fn(item); + const [key, value] = fn(item); - obj[ret[0]] = ret[1]; + obj[key] = value; } return obj; diff --git a/src/public/libraries/codemirror/addon/lint/eslint.js b/src/public/libraries/codemirror/addon/lint/eslint.js index ba4b221ef..28ca71b97 100644 --- a/src/public/libraries/codemirror/addon/lint/eslint.js +++ b/src/public/libraries/codemirror/addon/lint/eslint.js @@ -28,7 +28,7 @@ } async function validatorJavaScript(text, options) { - if (glob.getCurrentNote().detail.mime === 'application/json') { + if (glob.getCurrentNote().mime === 'application/json') { // eslint doesn't seem to validate pure JSON well return []; } diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js index 138fd828a..f49e476a9 100644 --- a/src/routes/api/notes.js +++ b/src/routes/api/notes.js @@ -5,7 +5,6 @@ const router = express.Router(); const auth = require('../../services/auth'); const sql = require('../../services/sql'); const notes = require('../../services/notes'); -const labels = require('../../services/labels'); const log = require('../../services/log'); const utils = require('../../services/utils'); const protected_session = require('../../services/protected_session'); @@ -26,20 +25,12 @@ router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => { protected_session.decryptNote(req, detail); - let labelMap = null; - if (detail.type === 'file') { - // no need to transfer attachment payload for this request + // no need to transfer (potentially large) attachment payload for this request detail.content = null; - - // labels contain important attachment metadata - filename and size - labelMap = await labels.getNoteLabelMap(noteId); } - res.send({ - detail: detail, - labels: labelMap - }); + res.send(detail); })); router.post('/:parentNoteId/children', auth.checkApiAuth, wrap(async (req, res, next) => { diff --git a/src/routes/api/search.js b/src/routes/api/search.js index 61ce68d02..7d280260c 100644 --- a/src/routes/api/search.js +++ b/src/routes/api/search.js @@ -26,7 +26,8 @@ router.post('/:searchString', auth.checkApiAuth, wrap(async (req, res, next) => const noteId = await notes.createNote('root', 'Search note', noteContent, { json: true, - type: 'search' + type: 'search', + mime: "application/json" }); res.send({ noteId });