From 7ae2a24770d010605cc3c2a2a76f0d8634050840 Mon Sep 17 00:00:00 2001 From: azivner Date: Tue, 28 Aug 2018 20:55:21 +0200 Subject: [PATCH] use relations to pick note to render, fixes #141 --- src/public/javascripts/dialogs/attributes.js | 2 +- .../javascripts/services/note_detail.js | 31 ++++++-- .../services/note_detail_render.js | 71 +++++-------------- src/public/stylesheets/style.css | 7 +- src/services/attributes.js | 3 +- src/views/index.ejs | 17 +++-- 6 files changed, 61 insertions(+), 70 deletions(-) diff --git a/src/public/javascripts/dialogs/attributes.js b/src/public/javascripts/dialogs/attributes.js index 52dbfa95c..9cab0d29a 100644 --- a/src/public/javascripts/dialogs/attributes.js +++ b/src/public/javascripts/dialogs/attributes.js @@ -170,7 +170,7 @@ function AttributesModel() { infoService.showMessage("Attributes have been saved."); - noteDetailService.loadAttributes(); + noteDetailService.refreshAttributes(); }; function addLastEmptyRow() { diff --git a/src/public/javascripts/services/note_detail.js b/src/public/javascripts/services/note_detail.js index 58da247dd..7a449f10b 100644 --- a/src/public/javascripts/services/note_detail.js +++ b/src/public/javascripts/services/note_detail.js @@ -38,6 +38,8 @@ let noteChangeDisabled = false; let isNoteChanged = false; +let attributePromise; + const components = { 'code': noteDetailCode, 'text': noteDetailText, @@ -147,6 +149,7 @@ async function handleProtectedSession() { async function loadNoteDetail(noteId) { currentNote = await loadNote(noteId); + refreshAttributes(); // needs to happend after loading the note itself because it references current noteId if (isNewNoteCreated) { isNewNoteCreated = false; @@ -191,13 +194,15 @@ async function loadNoteDetail(noteId) { await bundleService.executeRelationBundles(getCurrentNote(), 'runOnNoteView'); - const attributes = await loadAttributes(); + await showAttributes(); - const hideChildrenOverview = attributes.some(attr => attr.type === 'label' && attr.name === 'hideChildrenOverview'); - await showChildrenOverview(hideChildrenOverview); + await showChildrenOverview(); } -async function showChildrenOverview(hideChildrenOverview) { +async function showChildrenOverview() { + const attributes = await attributePromise; + const hideChildrenOverview = attributes.some(attr => attr.type === 'label' && attr.name === 'hideChildrenOverview'); + if (hideChildrenOverview) { $childrenOverview.hide(); return; @@ -222,13 +227,23 @@ async function showChildrenOverview(hideChildrenOverview) { $childrenOverview.show(); } -async function loadAttributes() { +async function refreshAttributes() { + attributePromise = server.get('notes/' + getCurrentNoteId() + '/attributes'); + + await showAttributes(); +} + +async function getAttributes() { + return await attributePromise; +} + +async function showAttributes() { $promotedAttributesContainer.empty(); $attributeList.hide(); const noteId = getCurrentNoteId(); - const attributes = await server.get('notes/' + noteId + '/attributes'); + const attributes = await attributePromise; const promoted = attributes.filter(attr => (attr.type === 'label-definition' || attr.type === 'relation-definition') @@ -525,7 +540,9 @@ export default { getCurrentNoteId, newNoteCreated, focus, - loadAttributes, + getAttributes, + showAttributes, + refreshAttributes, saveNote, saveNoteIfChanged, noteChanged diff --git a/src/public/javascripts/services/note_detail_render.js b/src/public/javascripts/services/note_detail_render.js index 5b1dec521..4e97c18ee 100644 --- a/src/public/javascripts/services/note_detail_render.js +++ b/src/public/javascripts/services/note_detail_render.js @@ -1,73 +1,38 @@ import bundleService from "./bundle.js"; import server from "./server.js"; import noteDetailService from "./note_detail.js"; -import noteDetailCodeService from "./note_detail_code.js"; -const $noteDetailCode = $('#note-detail-code'); const $noteDetailRender = $('#note-detail-render'); -const $toggleEditButton = $('#toggle-edit-button'); +const $noteDetailRenderHelp = $('#note-detail-render-help'); +const $noteDetailRenderContent = $('#note-detail-render-content'); const $renderButton = $('#render-button'); -let codeEditorInitialized; +async function render() { + const attributes = await noteDetailService.getAttributes(); + const renderNotes = attributes.filter(attr => + attr.type === 'relation' + && attr.name === 'renderNote' + && !!attr.value); -async function show() { - codeEditorInitialized = false; + $noteDetailRender.show(); - $noteDetailRender.empty().show(); + $noteDetailRenderContent.empty(); + $noteDetailRenderContent.toggle(renderNotes.length > 0); + $noteDetailRenderHelp.toggle(renderNotes.length === 0); - await render(); -} + for (const renderNote of renderNotes) { + const bundle = await server.get('script/bundle/' + renderNote.value); -async function toggleEdit() { - if ($noteDetailCode.is(":visible")) { - $noteDetailCode.hide(); - } - else { - if (!codeEditorInitialized) { - await noteDetailCodeService.show(); + $noteDetailRenderContent.append(bundle.html); - // because we can't properly scroll only the editor without scrolling the rendering - // we limit its height - $noteDetailCode.find('.CodeMirror').css('height', '300'); - - codeEditorInitialized = true; - } - else { - $noteDetailCode.show(); - } + await bundleService.executeBundle(bundle); } } -$toggleEditButton.click(toggleEdit); - $renderButton.click(render); -async function render() { - // ctrl+enter is also used elsewhere so make sure we're running only when appropriate - if (noteDetailService.getCurrentNoteType() !== 'render') { - return; - } - - if (codeEditorInitialized) { - await noteDetailService.saveNoteIfChanged(); - } - - const bundle = await server.get('script/bundle/' + noteDetailService.getCurrentNoteId()); - - $noteDetailRender.html(bundle.html); - - // if the note is empty, it doesn't make sense to do render-only since nothing will be rendered - if (!bundle.html.trim()) { - toggleEdit(); - } - - await bundleService.executeBundle(bundle); -} - -$(document).bind('keydown', "ctrl+return", render); - export default { - show, - getContent: noteDetailCodeService.getContent, + show: render, + getContent: () => "", focus: () => null } \ No newline at end of file diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index 174004872..9ef949231 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -434,7 +434,7 @@ html.theme-dark body { margin: auto; } -#note-detail-promoted-attributes td, note-detail-promoted-attributes th { +#note-detail-promoted-attributes td, #note-detail-promoted-attributes th { padding: 5px; } @@ -453,4 +453,9 @@ table.promoted-attributes-in-tooltip { table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th { padding: 10px; +} + +#note-detail-render-help { + margin: 50px; + padding: 20px; } \ No newline at end of file diff --git a/src/services/attributes.js b/src/services/attributes.js index 9f87ab462..39e41f8b2 100644 --- a/src/services/attributes.js +++ b/src/services/attributes.js @@ -25,7 +25,8 @@ const BUILTIN_ATTRIBUTES = [ { type: 'relation', name: 'runOnChildNoteCreation' }, { type: 'relation', name: 'runOnAttributeCreation' }, { type: 'relation', name: 'runOnAttributeChange' }, - { type: 'relation', name: 'template' } + { type: 'relation', name: 'template' }, + { type: 'relation', name: 'renderNote' } ]; async function getNotesWithLabel(name, value) { diff --git a/src/views/index.ejs b/src/views/index.ejs index ddc51b5c5..d473b69fd 100644 --- a/src/views/index.ejs +++ b/src/views/index.ejs @@ -114,14 +114,9 @@
- -
-
+
+
+

This help note is shown because this note of type Render HTML doesn't have required relation to function properly.

+ +

Render HTML note type is used for scripting. In short, you have a HTML code note (optionally with some JavaScript) and this note will render it. To make it work, you need to define a relation (in Attributes dialog) called "renderNote" pointing to the HTML note to render. Once that's defined you can click on the "play" button to render.

+
+ +
+