| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | import server from "../services/server.js"; | 
					
						
							|  |  |  | import treeCache from "../services/tree_cache.js"; | 
					
						
							|  |  |  | import treeService from "../services/tree.js"; | 
					
						
							|  |  |  | import linkService from "../services/link.js"; | 
					
						
							| 
									
										
										
										
											2020-07-26 00:04:34 +02:00
										 |  |  | import attributeAutocompleteService from "../services/attribute_autocomplete.js"; | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  | import noteAutocompleteService from "../services/note_autocomplete.js"; | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | import promotedAttributeDefinitionParser from '../services/promoted_attribute_definition_parser.js'; | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  | import TabAwareWidget from "./tab_aware_widget.js"; | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  | import SpacedUpdate from "../services/spaced_update.js"; | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | const TPL = `
 | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  | <div class="attr-detail"> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |     <style> | 
					
						
							|  |  |  |         .attr-detail { | 
					
						
							|  |  |  |             display: block; | 
					
						
							|  |  |  |             background-color: var(--accented-background-color); | 
					
						
							|  |  |  |             border: 1px solid var(--main-border-color); | 
					
						
							|  |  |  |             border-radius: 4px; | 
					
						
							|  |  |  |             z-index: 1000; | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  |             padding: 15px; | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |             position: absolute; | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             width: 500px; | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |             max-height: 600px; | 
					
						
							|  |  |  |             overflow: auto; | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             box-shadow: 10px 10px 93px -25px var(--main-text-color); | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         .related-notes-list { | 
					
						
							|  |  |  |             padding-left: 20px; | 
					
						
							|  |  |  |             margin-top: 10px; | 
					
						
							|  |  |  |             margin-bottom: 10px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         .attr-edit-table { | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |             width: 100%; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         .attr-edit-table th { | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |             text-align: left; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         .attr-edit-table td input { | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |             width: 100%; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-03 22:27:45 +02:00
										 |  |  |          | 
					
						
							|  |  |  |         .close-attr-detail-button { | 
					
						
							|  |  |  |             font-size: x-large; | 
					
						
							|  |  |  |             cursor: pointer; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |          | 
					
						
							|  |  |  |         .attr-save-delete-button-container { | 
					
						
							|  |  |  |             display: flex;  | 
					
						
							|  |  |  |             margin-top: 15px; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |     </style> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 22:27:45 +02:00
										 |  |  |     <div style="display: flex; justify-content: space-between;"> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |         <h5 class="attr-detail-title"></h5> | 
					
						
							| 
									
										
										
										
											2020-07-03 22:27:45 +02:00
										 |  |  |          | 
					
						
							|  |  |  |         <span class="bx bx-x close-attr-detail-button"></span> | 
					
						
							|  |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  |     <div class="attr-is-owned-by"></div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |     <table class="attr-edit-table"> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         <tr> | 
					
						
							|  |  |  |             <th>Name:</th> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             <td><input type="text" class="attr-input-name form-control" /></td> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         <tr class="attr-row-value"> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |             <th>Value:</th> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             <td><input type="text" class="attr-input-value form-control" /></td> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         <tr class="attr-row-target-note"> | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |             <th>Target note:</th> | 
					
						
							|  |  |  |             <td> | 
					
						
							|  |  |  |                 <div class="input-group"> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |                     <input type="text" class="attr-input-target-note form-control" /> | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |                 </div> | 
					
						
							|  |  |  |             </td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         <tr class="attr-row-promoted"> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |             <th>Promoted:</th> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             <td><input type="checkbox" class="attr-input-promoted form-control form-control-sm" /></td> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         <tr class="attr-row-multiplicity"> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |             <th>Multiplicity:</th> | 
					
						
							|  |  |  |             <td> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |                 <select class="attr-input-multiplicity form-control"> | 
					
						
							|  |  |  |                   <option value="single">Single value</option> | 
					
						
							|  |  |  |                   <option value="multi">Multi value</option> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |                 </select> | 
					
						
							|  |  |  |             </td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         <tr class="attr-row-label-type"> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |             <th>Type:</th> | 
					
						
							|  |  |  |             <td> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |                 <select class="attr-input-label-type form-control"> | 
					
						
							|  |  |  |                   <option value="text">Text</option> | 
					
						
							|  |  |  |                   <option value="number">Number</option> | 
					
						
							|  |  |  |                   <option value="boolean">Boolean</option> | 
					
						
							|  |  |  |                   <option value="date">Date</option> | 
					
						
							|  |  |  |                   <option value="url">URL</option> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |                 </select> | 
					
						
							|  |  |  |             </td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         <tr class="attr-row-number-precision"> | 
					
						
							|  |  |  |             <th>Precision:</th> | 
					
						
							|  |  |  |             <td> | 
					
						
							|  |  |  |                 <div class="input-group"> | 
					
						
							|  |  |  |                     <input type="number" class="form-control attr-input-number-precision" style="text-align: right"> | 
					
						
							|  |  |  |                     <div class="input-group-append"> | 
					
						
							|  |  |  |                         <span class="input-group-text">digits</span> | 
					
						
							|  |  |  |                     </div> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |             </td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							|  |  |  |         <tr class="attr-row-inverse-relation"> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |             <th>Inverse relation:</th> | 
					
						
							|  |  |  |             <td> | 
					
						
							|  |  |  |                 <div class="input-group"> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |                     <input type="text" class="attr-input-inverse-relation form-control" /> | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |                 </div> | 
					
						
							|  |  |  |             </td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         <tr> | 
					
						
							|  |  |  |             <th>Inheritable:</th> | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             <td><input type="checkbox" class="attr-input-inheritable form-control form-control-sm" /></td> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         </tr> | 
					
						
							|  |  |  |     </table> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |     <div class="attr-save-delete-button-container"> | 
					
						
							|  |  |  |         <button class="btn btn-primary btn-sm attr-save-changes-and-close-button"  | 
					
						
							|  |  |  |             style="flex-grow: 1; margin-right: 20px"> | 
					
						
							|  |  |  |             Save & close</button> | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |         <button class="btn btn-secondary btn-sm attr-delete-button"> | 
					
						
							|  |  |  |             Delete</button> | 
					
						
							|  |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2020-07-23 00:19:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  |     <div class="related-notes-container"> | 
					
						
							|  |  |  |         <br/> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  |         <h5 class="related-notes-tile">Other notes with this label</h5> | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         <ul class="related-notes-list"></ul> | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         <div class="related-notes-more-notes"></div> | 
					
						
							|  |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | </div>`; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const DISPLAYED_NOTES = 10; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  | const ATTR_TITLES = { | 
					
						
							|  |  |  |     "label": "Label detail", | 
					
						
							|  |  |  |     "label-definition": "Label definition detail", | 
					
						
							|  |  |  |     "relation": "Relation detail", | 
					
						
							|  |  |  |     "relation-definition": "Relation definition detail" | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  | export default class AttributeDetailWidget extends TabAwareWidget { | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |     doRender() { | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.relatedNotesSpacedUpdate = new SpacedUpdate(async () => this.updateRelatedNotes(), 1000); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         this.$widget = $(TPL); | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |         this.$title = this.$widget.find('.attr-detail-title'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  |         this.$relatedNotesContainer = this.$widget.find('.related-notes-container'); | 
					
						
							|  |  |  |         this.$relatedNotesTitle = this.$relatedNotesContainer.find('.related-notes-tile'); | 
					
						
							|  |  |  |         this.$relatedNotesList = this.$relatedNotesContainer.find('.related-notes-list'); | 
					
						
							|  |  |  |         this.$relatedNotesMoreNotes = this.$relatedNotesContainer.find('.related-notes-more-notes'); | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$inputName = this.$widget.find('.attr-input-name'); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.$inputName.on('keyup', () => this.userEditedAttribute()); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$inputName.on('focus', () => { | 
					
						
							| 
									
										
										
										
											2020-07-26 00:04:34 +02:00
										 |  |  |             attributeAutocompleteService.initAttributeNameAutocomplete({ | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |                 $el: this.$inputName, | 
					
						
							| 
									
										
										
										
											2020-07-26 00:04:34 +02:00
										 |  |  |                 attributeType: () => ['relation', 'relation-definition'].includes(this.attrType) ? 'relation' : 'label', | 
					
						
							|  |  |  |                 open: true | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowValue = this.$widget.find('.attr-row-value'); | 
					
						
							|  |  |  |         this.$inputValue = this.$widget.find('.attr-input-value'); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.$inputValue.on('keyup', () => this.userEditedAttribute()); | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$inputValue.on('focus', () => { | 
					
						
							| 
									
										
										
										
											2020-07-26 00:04:34 +02:00
										 |  |  |             attributeAutocompleteService.initLabelValueAutocomplete({ | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |                 $el: this.$inputValue, | 
					
						
							| 
									
										
										
										
											2020-07-26 00:04:34 +02:00
										 |  |  |                 open: true, | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |                 nameCallback: () => this.$inputName.val() | 
					
						
							| 
									
										
										
										
											2020-07-26 00:04:34 +02:00
										 |  |  |             }); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowPromoted = this.$widget.find('.attr-row-promoted'); | 
					
						
							|  |  |  |         this.$inputPromoted = this.$widget.find('.attr-input-promoted'); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.$inputPromoted.on('change', () => this.userEditedAttribute()); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowMultiplicity = this.$widget.find('.attr-row-multiplicity'); | 
					
						
							|  |  |  |         this.$inputMultiplicity = this.$widget.find('.attr-input-multiplicity'); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.$inputMultiplicity.on('change', () => this.userEditedAttribute()); | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowLabelType = this.$widget.find('.attr-row-label-type'); | 
					
						
							|  |  |  |         this.$inputLabelType = this.$widget.find('.attr-input-label-type'); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.$inputLabelType.on('change', () => this.userEditedAttribute()); | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowNumberPrecision = this.$widget.find('.attr-row-number-precision'); | 
					
						
							|  |  |  |         this.$inputNumberPrecision = this.$widget.find('.attr-input-number-precision'); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.$inputNumberPrecision.on('change', () => this.userEditedAttribute()); | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowInverseRelation = this.$widget.find('.attr-row-inverse-relation'); | 
					
						
							|  |  |  |         this.$inputInverseRelation = this.$widget.find('.attr-input-inverse-relation'); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.$inputInverseRelation.on('keyup', () => this.userEditedAttribute()); | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowTargetNote = this.$widget.find('.attr-row-target-note'); | 
					
						
							|  |  |  |         this.$inputTargetNote = this.$widget.find('.attr-input-target-note'); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         noteAutocompleteService.initNoteAutocomplete(this.$inputTargetNote) | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |             .on('autocomplete:selected', (event, suggestion, dataset) => { | 
					
						
							|  |  |  |                 if (!suggestion.notePath) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 this.attribute.value = suggestion.notePath; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 this.triggerCommand('updateAttributeList', { attributes: this.allAttributes }); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |                 this.updateRelatedNotes(); | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$inputInheritable = this.$widget.find('.attr-input-inheritable'); | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         this.$inputInheritable.on('change', () => this.userEditedAttribute()); | 
					
						
							| 
									
										
										
										
											2020-07-13 23:27:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 22:27:45 +02:00
										 |  |  |         this.$closeAttrDetailButton = this.$widget.find('.close-attr-detail-button'); | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  |         this.$attrIsOwnedBy = this.$widget.find('.attr-is-owned-by'); | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$attrSaveDeleteButtonContainer = this.$widget.find('.attr-save-delete-button-container'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 00:19:50 +02:00
										 |  |  |         this.$saveAndCloseButton = this.$widget.find('.attr-save-changes-and-close-button'); | 
					
						
							|  |  |  |         this.$saveAndCloseButton.on('click', async () => { | 
					
						
							|  |  |  |             await this.triggerCommand('saveAttributes'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.hide(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$deleteButton = this.$widget.find('.attr-delete-button'); | 
					
						
							|  |  |  |         this.$deleteButton.on('click', async () => { | 
					
						
							|  |  |  |             await this.triggerCommand('updateAttributeList', { | 
					
						
							|  |  |  |                 attributes: this.allAttributes.filter(attr => attr !== this.attribute) | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             await this.triggerCommand('saveAttributes'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.hide(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 22:27:45 +02:00
										 |  |  |         this.$closeAttrDetailButton.on('click', () => this.hide()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $(window).on('mouseup', e => { | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |             if (!$(e.target).closest(this.$widget[0]).length | 
					
						
							|  |  |  |                 && !$(e.target).closest(".algolia-autocomplete").length) { | 
					
						
							| 
									
										
										
										
											2020-07-03 22:27:45 +02:00
										 |  |  |                 this.hide(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.toggleInt(false); // initial state is hidden
 | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |     userEditedAttribute() { | 
					
						
							|  |  |  |         this.updateAttributeInEditor(); | 
					
						
							|  |  |  |         this.relatedNotesSpacedUpdate.scheduleUpdate(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-09 23:59:27 +02:00
										 |  |  |     async showAttributeDetail({allAttributes, attribute, isOwned, x, y}) { | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  |         if (!attribute) { | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |             this.hide(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         this.attrType = this.getAttrType(attribute); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         const attrName = | 
					
						
							|  |  |  |             this.attrType === 'label-definition' ? attribute.name.substr(6) | 
					
						
							|  |  |  |                 : (this.attrType === 'relation-definition' ? attribute.name.substr(9) : attribute.name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         const definition = this.attrType.endsWith('-definition') | 
					
						
							|  |  |  |             ? promotedAttributeDefinitionParser.parse(attribute.value) | 
					
						
							|  |  |  |             : {}; | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         this.$title.text(ATTR_TITLES[this.attrType]); | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-09 23:59:27 +02:00
										 |  |  |         this.allAttributes = allAttributes; | 
					
						
							|  |  |  |         this.attribute = attribute; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |         await this.updateRelatedNotes(); | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$attrSaveDeleteButtonContainer.toggle(!!isOwned); | 
					
						
							| 
									
										
										
										
											2020-08-11 22:52:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  |         if (isOwned) { | 
					
						
							|  |  |  |             this.$attrIsOwnedBy.hide(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             this.$attrIsOwnedBy | 
					
						
							|  |  |  |                 .show() | 
					
						
							| 
									
										
										
										
											2020-08-11 22:52:17 +02:00
										 |  |  |                 .empty() | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  |                 .append(attribute.type === 'label' ? 'Label' : 'Relation') | 
					
						
							|  |  |  |                 .append(' is owned by note ') | 
					
						
							|  |  |  |                 .append(await linkService.createNoteLink(attribute.noteId)) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$inputName | 
					
						
							| 
									
										
										
										
											2020-07-22 23:42:58 +02:00
										 |  |  |             .val(attrName) | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |             .attr('readonly', () => !isOwned); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowValue.toggle(this.attrType === 'label'); | 
					
						
							|  |  |  |         this.$rowTargetNote.toggle(this.attrType === 'relation'); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowPromoted.toggle(['label-definition', 'relation-definition'].includes(this.attrType)); | 
					
						
							|  |  |  |         this.$inputPromoted | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             .prop("checked", !!definition.isPromoted) | 
					
						
							|  |  |  |             .attr('disabled', () => !isOwned); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowMultiplicity.toggle(['label-definition', 'relation-definition'].includes(this.attrType)); | 
					
						
							|  |  |  |         this.$inputMultiplicity | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             .val(definition.multiplicity) | 
					
						
							|  |  |  |             .attr('disabled', () => !isOwned); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowLabelType.toggle(this.attrType === 'label-definition'); | 
					
						
							|  |  |  |         this.$inputLabelType | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             .val(definition.labelType) | 
					
						
							|  |  |  |             .attr('disabled', () => !isOwned); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowNumberPrecision.toggle(this.attrType === 'label-definition' && definition.labelType === 'number'); | 
					
						
							|  |  |  |         this.$inputNumberPrecision | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             .val(definition.numberPrecision) | 
					
						
							|  |  |  |             .attr('disabled', () => !isOwned); | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowInverseRelation.toggle(this.attrType === 'relation-definition'); | 
					
						
							|  |  |  |         this.$inputInverseRelation | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             .val(definition.inverseRelation) | 
					
						
							|  |  |  |             .attr('disabled', () => !isOwned); | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |         if (attribute.type === 'label') { | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             this.$inputValue | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |                 .val(attribute.value) | 
					
						
							|  |  |  |                 .attr('readonly', () => !isOwned); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (attribute.type === 'relation') { | 
					
						
							|  |  |  |             const targetNote = await treeCache.getNote(attribute.value); | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             this.$inputTargetNote | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |                 .attr('readonly', () => !isOwned) | 
					
						
							|  |  |  |                 .val(targetNote ? targetNote.title : "") | 
					
						
							|  |  |  |                 .setSelectedNotePath(attribute.value); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$inputInheritable | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  |             .prop("checked", !!attribute.isInheritable) | 
					
						
							|  |  |  |             .attr('disabled', () => !isOwned); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.toggleInt(true); | 
					
						
							| 
									
										
										
										
											2020-07-13 23:27:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-14 23:29:37 +02:00
										 |  |  |         this.$widget.css("left", x - this.$widget.outerWidth() / 2); | 
					
						
							|  |  |  |         this.$widget.css("top", y + 25); | 
					
						
							| 
									
										
										
										
											2020-07-26 00:09:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // so that the detail window always fits
 | 
					
						
							|  |  |  |         this.$widget.css("max-height", | 
					
						
							|  |  |  |             this.$widget.outerHeight() + y > $(window).height() - 50 | 
					
						
							|  |  |  |                         ? $(window).height() - y - 50 | 
					
						
							|  |  |  |                         : 10000); | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 23:00:15 +02:00
										 |  |  |     async updateRelatedNotes() { | 
					
						
							|  |  |  |         let {results, count} = await server.post('search-related', this.attribute); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const res of results) { | 
					
						
							|  |  |  |             res.noteId = res.notePathArray[res.notePathArray.length - 1]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         results = results.filter(({noteId}) => noteId !== this.noteId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (results.length === 0) { | 
					
						
							|  |  |  |             this.$relatedNotesContainer.hide(); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             this.$relatedNotesContainer.show(); | 
					
						
							|  |  |  |             this.$relatedNotesTitle.text(`Other notes with ${this.attribute.type} name "${this.attribute.name}"`); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.$relatedNotesList.empty(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const displayedResults = results.length <= DISPLAYED_NOTES ? results : results.slice(0, DISPLAYED_NOTES); | 
					
						
							|  |  |  |             const displayedNotes = await treeCache.getNotes(displayedResults.map(res => res.noteId)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (const note of displayedNotes) { | 
					
						
							|  |  |  |                 const notePath = treeService.getSomeNotePath(note); | 
					
						
							|  |  |  |                 const $noteLink = await linkService.createNoteLink(notePath, {showNotePath: true}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 this.$relatedNotesList.append( | 
					
						
							|  |  |  |                     $("<li>").append($noteLink) | 
					
						
							|  |  |  |                 ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (results.length > DISPLAYED_NOTES) { | 
					
						
							|  |  |  |                 this.$relatedNotesMoreNotes.show().text(`... and ${count - DISPLAYED_NOTES} more.`); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 this.$relatedNotesMoreNotes.hide(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-15 00:09:37 +02:00
										 |  |  |     getAttrType(attribute) { | 
					
						
							|  |  |  |         if (attribute.type === 'label') { | 
					
						
							|  |  |  |             if (attribute.name.startsWith('label:')) { | 
					
						
							|  |  |  |                 return "label-definition"; | 
					
						
							|  |  |  |             } else if (attribute.name.startsWith('relation:')) { | 
					
						
							|  |  |  |                 return "relation-definition"; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 return "label"; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (attribute.type === 'relation') { | 
					
						
							|  |  |  |             return "relation"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             this.$title.text(''); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 23:58:01 +02:00
										 |  |  |     updateAttributeInEditor() { | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         let attrName = this.$inputName.val(); | 
					
						
							| 
									
										
										
										
											2020-07-22 23:42:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (this.attrType === 'label-definition') { | 
					
						
							|  |  |  |             attrName = 'label:' + attrName; | 
					
						
							|  |  |  |         } else if (this.attrType === 'relation-definition') { | 
					
						
							|  |  |  |             attrName = 'relation:' + attrName; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.attribute.name = attrName; | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.attribute.isInheritable = this.$inputInheritable.is(":checked"); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 23:58:01 +02:00
										 |  |  |         if (this.attrType.endsWith('-definition')) { | 
					
						
							|  |  |  |             this.attribute.value = this.buildDefinitionValue(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-12 23:39:05 +02:00
										 |  |  |         else if (this.attrType === 'relation') { | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             this.attribute.value = this.$inputTargetNote.getSelectedNoteId(); | 
					
						
							| 
									
										
										
										
											2020-08-12 23:39:05 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-22 23:58:01 +02:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             this.attribute.value = this.$inputValue.val(); | 
					
						
							| 
									
										
										
										
											2020-07-22 23:58:01 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         this.triggerCommand('updateAttributeList', { attributes: this.allAttributes }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 23:58:01 +02:00
										 |  |  |     buildDefinitionValue() { | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         const props = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         if (this.$inputPromoted.is(":checked")) { | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             props.push("promoted"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         props.push(this.$inputMultiplicity.val()); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (this.attrType === 'label-definition') { | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             props.push(this.$inputLabelType.val()); | 
					
						
							| 
									
										
										
										
											2020-07-23 00:19:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             if (this.$inputLabelType.val() === 'number' && this.$inputNumberPrecision.val() !== '') { | 
					
						
							|  |  |  |                 props.push('precision=' + this.$inputNumberPrecision.val()); | 
					
						
							| 
									
										
										
										
											2020-07-23 00:19:50 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         } else if (this.attrType === 'relation-definition' && this.$inputInverseRelation.val().trim().length > 0) { | 
					
						
							|  |  |  |             props.push("inverse=" + this.$inputInverseRelation.val()); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |         this.$rowNumberPrecision.toggle( | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  |             this.attrType === 'label-definition' | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  |             && this.$inputLabelType.val() === 'number'); | 
					
						
							| 
									
										
										
										
											2020-07-18 23:45:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 23:58:01 +02:00
										 |  |  |         return props.join(","); | 
					
						
							| 
									
										
										
										
											2020-07-09 23:59:27 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |     hide() { | 
					
						
							|  |  |  |         this.toggleInt(false); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     createNoteLink(noteId) { | 
					
						
							|  |  |  |         return $("<a>", { | 
					
						
							|  |  |  |             href: '#' + noteId, | 
					
						
							|  |  |  |             class: 'reference-link', | 
					
						
							|  |  |  |             'data-note-path': noteId | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-13 23:23:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     async noteSwitched() { | 
					
						
							|  |  |  |         this.hide(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | } |