attribute UI & saving now fully working

This commit is contained in:
azivner 2018-08-05 20:08:56 +02:00
parent f437be7af0
commit 2089c32839
4 changed files with 63 additions and 28 deletions

View File

@ -15,11 +15,12 @@ function AttributesModel() {
this.availableTypes = [ this.availableTypes = [
{ text: "Label", value: "label" }, { text: "Label", value: "label" },
{ text: "Label definition", value: "definition" }, { text: "Label definition", value: "label-definition" },
{ text: "Relation", value: "relation" } { text: "Relation", value: "relation" },
{ text: "Relation definition", value: "relation-definition" }
]; ];
this.availableValueTypes = [ this.availableLabelTypes = [
{ text: "Text", value: "text" }, { text: "Text", value: "text" },
{ text: "Integer", value: "integer" }, { text: "Integer", value: "integer" },
{ text: "Decimal", value: "decimal" }, { text: "Decimal", value: "decimal" },
@ -36,7 +37,7 @@ function AttributesModel() {
self.getTargetAttribute(event.target).valueHasMutated(); self.getTargetAttribute(event.target).valueHasMutated();
}; };
this.valueTypeChanged = function(data, event) { this.labelTypeChanged = function(data, event) {
self.getTargetAttribute(event.target).valueHasMutated(); self.getTargetAttribute(event.target).valueHasMutated();
}; };
@ -52,26 +53,32 @@ function AttributesModel() {
}); });
}; };
this.loadAttributes = async function() { function prepareAttributes(attributes) {
const noteId = noteDetailService.getCurrentNoteId();
const attributes = await server.get('notes/' + noteId + '/attributes');
for (const attr of attributes) { for (const attr of attributes) {
attr.labelValue = attr.type === 'label' ? attr.value : ''; attr.labelValue = attr.type === 'label' ? attr.value : '';
attr.relationValue = attr.type === 'relation' ? attr.value : ''; attr.relationValue = attr.type === 'relation' ? attr.value : '';
attr.definition = { attr.labelDefinition = attr.type === 'label-definition' ? JSON.parse(attr.value) : {
valueType: "text", labelType: "text",
multiplicityType: "singlevalue", multiplicityType: "singlevalue",
showInUi: "true" isPromoted: true
};
attr.relationDefinition = attr.type === 'relation-definition' ? JSON.parse(attr.value) : {
multiplicityType: "singlevalue",
isPromoted: true
}; };
delete attr.value;
} }
self.attributes(attributes.map(ko.observable)); self.attributes(attributes.map(ko.observable));
addLastEmptyRow(); addLastEmptyRow();
}
this.loadAttributes = async function() {
const noteId = noteDetailService.getCurrentNoteId();
const attributes = await server.get('notes/' + noteId + '/attributes');
prepareAttributes(attributes);
// attribute might not be rendered immediatelly so could not focus // attribute might not be rendered immediatelly so could not focus
setTimeout(() => $(".attribute-name:last").focus(), 100); setTimeout(() => $(".attribute-name:last").focus(), 100);
@ -125,15 +132,37 @@ function AttributesModel() {
.map(attribute => attribute()) .map(attribute => attribute())
.filter(attribute => attribute.attributeId !== "" || attribute.name !== ""); .filter(attribute => attribute.attributeId !== "" || attribute.name !== "");
for (const attr of attributesToSave) {
if (attr.type === 'label') {
attr.value = attr.labelValue;
}
else if (attr.type === 'relation') {
attr.value = attr.relationValue;
}
else if (attr.type === 'label-definition') {
attr.value = JSON.stringify(attr.labelDefinition);
}
else if (attr.type === 'relation-definition') {
attr.value = JSON.stringify(attr.relationDefinition);
}
delete attr.labelValue;
delete attr.relationValue;
delete attr.labelDefinition;
delete attr.relationDefinition;
}
const attributes = await server.put('notes/' + noteId + '/attributes', attributesToSave); const attributes = await server.put('notes/' + noteId + '/attributes', attributesToSave);
self.attributes(attributes.map(ko.observable)); prepareAttributes(attributes);
addLastEmptyRow();
infoService.showMessage("Attributes have been saved."); infoService.showMessage("Attributes have been saved.");
noteDetailService.loadAttributeList(); // FIXME FIXME FIXME FIXME FIXME
// FIXME FIXME FIXME FIXME FIXME
// FIXME FIXME FIXME FIXME FIXME
// FIXME FIXME FIXME FIXME FIXME
//noteDetailService.loadAttributeList();
}; };
function addLastEmptyRow() { function addLastEmptyRow() {
@ -150,10 +179,10 @@ function AttributesModel() {
isInheritable: false, isInheritable: false,
isDeleted: 0, isDeleted: 0,
position: 0, position: 0,
definition: { labelDefinition: {
valueType: "text", valueType: "text",
multiplicityType: "singlevalue", multiplicityType: "singlevalue",
showInUi: "true" isPromoted: true
} }
})); }));
} }
@ -177,7 +206,7 @@ function AttributesModel() {
for (let attributes = self.attributes(), i = 0; i < attributes.length; i++) { for (let attributes = self.attributes(), i = 0; i < attributes.length; i++) {
const attribute = attributes[i](); const attribute = attributes[i]();
if (index !== i && cur.name === attribute.name) { if (index !== i && cur.name === attribute.name && cur.type === attribute.type) {
return true; return true;
} }
} }

View File

@ -31,9 +31,11 @@ async function updateNoteAttributes(req) {
attributeEntity.noteId = noteId; attributeEntity.noteId = noteId;
} }
attributeEntity.type = attribute.type;
attributeEntity.name = attribute.name; attributeEntity.name = attribute.name;
attributeEntity.value = attribute.value; attributeEntity.value = attribute.value;
attributeEntity.position = attribute.position; attributeEntity.position = attribute.position;
attributeEntity.isInheritable = attribute.isInheritable;
attributeEntity.isDeleted = attribute.isDeleted; attributeEntity.isDeleted = attribute.isDeleted;
await attributeEntity.save(); await attributeEntity.save();

