From 61987e46f7d107cdb80dfbbf3aeebc0fc8a7c2e6 Mon Sep 17 00:00:00 2001 From: azivner Date: Fri, 3 Aug 2018 13:06:56 +0200 Subject: [PATCH] work in progress on attributes UI - unification of labels and relations now mostly works --- .../0110__add_isInheritable_to_attributes.sql | 1 + src/entities/attribute.js | 6 +- src/public/javascripts/dialogs/attributes.js | 64 +++++++++++++++++-- src/services/app_info.js | 2 +- src/services/note_cache.js | 2 +- src/views/index.ejs | 20 +++++- 6 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 db/migrations/0110__add_isInheritable_to_attributes.sql diff --git a/db/migrations/0110__add_isInheritable_to_attributes.sql b/db/migrations/0110__add_isInheritable_to_attributes.sql new file mode 100644 index 000000000..753e47a7f --- /dev/null +++ b/db/migrations/0110__add_isInheritable_to_attributes.sql @@ -0,0 +1 @@ +ALTER TABLE attributes ADD isInheritable int DEFAULT 0 NULL; \ No newline at end of file diff --git a/src/entities/attribute.js b/src/entities/attribute.js index 1c2eefb05..b4ce46fc6 100644 --- a/src/entities/attribute.js +++ b/src/entities/attribute.js @@ -8,7 +8,7 @@ const sql = require('../services/sql'); class Attribute extends Entity { static get tableName() { return "attributes"; } static get primaryKeyName() { return "attributeId"; } - static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "dateModified", "dateCreated"]; } + static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable", "dateModified", "dateCreated"]; } async getNote() { return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); @@ -26,6 +26,10 @@ class Attribute extends Entity { this.position = 1 + await sql.getValue(`SELECT COALESCE(MAX(position), 0) FROM attributes WHERE noteId = ?`, [this.noteId]); } + if (!this.isInheritable) { + this.isInheritable = false; + } + if (!this.isDeleted) { this.isDeleted = false; } diff --git a/src/public/javascripts/dialogs/attributes.js b/src/public/javascripts/dialogs/attributes.js index 263887c2a..2f8b14850 100644 --- a/src/public/javascripts/dialogs/attributes.js +++ b/src/public/javascripts/dialogs/attributes.js @@ -19,6 +19,10 @@ function AttributesModel() { { text: "Relation", value: "relation" } ]; + this.typeChanged = function(data, event) { + self.getTargetAttribute(event.target).valueHasMutated(); + }; + this.updateAttributePositions = function() { let position = 0; @@ -36,6 +40,13 @@ function AttributesModel() { const attributes = await server.get('notes/' + noteId + '/attributes'); + for (const attr of attributes) { + attr.labelValue = attr.type === 'label' ? attr.value : ''; + attr.relationValue = attr.type === 'relation' ? attr.value : ''; + + delete attr.value; + } + self.attributes(attributes.map(ko.observable)); addLastEmptyRow(); @@ -107,12 +118,14 @@ function AttributesModel() { const attributes = self.attributes().filter(attr => attr().isDeleted === 0); const last = attributes.length === 0 ? null : attributes[attributes.length - 1](); - if (!last || last.name.trim() !== "" || last.value !== "") { + if (!last || last.name.trim() !== "") { self.attributes.push(ko.observable({ attributeId: '', type: 'label', name: '', - value: '', + labelValue: '', + relationValue: '', + isInheritable: false, isDeleted: 0, position: 0 })); @@ -148,7 +161,7 @@ function AttributesModel() { this.isEmptyName = function(index) { const cur = self.attributes()[index](); - return cur.name.trim() === "" && (cur.attributeId !== "" || cur.value !== ""); + return cur.name.trim() === "" && (cur.attributeId !== "" || cur.labelValue !== "" || cur.relationValue); }; this.getTargetAttribute = function(target) { @@ -204,7 +217,7 @@ $dialog.on('focus', '.attribute-name', function (e) { $(this).autocomplete("search", $(this).val()); }); -$dialog.on('focus', '.attribute-value', async function (e) { +$dialog.on('focus', '.label-value', async function (e) { if (!$(this).hasClass("ui-autocomplete-input")) { const attributeName = $(this).parent().parent().find('.attribute-name').val(); @@ -234,6 +247,49 @@ $dialog.on('focus', '.attribute-value', async function (e) { $(this).autocomplete("search", $(this).val()); }); +async function initNoteAutocomplete($el) { + if (!$el.hasClass("ui-autocomplete-input")) { + await $el.autocomplete({ + source: async function (request, response) { + const result = await server.get('autocomplete?query=' + encodeURIComponent(request.term)); + + if (result.length > 0) { + response(result.map(row => { + return { + label: row.label, + value: row.label + ' (' + row.value + ')' + } + })); + } + else { + response([{ + label: "No results", + value: "No results" + }]); + } + }, + minLength: 0, + select: function (event, ui) { + if (ui.item.value === 'No results') { + return false; + } + } + }); + } +} + +$dialog.on('focus', '.relation-target-note-id', async function () { + await initNoteAutocomplete($(this)); +}); + +$dialog.on('click', '.relations-show-recent-notes', async function () { + const $autocomplete = $(this).parent().find('.relation-target-note-id'); + + await initNoteAutocomplete($autocomplete); + + $autocomplete.autocomplete("search", ""); +}); + export default { showDialog }; \ No newline at end of file diff --git a/src/services/app_info.js b/src/services/app_info.js index dc5fa5984..66ab29459 100644 --- a/src/services/app_info.js +++ b/src/services/app_info.js @@ -3,7 +3,7 @@ const build = require('./build'); const packageJson = require('../../package'); -const APP_DB_VERSION = 109; +const APP_DB_VERSION = 110; const SYNC_VERSION = 1; module.exports = { diff --git a/src/services/note_cache.js b/src/services/note_cache.js index dacdae569..c43d97454 100644 --- a/src/services/note_cache.js +++ b/src/services/note_cache.js @@ -40,7 +40,7 @@ async function load() { } function findNotes(query) { - if (!noteTitles || query.length <= 2) { + if (!noteTitles || !query.length) { return []; } diff --git a/src/views/index.ejs b/src/views/index.ejs index b62f50820..a93cf5467 100644 --- a/src/views/index.ejs +++ b/src/views/index.ejs @@ -567,13 +567,15 @@ ID + Type Name Value + Inheritable - + @@ -581,7 +583,7 @@ - + @@ -590,7 +592,19 @@
Attribute name can't be empty.
- + + +
+ + + +
+ + +