| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  | import noteDetailService from '../services/note_detail.js'; | 
					
						
							|  |  |  | import server from '../services/server.js'; | 
					
						
							|  |  |  | import infoService from "../services/info.js"; | 
					
						
							| 
									
										
										
										
											2018-08-06 11:30:37 +02:00
										 |  |  | import treeUtils from "../services/tree_utils.js"; | 
					
						
							|  |  |  | import linkService from "../services/link.js"; | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | const $dialog = $("#attributes-dialog"); | 
					
						
							|  |  |  | const $saveAttributesButton = $("#save-attributes-button"); | 
					
						
							|  |  |  | const $attributesBody = $('#attributes-table tbody'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const attributesModel = new AttributesModel(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function AttributesModel() { | 
					
						
							|  |  |  |     const self = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.attributes = ko.observableArray(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.availableTypes = [ | 
					
						
							|  |  |  |         { text: "Label", value: "label" }, | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |         { text: "Label definition", value: "label-definition" }, | 
					
						
							|  |  |  |         { text: "Relation", value: "relation" }, | 
					
						
							|  |  |  |         { text: "Relation definition", value: "relation-definition" } | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |     this.availableLabelTypes = [ | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |         { text: "Text", value: "text" }, | 
					
						
							| 
									
										
										
										
											2018-08-06 08:59:26 +02:00
										 |  |  |         { text: "Number", value: "number" }, | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |         { text: "Boolean", value: "boolean" }, | 
					
						
							| 
									
										
										
										
											2018-08-06 15:58:59 +02:00
										 |  |  |         { text: "Date", value: "date" } | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.multiplicityTypes = [ | 
					
						
							|  |  |  |         { text: "Single value", value: "singlevalue" }, | 
					
						
							|  |  |  |         { text: "Multi value", value: "multivalue" } | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-03 13:06:56 +02:00
										 |  |  |     this.typeChanged = function(data, event) { | 
					
						
							|  |  |  |         self.getTargetAttribute(event.target).valueHasMutated(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |     this.labelTypeChanged = function(data, event) { | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |         self.getTargetAttribute(event.target).valueHasMutated(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |     this.updateAttributePositions = function() { | 
					
						
							|  |  |  |         let position = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // we need to update positions by searching in the DOM, because order of the
 | 
					
						
							|  |  |  |         // attributes in the viewmodel (self.attributes()) stays the same
 | 
					
						
							|  |  |  |         $attributesBody.find('input[name="position"]').each(function() { | 
					
						
							|  |  |  |             const attribute = self.getTargetAttribute(this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             attribute().position = position++; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-06 11:30:37 +02:00
										 |  |  |     async function showAttributes(attributes) { | 
					
						
							| 
									
										
										
										
											2018-08-03 13:06:56 +02:00
										 |  |  |         for (const attr of attributes) { | 
					
						
							|  |  |  |             attr.labelValue = attr.type === 'label' ? attr.value : ''; | 
					
						
							| 
									
										
										
										
											2018-08-06 11:30:37 +02:00
										 |  |  |             attr.relationValue = attr.type === 'relation' ? (await treeUtils.getNoteTitle(attr.value) + " (" + attr.value + ")") : ''; | 
					
						
							| 
									
										
										
										
											2018-08-06 08:59:26 +02:00
										 |  |  |             attr.labelDefinition = (attr.type === 'label-definition' && attr.value) ? attr.value : { | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |                 labelType: "text", | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |                 multiplicityType: "singlevalue", | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |                 isPromoted: true | 
					
						
							|  |  |  |             }; | 
					
						
							| 
									
										
										
										
											2018-08-06 08:59:26 +02:00
										 |  |  |             attr.relationDefinition = attr.type === ('relation-definition' && attr.value) ? attr.value : { | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |                 multiplicityType: "singlevalue", | 
					
						
							|  |  |  |                 isPromoted: true | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |             }; | 
					
						
							| 
									
										
										
										
											2018-08-06 08:59:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             delete attr.value; | 
					
						
							| 
									
										
										
										
											2018-08-03 13:06:56 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |         self.attributes(attributes.map(ko.observable)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         addLastEmptyRow(); | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.loadAttributes = async function() { | 
					
						
							|  |  |  |         const noteId = noteDetailService.getCurrentNoteId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const attributes = await server.get('notes/' + noteId + '/attributes'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-06 11:30:37 +02:00
										 |  |  |         await showAttributes(attributes); | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // attribute might not be rendered immediatelly so could not focus
 | 
					
						
							|  |  |  |         setTimeout(() => $(".attribute-name:last").focus(), 100); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $attributesBody.sortable({ | 
					
						
							|  |  |  |             handle: '.handle', | 
					
						
							|  |  |  |             containment: $attributesBody, | 
					
						
							|  |  |  |             update: this.updateAttributePositions | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.deleteAttribute = function(data, event) { | 
					
						
							|  |  |  |         const attribute = self.getTargetAttribute(event.target); | 
					
						
							|  |  |  |         const attributeData = attribute(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (attributeData) { | 
					
						
							|  |  |  |             attributeData.isDeleted = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             attribute(attributeData); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             addLastEmptyRow(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function isValid() { | 
					
						
							|  |  |  |         for (let attributes = self.attributes(), i = 0; i < attributes.length; i++) { | 
					
						
							|  |  |  |             if (self.isEmptyName(i)) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.save = async function() { | 
					
						
							|  |  |  |         // we need to defocus from input (in case of enter-triggered save) because value is updated
 | 
					
						
							|  |  |  |         // on blur event (because of conflict with jQuery UI Autocomplete). Without this, input would
 | 
					
						
							|  |  |  |         // stay in focus, blur wouldn't be triggered and change wouldn't be updated in the viewmodel.
 | 
					
						
							|  |  |  |         $saveAttributesButton.focus(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!isValid()) { | 
					
						
							|  |  |  |             alert("Please fix all validation errors and try saving again."); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.updateAttributePositions(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const noteId = noteDetailService.getCurrentNoteId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const attributesToSave = self.attributes() | 
					
						
							|  |  |  |             .map(attribute => attribute()) | 
					
						
							|  |  |  |             .filter(attribute => attribute.attributeId !== "" || attribute.name !== ""); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |         for (const attr of attributesToSave) { | 
					
						
							|  |  |  |             if (attr.type === 'label') { | 
					
						
							|  |  |  |                 attr.value = attr.labelValue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (attr.type === 'relation') { | 
					
						
							| 
									
										
										
										
											2018-08-06 11:30:37 +02:00
										 |  |  |                 attr.value = treeUtils.getNoteIdFromNotePath(linkService.getNotePathFromLabel(attr.relationValue)); | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             else if (attr.type === 'label-definition') { | 
					
						
							| 
									
										
										
										
											2018-08-06 08:59:26 +02:00
										 |  |  |                 attr.value = attr.labelDefinition; | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             else if (attr.type === 'relation-definition') { | 
					
						
							| 
									
										
										
										
											2018-08-06 08:59:26 +02:00
										 |  |  |                 attr.value = attr.relationDefinition; | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |             delete attr.labelValue; | 
					
						
							|  |  |  |             delete attr.relationValue; | 
					
						
							|  |  |  |             delete attr.labelDefinition; | 
					
						
							|  |  |  |             delete attr.relationDefinition; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |         const attributes = await server.put('notes/' + noteId + '/attributes', attributesToSave); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-06 11:30:37 +02:00
										 |  |  |         await showAttributes(attributes); | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         infoService.showMessage("Attributes have been saved."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-06 08:59:26 +02:00
										 |  |  |         noteDetailService.loadAttributes(); | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function addLastEmptyRow() { | 
					
						
							|  |  |  |         const attributes = self.attributes().filter(attr => attr().isDeleted === 0); | 
					
						
							|  |  |  |         const last = attributes.length === 0 ? null : attributes[attributes.length - 1](); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-03 13:06:56 +02:00
										 |  |  |         if (!last || last.name.trim() !== "") { | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |             self.attributes.push(ko.observable({ | 
					
						
							|  |  |  |                 attributeId: '', | 
					
						
							|  |  |  |                 type: 'label', | 
					
						
							|  |  |  |                 name: '', | 
					
						
							| 
									
										
										
										
											2018-08-03 13:06:56 +02:00
										 |  |  |                 labelValue: '', | 
					
						
							|  |  |  |                 relationValue: '', | 
					
						
							|  |  |  |                 isInheritable: false, | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |                 isDeleted: 0, | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |                 position: 0, | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |                 labelDefinition: { | 
					
						
							| 
									
										
										
										
											2018-08-05 20:48:56 +02:00
										 |  |  |                     labelType: "text", | 
					
						
							|  |  |  |                     multiplicityType: "singlevalue", | 
					
						
							|  |  |  |                     isPromoted: true | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 relationDefinition: { | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |                     multiplicityType: "singlevalue", | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |                     isPromoted: true | 
					
						
							| 
									
										
										
										
											2018-08-03 22:56:49 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |             })); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.attributeChanged = function (data, event) { | 
					
						
							|  |  |  |         addLastEmptyRow(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const attribute = self.getTargetAttribute(event.target); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         attribute.valueHasMutated(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.isNotUnique = function(index) { | 
					
						
							|  |  |  |         const cur = self.attributes()[index](); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (cur.name.trim() === "") { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (let attributes = self.attributes(), i = 0; i < attributes.length; i++) { | 
					
						
							|  |  |  |             const attribute = attributes[i](); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-05 20:08:56 +02:00
										 |  |  |             if (index !== i && cur.name === attribute.name && cur.type === attribute.type) { | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.isEmptyName = function(index) { | 
					
						
							|  |  |  |         const cur = self.attributes()[index](); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-03 13:06:56 +02:00
										 |  |  |         return cur.name.trim() === "" && (cur.attributeId !== "" || cur.labelValue !== "" || cur.relationValue); | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.getTargetAttribute = function(target) { | 
					
						
							|  |  |  |         const context = ko.contextFor(target); | 
					
						
							|  |  |  |         const index = context.$index(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return self.attributes()[index]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function showDialog() { | 
					
						
							|  |  |  |     glob.activeDialog = $dialog; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await attributesModel.loadAttributes(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $dialog.dialog({ | 
					
						
							|  |  |  |         modal: true, | 
					
						
							|  |  |  |         width: 950, | 
					
						
							|  |  |  |         height: 500 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ko.applyBindings(attributesModel, $dialog[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $dialog.on('focus', '.attribute-name', function (e) { | 
					
						
							|  |  |  |     if (!$(this).hasClass("ui-autocomplete-input")) { | 
					
						
							|  |  |  |         $(this).autocomplete({ | 
					
						
							|  |  |  |             source: async (request, response) => { | 
					
						
							|  |  |  |                 const attribute = attributesModel.getTargetAttribute(this); | 
					
						
							| 
									
										
										
										
											2018-08-05 20:48:56 +02:00
										 |  |  |                 const type = (attribute().type === 'relation' || attribute().type === 'relation-definition') ? 'relation' : 'label'; | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |                 const names = await server.get('attributes/names/?type=' + type + '&query=' + encodeURIComponent(request.term)); | 
					
						
							|  |  |  |                 const result = names.map(name => { | 
					
						
							|  |  |  |                     return { | 
					
						
							|  |  |  |                         label: name, | 
					
						
							|  |  |  |                         value: name | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (result.length > 0) { | 
					
						
							|  |  |  |                     response(result); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     response([{ | 
					
						
							|  |  |  |                         label: "No results", | 
					
						
							|  |  |  |                         value: "No results" | 
					
						
							|  |  |  |                     }]); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             minLength: 0 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $(this).autocomplete("search", $(this).val()); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-03 13:06:56 +02:00
										 |  |  | $dialog.on('focus', '.label-value', async function (e) { | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  |     if (!$(this).hasClass("ui-autocomplete-input")) { | 
					
						
							|  |  |  |         const attributeName = $(this).parent().parent().find('.attribute-name').val(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (attributeName.trim() === "") { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const attributeValues = await server.get('attributes/values/' + encodeURIComponent(attributeName)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (attributeValues.length === 0) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $(this).autocomplete({ | 
					
						
							|  |  |  |             // shouldn't be required and autocomplete should just accept array of strings, but that fails
 | 
					
						
							|  |  |  |             // because we have overriden filter() function in autocomplete.js
 | 
					
						
							|  |  |  |             source: attributeValues.map(attribute => { | 
					
						
							|  |  |  |                 return { | 
					
						
							|  |  |  |                     attribute: attribute, | 
					
						
							|  |  |  |                     value: attribute | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }), | 
					
						
							|  |  |  |             minLength: 0 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $(this).autocomplete("search", $(this).val()); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-03 13:06:56 +02:00
										 |  |  | 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", ""); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-03 11:11:57 +02:00
										 |  |  | export default { | 
					
						
							|  |  |  |     showDialog | 
					
						
							|  |  |  | }; |