View File

@ -37,6 +37,10 @@ async function getImage(imageId) {
return await getEntity("SELECT * FROM images WHERE imageId = ?", [imageId]); return await getEntity("SELECT * FROM images WHERE imageId = ?", [imageId]);
} }
async function getAttribute(attributeId) {
return await getEntity("SELECT * FROM attributes WHERE attributeId = ?", [attributeId]);
}
async function getLabel(labelId) { async function getLabel(labelId) {
return await getEntity("SELECT * FROM labels WHERE labelId = ?", [labelId]); return await getEntity("SELECT * FROM labels WHERE labelId = ?", [labelId]);
} }
@ -75,6 +79,7 @@ module.exports = {
getNote, getNote,
getBranch, getBranch,
getImage, getImage,
getAttribute,
getLabel, getLabel,
getRelation, getRelation,
getOption, getOption,

View File

@ -591,21 +591,20 @@
<td> <td>
<input type="text" class="label-value form-control" data-bind="visible: type == 'label', value: labelValue, valueUpdate: 'blur', event: { blur: $parent.attributeChanged }" style="width: 300px"/> <input type="text" class="label-value form-control" data-bind="visible: type == 'label', value: labelValue, valueUpdate: 'blur', event: { blur: $parent.attributeChanged }" style="width: 300px"/>
<div class="relation-value input-group" data-bind="visible: type == 'relation'"> <div class="relation-value input-group" data-bind="visible: type == 'relation'" style="width: 300px;">
<input class="form-control relation-target-note-id" <input class="form-control relation-target-note-id"
placeholder="search for note by its name" placeholder="search for note by its name"
data-bind="value: relationValue, valueUpdate: 'blur', event: { blur: $parent.attributeChanged }" data-bind="value: relationValue, valueUpdate: 'blur', event: { blur: $parent.attributeChanged }">
style="width: 300px;">
<span class="input-group-addon relations-show-recent-notes" title="Show recent notes" style="background: url('/images/icons/clock-16.png') no-repeat center; cursor: pointer;"></span> <span class="input-group-addon relations-show-recent-notes" title="Show recent notes" style="background: url('/images/icons/clock-16.png') no-repeat center; cursor: pointer;"></span>
</div> </div>
<div data-bind="visible: type == 'definition'"> <div data-bind="visible: type == 'label-definition'">
<select data-bind="options: $parent.availableValueTypes, optionsText: 'text', optionsValue: 'value', value: definition.valueType"></select> <select data-bind="options: $parent.availableLabelTypes, optionsText: 'text', optionsValue: 'value', value: labelDefinition.labelType"></select>
<select data-bind="options: $parent.multiplicityTypes, optionsText: 'text', optionsValue: 'value', value: definition.multiplicityType"></select> <select data-bind="options: $parent.multiplicityTypes, optionsText: 'text', optionsValue: 'value', value: labelDefinition.multiplicityType"></select>
<input type="checkbox" value="true" data-bind="checked: definition.showInUi" /> Show In UI <input type="checkbox" value="true" data-bind="checked: labelDefinition.isPromoted" /> Promoted
</div> </div>
</td> </td>
<td title="Inheritable relations are automatically inherited to the child notes"> <td title="Inheritable relations are automatically inherited to the child notes">