diff --git a/src/public/javascripts/dialogs/attributes.js b/src/public/javascripts/dialogs/attributes.js index f31cdefc3..e0899fa99 100644 --- a/src/public/javascripts/dialogs/attributes.js +++ b/src/public/javascripts/dialogs/attributes.js @@ -53,6 +53,8 @@ const attributesDialog = (function() { addLastEmptyRow(); showMessage("Attributes have been saved."); + + noteEditor.loadAttributeList(); }; function addLastEmptyRow() { diff --git a/src/public/javascripts/note_editor.js b/src/public/javascripts/note_editor.js index 356faa082..e243c9c0e 100644 --- a/src/public/javascripts/note_editor.js +++ b/src/public/javascripts/note_editor.js @@ -9,6 +9,8 @@ const noteEditor = (function() { const unprotectButton = $("#unprotect-button"); const noteDetailWrapperEl = $("#note-detail-wrapper"); const noteIdDisplayEl = $("#note-id-display"); + const attributeListEl = $("#attribute-list"); + const attributeListInnerEl = $("#attribute-list-inner"); let editor = null; let codeEditor = null; @@ -187,6 +189,27 @@ const noteEditor = (function() { // after loading new note make sure editor is scrolled to the top noteDetailWrapperEl.scrollTop(0); + + loadAttributeList(); + } + + async function loadAttributeList() { + const noteId = getCurrentNoteId(); + + const attributes = await server.get('notes/' + noteId + '/attributes'); + + attributeListInnerEl.html(''); + + if (attributes.length > 0) { + for (const attr of attributes) { + attributeListInnerEl.append(formatAttribute(attr) + " "); + } + + attributeListEl.show(); + } + else { + attributeListEl.hide(); + } } async function loadNote(noteId) { @@ -290,6 +313,7 @@ const noteEditor = (function() { newNoteCreated, getEditor, focus, - executeCurrentNote + executeCurrentNote, + loadAttributeList }; })(); \ No newline at end of file diff --git a/src/public/javascripts/utils.js b/src/public/javascripts/utils.js index 9e1ae2e5b..6b19a7f53 100644 --- a/src/public/javascripts/utils.js +++ b/src/public/javascripts/utils.js @@ -118,4 +118,18 @@ async function stopWatch(what, func) { function executeScript(script) { // last \r\n is necessary if script contains line comment on its last line eval("(async function() {" + script + "\r\n})()"); +} + +function formatValueWithWhitespace(val) { + return /\s/.test(val) ? '"' + val + '"' : val; +} + +function formatAttribute(attr) { + let str = "@" + formatValueWithWhitespace(attr.name); + + if (attr.value !== "") { + str += "=" + formatValueWithWhitespace(attr.value); + } + + return str; } \ No newline at end of file diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index f22c9ae17..048afe109 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -6,7 +6,8 @@ grid-template-areas: "header header" "tree-actions title" "tree note-content" - "parent-list note-content"; + "parent-list note-content" + "parent-list attribute-list"; grid-template-columns: 2fr 5fr; grid-template-rows: auto auto @@ -238,7 +239,7 @@ div.ui-tooltip { #note-id-display { position: absolute; right: 10px; - bottom: 5px; + bottom: 8px; z-index: 1000; color: lightgrey; } @@ -249,4 +250,16 @@ div.ui-tooltip { overflow-x: hidden; } -.cm-matchhighlight {background-color: #eeeeee} \ No newline at end of file +.cm-matchhighlight {background-color: #eeeeee} + +#attribute-list { + grid-area: attribute-list; + color: #777777; + border-top: 1px solid #eee; + padding: 5px; display: none; +} + +#attribute-list button { + padding: 2px; + margin-right: 10px; +} \ No newline at end of file diff --git a/src/routes/api/attributes.js b/src/routes/api/attributes.js index 6cc18d145..f3215c701 100644 --- a/src/routes/api/attributes.js +++ b/src/routes/api/attributes.js @@ -63,7 +63,7 @@ router.get('/attributes/names', auth.checkApiAuth, wrap(async (req, res, next) = router.get('/attributes/values/:attributeName', auth.checkApiAuth, wrap(async (req, res, next) => { const attributeName = req.params.attributeName; - const values = await sql.getColumn("SELECT DISTINCT value FROM attributes WHERE name = ? ORDER BY value", [attributeName]); + const values = await sql.getColumn("SELECT DISTINCT value FROM attributes WHERE name = ? AND value != '' ORDER BY value", [attributeName]); res.send(values); })); diff --git a/src/views/index.ejs b/src/views/index.ejs index 95fee20c6..e9f911113 100644 --- a/src/views/index.ejs +++ b/src/views/index.ejs @@ -143,6 +143,12 @@
+ +