From 6416e3e9fb5c85c04d5311f9907e9e914761c296 Mon Sep 17 00:00:00 2001 From: azivner Date: Thu, 8 Nov 2018 20:01:25 +0100 Subject: [PATCH] refactored attributes out of note detail, fixes #213 --- src/public/javascripts/dialogs/attributes.js | 4 +- src/public/javascripts/services/attributes.js | 298 ++++++++++++++++++ .../javascripts/services/note_detail.js | 295 +---------------- .../services/note_detail_render.js | 3 +- 4 files changed, 306 insertions(+), 294 deletions(-) create mode 100644 src/public/javascripts/services/attributes.js diff --git a/src/public/javascripts/dialogs/attributes.js b/src/public/javascripts/dialogs/attributes.js index 74f239f6b..6d04b0a3b 100644 --- a/src/public/javascripts/dialogs/attributes.js +++ b/src/public/javascripts/dialogs/attributes.js @@ -2,7 +2,7 @@ import noteDetailService from '../services/note_detail.js'; import server from '../services/server.js'; import infoService from "../services/info.js"; import treeUtils from "../services/tree_utils.js"; -import linkService from "../services/link.js"; +import attributeService from "../services/attributes.js"; const $dialog = $("#attributes-dialog"); const $saveAttributesButton = $("#save-attributes-button"); @@ -165,7 +165,7 @@ function AttributesModel() { infoService.showMessage("Attributes have been saved."); - noteDetailService.refreshAttributes(); + attributeService.refreshAttributes(); }; function addLastEmptyRow() { diff --git a/src/public/javascripts/services/attributes.js b/src/public/javascripts/services/attributes.js new file mode 100644 index 000000000..785fae1cb --- /dev/null +++ b/src/public/javascripts/services/attributes.js @@ -0,0 +1,298 @@ +import server from "./server.js"; +import utils from "./utils.js"; +import messagingService from "./messaging.js"; +import treeUtils from "./tree_utils.js"; +import noteAutocompleteService from "./note_autocomplete.js"; +import treeService from "./tree.js"; +import linkService from "./link.js"; +import infoService from "./info.js"; +import noteDetailService from "./note_detail.js"; + +const $attributeList = $("#attribute-list"); +const $attributeListInner = $("#attribute-list-inner"); +const $promotedAttributesContainer = $("#note-detail-promoted-attributes"); + +let attributePromise; + +async function refreshAttributes() { + attributePromise = server.get('notes/' + noteDetailService.getCurrentNoteId() + '/attributes'); + + await showAttributes(); +} + +async function getAttributes() { + return await attributePromise; +} + +async function showAttributes() { + $promotedAttributesContainer.empty(); + $attributeList.hide(); + + const noteId = noteDetailService.getCurrentNoteId(); + + const attributes = await attributePromise; + + const promoted = attributes.filter(attr => + (attr.type === 'label-definition' || attr.type === 'relation-definition') + && !attr.name.startsWith("child:") + && attr.value.isPromoted); + + let idx = 1; + + async function createRow(definitionAttr, valueAttr) { + const definition = definitionAttr.value; + const inputId = "promoted-input-" + idx; + const $tr = $(""); + const $labelCell = $("").append(valueAttr.name); + const $input = $("") + .prop("id", inputId) + .prop("tabindex", definitionAttr.position) + .prop("attribute-id", valueAttr.isOwned ? valueAttr.attributeId : '') // if not owned, we'll force creation of a new attribute instead of updating the inherited one + .prop("attribute-type", valueAttr.type) + .prop("attribute-name", valueAttr.name) + .prop("value", valueAttr.value) + .addClass("form-control") + .addClass("promoted-attribute-input") + .change(promotedAttributeChanged); + + idx++; + + const $inputCell = $("").append($("
").addClass("input-group").append($input)); + + const $actionCell = $(""); + const $multiplicityCell = $(""); + + $tr + .append($labelCell) + .append($inputCell) + .append($actionCell) + .append($multiplicityCell); + + if (valueAttr.type === 'label') { + if (definition.labelType === 'text') { + $input.prop("type", "text"); + + // no need to await for this, can be done asynchronously + server.get('attributes/values/' + encodeURIComponent(valueAttr.name)).then(attributeValues => { + if (attributeValues.length === 0) { + return; + } + + attributeValues = attributeValues.map(attribute => { return { value: attribute }; }); + + $input.autocomplete({ + appendTo: document.querySelector('body'), + hint: false, + autoselect: true, + openOnFocus: true, + minLength: 0 + }, [{ + displayKey: 'value', + source: function (term, cb) { + term = term.toLowerCase(); + + const filtered = attributeValues.filter(attr => attr.value.toLowerCase().includes(term)); + + cb(filtered); + } + }]); + }); + } + else if (definition.labelType === 'number') { + $input.prop("type", "number"); + } + else if (definition.labelType === 'boolean') { + $input.prop("type", "checkbox"); + + if (valueAttr.value === "true") { + $input.prop("checked", "checked"); + } + } + else if (definition.labelType === 'date') { + $input.prop("type", "date"); + + const $todayButton = $("