| 
									
										
										
										
											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"; | 
					
						
							|  |  |  | import BasicWidget from "./basic_widget.js"; | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  | import noteAutocompleteService from "../services/note_autocomplete.js"; | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | const TPL = `
 | 
					
						
							|  |  |  | <div class="attr-detail" style="display: none;"> | 
					
						
							|  |  |  |     <style> | 
					
						
							|  |  |  |         .attr-detail { | 
					
						
							|  |  |  |             display: block; | 
					
						
							|  |  |  |             background-color: var(--accented-background-color); | 
					
						
							|  |  |  |             border: 1px solid var(--main-border-color); | 
					
						
							|  |  |  |             border-radius: 4px; | 
					
						
							|  |  |  |             z-index: 1000; | 
					
						
							|  |  |  |             padding: 10px; | 
					
						
							|  |  |  |             position: absolute; | 
					
						
							|  |  |  |             max-width: 600px; | 
					
						
							|  |  |  |             max-height: 600px; | 
					
						
							|  |  |  |             overflow: auto; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         .related-notes-list { | 
					
						
							|  |  |  |             padding-left: 20px; | 
					
						
							|  |  |  |             margin-top: 10px; | 
					
						
							|  |  |  |             margin-bottom: 10px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         .attr-edit { | 
					
						
							|  |  |  |             width: 100%; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         .attr-edit th { | 
					
						
							|  |  |  |             text-align: left; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         .attr-edit td input { | 
					
						
							|  |  |  |             width: 100%; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-03 22:27:45 +02:00
										 |  |  |          | 
					
						
							|  |  |  |         .close-attr-detail-button { | 
					
						
							|  |  |  |             font-size: x-large; | 
					
						
							|  |  |  |             cursor: pointer; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											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;"> | 
					
						
							|  |  |  |         <h5>Label detail</h5> | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         <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-06-26 22:17:39 +02:00
										 |  |  |     <table class="attr-edit"> | 
					
						
							|  |  |  |         <tr> | 
					
						
							|  |  |  |             <th>Name:</th> | 
					
						
							|  |  |  |             <td><input type="text" class="attr-edit-name form-control form-control-sm" /></td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |         <tr class="attr-value-row"> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |             <th>Value:</th> | 
					
						
							|  |  |  |             <td><input type="text" class="attr-edit-value form-control form-control-sm" /></td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |         <tr class="attr-target-note-row"> | 
					
						
							|  |  |  |             <th>Target note:</th> | 
					
						
							|  |  |  |             <td> | 
					
						
							|  |  |  |                 <div class="input-group"> | 
					
						
							|  |  |  |                     <input type="text" class="attr-edit-target-note form-control" /> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |             </td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         <tr> | 
					
						
							|  |  |  |             <th>Inheritable:</th> | 
					
						
							|  |  |  |             <td><input type="checkbox" class="attr-edit-inheritable form-control form-control-sm" /></td> | 
					
						
							|  |  |  |         </tr> | 
					
						
							|  |  |  |     </table> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <br/> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <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>`; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const DISPLAYED_NOTES = 10; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default class AttributeDetailWidget extends BasicWidget { | 
					
						
							|  |  |  |     doRender() { | 
					
						
							|  |  |  |         this.$widget = $(TPL); | 
					
						
							|  |  |  |         this.$relatedNotesTitle = this.$widget.find('.related-notes-tile'); | 
					
						
							|  |  |  |         this.$relatedNotesList = this.$widget.find('.related-notes-list'); | 
					
						
							|  |  |  |         this.$relatedNotesMoreNotes = this.$widget.find('.related-notes-more-notes'); | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         this.$attrEditName = this.$widget.find('.attr-edit-name'); | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |         this.$attrEditName.on('keyup', () => this.updateParent()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.$attrValueRow = this.$widget.find('.attr-value-row'); | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         this.$attrEditValue = this.$widget.find('.attr-edit-value'); | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |         this.$attrEditValue.on('keyup', () => this.updateParent()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.$attrTargetNoteRow = this.$widget.find('.attr-target-note-row'); | 
					
						
							|  |  |  |         this.$attrEditTargetNote = this.$widget.find('.attr-edit-target-note'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         noteAutocompleteService.initNoteAutocomplete(this.$attrEditTargetNote) | 
					
						
							|  |  |  |             .on('autocomplete:selected', (event, suggestion, dataset) => { | 
					
						
							|  |  |  |                 if (!suggestion.notePath) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 this.attribute.value = suggestion.notePath; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 this.triggerCommand('updateAttributeList', { attributes: this.allAttributes }); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         this.$attrEditInheritable = this.$widget.find('.attr-edit-inheritable'); | 
					
						
							| 
									
										
										
										
											2020-07-13 23:27:23 +02:00
										 |  |  |         this.$attrEditInheritable.on('change', () => this.updateParent()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-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-06-26 22:17:39 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-09 23:59:27 +02:00
										 |  |  |         this.allAttributes = allAttributes; | 
					
						
							|  |  |  |         this.attribute = attribute; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         this.toggleInt(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  |         let {results, count} = await server.post('search-related', attribute); | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         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.$relatedNotesTitle.hide(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  |             this.$relatedNotesTitle.text(`Other notes with ${attribute.type} name "${attribute.name}"`); | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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-05 23:53:55 +02:00
										 |  |  |         if (isOwned) { | 
					
						
							|  |  |  |             this.$attrIsOwnedBy.hide(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             this.$attrIsOwnedBy | 
					
						
							|  |  |  |                 .show() | 
					
						
							|  |  |  |                 .append(attribute.type === 'label' ? 'Label' : 'Relation') | 
					
						
							|  |  |  |                 .append(' is owned by note ') | 
					
						
							|  |  |  |                 .append(await linkService.createNoteLink(attribute.noteId)) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.$attrEditName | 
					
						
							|  |  |  |             .val(attribute.name) | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |             .attr('readonly', () => !isOwned); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.$attrValueRow.toggle(attribute.type === 'label'); | 
					
						
							|  |  |  |         this.$attrTargetNoteRow.toggle(attribute.type === 'relation'); | 
					
						
							| 
									
										
										
										
											2020-07-05 23:53:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 00:15:00 +02:00
										 |  |  |         if (attribute.type === 'label') { | 
					
						
							|  |  |  |             this.$attrEditValue | 
					
						
							|  |  |  |                 .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-07-13 00:15:00 +02:00
										 |  |  |             this.$attrEditTargetNote | 
					
						
							|  |  |  |                 .attr('readonly', () => !isOwned) | 
					
						
							|  |  |  |                 .val(targetNote ? targetNote.title : "") | 
					
						
							|  |  |  |                 .setSelectedNotePath(attribute.value); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 23:27:23 +02:00
										 |  |  |         this.$attrEditInheritable.prop("checked", !!attribute.isInheritable); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 22:17:39 +02:00
										 |  |  |         this.$widget.css("left", x - this.$widget.width() / 2); | 
					
						
							|  |  |  |         this.$widget.css("top", y + 30); | 
					
						
							|  |  |  |         this.$widget.show(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-09 23:59:27 +02:00
										 |  |  |     updateParent() { | 
					
						
							|  |  |  |         this.attribute.name = this.$attrEditName.val(); | 
					
						
							|  |  |  |         this.attribute.value = this.$attrEditValue.val(); | 
					
						
							| 
									
										
										
										
											2020-07-13 23:27:23 +02:00
										 |  |  |         this.attribute.isInheritable = this.$attrEditInheritable.is(":checked"); | 
					
						
							| 
									
										
										
										
											2020-07-09 23:59:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.triggerCommand('updateAttributeList', { attributes: this.allAttributes }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |