mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-27 09:39:00 +01:00 
			
		
		
		
	converted note type chooser dialog to new pattern
This commit is contained in:
		
							parent
							
								
									ebd715ca1b
								
							
						
					
					
						commit
						1347d3fcc2
					
				| @ -1,94 +0,0 @@ | |||||||
| import noteTypesService from "../services/note_types.js"; |  | ||||||
| 
 |  | ||||||
| const $dialog = $("#note-type-chooser-dialog"); |  | ||||||
| const $noteTypeDropdown = $("#note-type-dropdown"); |  | ||||||
| const $noteTypeDropdownTrigger = $("#note-type-dropdown-trigger"); |  | ||||||
| $noteTypeDropdownTrigger.dropdown(); |  | ||||||
| 
 |  | ||||||
| let resolve; |  | ||||||
| let $originalFocused; // element focused before the dialog was opened, so we can return to it afterwards
 |  | ||||||
| let $originalDialog; |  | ||||||
| 
 |  | ||||||
| export async function chooseNoteType() { |  | ||||||
|     $originalFocused = $(':focus'); |  | ||||||
| 
 |  | ||||||
|     const noteTypes = await noteTypesService.getNoteTypeItems(); |  | ||||||
| 
 |  | ||||||
|     $noteTypeDropdown.empty(); |  | ||||||
| 
 |  | ||||||
|     for (const noteType of noteTypes) { |  | ||||||
|         if (noteType.title === '----') { |  | ||||||
|             $noteTypeDropdown.append($('<h6 class="dropdown-header">').append("Templates:")); |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|             $noteTypeDropdown.append( |  | ||||||
|                 $('<a class="dropdown-item" tabindex="0">') |  | ||||||
|                     .attr("data-note-type", noteType.type) |  | ||||||
|                     .attr("data-template-note-id", noteType.templateNoteId) |  | ||||||
|                     .append($("<span>").addClass(noteType.uiIcon)) |  | ||||||
|                     .append(" " + noteType.title) |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     $noteTypeDropdownTrigger.dropdown('show'); |  | ||||||
| 
 |  | ||||||
|     $originalDialog = glob.activeDialog; |  | ||||||
|     glob.activeDialog = $dialog; |  | ||||||
|     $dialog.modal(); |  | ||||||
| 
 |  | ||||||
|     $noteTypeDropdown.find(".dropdown-item:first").focus(); |  | ||||||
| 
 |  | ||||||
|     return new Promise((res, rej) => { resolve = res; }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| $dialog.on("hidden.bs.modal", () => { |  | ||||||
|     if (resolve) { |  | ||||||
|         resolve({success: false}); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if ($originalFocused) { |  | ||||||
|         $originalFocused.trigger('focus'); |  | ||||||
|         $originalFocused = null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     glob.activeDialog = $originalDialog; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| function doResolve(e) { |  | ||||||
|     const $item = $(e.target).closest(".dropdown-item"); |  | ||||||
|     const noteType = $item.attr("data-note-type"); |  | ||||||
|     const templateNoteId = $item.attr("data-template-note-id"); |  | ||||||
| 
 |  | ||||||
|     resolve({ |  | ||||||
|         success: true, |  | ||||||
|         noteType, |  | ||||||
|         templateNoteId |  | ||||||
|     }); |  | ||||||
|     resolve = null; |  | ||||||
| 
 |  | ||||||
|     $dialog.modal("hide"); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| $noteTypeDropdown.on('click', '.dropdown-item', e => doResolve(e)); |  | ||||||
| 
 |  | ||||||
| $noteTypeDropdown.on('focus', '.dropdown-item', e => { |  | ||||||
|     $noteTypeDropdown.find('.dropdown-item').each((i, el) => { |  | ||||||
|         $(el).toggleClass('active', el === e.target); |  | ||||||
|     }); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| $noteTypeDropdown.on('keydown', '.dropdown-item', e => { |  | ||||||
|     if (e.key === 'Enter') { |  | ||||||
|         doResolve(e); |  | ||||||
|         e.preventDefault(); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| $noteTypeDropdown.parent().on('hide.bs.dropdown', e => { |  | ||||||
|     // prevent closing dropdown by clicking outside
 |  | ||||||
|     if (e.clickEvent) { |  | ||||||
|         e.preventDefault(); |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
| @ -60,6 +60,7 @@ import BranchPrefixDialog from "../widgets/dialogs/branch_prefix.js"; | |||||||
| import SortChildNotesDialog from "../widgets/dialogs/sort_child_notes.js"; | import SortChildNotesDialog from "../widgets/dialogs/sort_child_notes.js"; | ||||||
| import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js"; | import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js"; | ||||||
| import IncludeNoteDialog from "../widgets/dialogs/include_note.js"; | import IncludeNoteDialog from "../widgets/dialogs/include_note.js"; | ||||||
|  | import NoteTypeChooserDialog from "../widgets/dialogs/note_type_chooser.js"; | ||||||
| 
 | 
 | ||||||
| export default class DesktopLayout { | export default class DesktopLayout { | ||||||
|     constructor(customWidgets) { |     constructor(customWidgets) { | ||||||
| @ -194,6 +195,7 @@ export default class DesktopLayout { | |||||||
|             .child(new BranchPrefixDialog()) |             .child(new BranchPrefixDialog()) | ||||||
|             .child(new SortChildNotesDialog()) |             .child(new SortChildNotesDialog()) | ||||||
|             .child(new PasswordNoteSetDialog()) |             .child(new PasswordNoteSetDialog()) | ||||||
|             .child(new IncludeNoteDialog()); |             .child(new IncludeNoteDialog()) | ||||||
|  |             .child(new NoteTypeChooserDialog()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -172,8 +172,7 @@ function initNoteAutocomplete($el, options) { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (suggestion.action === 'create-note') { |         if (suggestion.action === 'create-note') { | ||||||
|             const noteTypeChooserDialog = await import('../dialogs/note_type_chooser.js'); |             const {success, noteType, templateNoteId} = await noteCreateService.chooseNoteType(); | ||||||
|             const {success, noteType, templateNoteId} = await noteTypeChooserDialog.chooseNoteType(); |  | ||||||
| 
 | 
 | ||||||
|             if (!success) { |             if (!success) { | ||||||
|                 return; |                 return; | ||||||
|  | |||||||
| @ -75,9 +75,14 @@ async function createNote(parentNotePath, options = {}) { | |||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | async function chooseNoteType() { | ||||||
|  |     return new Promise(res => { | ||||||
|  |         appContext.triggerCommand("chooseNoteType", {callback: res}); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| async function createNoteWithTypePrompt(parentNotePath, options = {}) { | async function createNoteWithTypePrompt(parentNotePath, options = {}) { | ||||||
|     const noteTypeChooserDialog = await import('../dialogs/note_type_chooser.js'); |     const {success, noteType, templateNoteId} = await chooseNoteType(); | ||||||
|     const {success, noteType, templateNoteId} = await noteTypeChooserDialog.chooseNoteType(); |  | ||||||
| 
 | 
 | ||||||
|     if (!success) { |     if (!success) { | ||||||
|         return; |         return; | ||||||
| @ -121,5 +126,6 @@ async function duplicateSubtree(noteId, parentNotePath) { | |||||||
| export default { | export default { | ||||||
|     createNote, |     createNote, | ||||||
|     createNoteWithTypePrompt, |     createNoteWithTypePrompt, | ||||||
|     duplicateSubtree |     duplicateSubtree, | ||||||
|  |     chooseNoteType | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										138
									
								
								src/public/app/widgets/dialogs/note_type_chooser.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/public/app/widgets/dialogs/note_type_chooser.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,138 @@ | |||||||
|  | import noteTypesService from "../../services/note_types.js"; | ||||||
|  | import BasicWidget from "../basic_widget.js"; | ||||||
|  | 
 | ||||||
|  | const TPL = ` | ||||||
|  | <div class="note-type-chooser-dialog modal mx-auto" tabindex="-1" role="dialog"> | ||||||
|  |     <style> | ||||||
|  |         .note-type-dropdown { | ||||||
|  |             position: relative; | ||||||
|  |             font-size: large; | ||||||
|  |             padding: 20px; | ||||||
|  |             width: 100%; | ||||||
|  |             margin-top: 15px; | ||||||
|  |             max-height: 80vh; | ||||||
|  |             overflow: auto; | ||||||
|  |         } | ||||||
|  |     </style> | ||||||
|  |     <div class="modal-dialog" style="max-width: 500px;" role="document"> | ||||||
|  |         <div class="modal-content"> | ||||||
|  |             <div class="modal-header"> | ||||||
|  |                 <h5 class="modal-title mr-auto">Choose note type</h5> | ||||||
|  | 
 | ||||||
|  |                 <button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0 !important;"> | ||||||
|  |                     <span aria-hidden="true">×</span> | ||||||
|  |                 </button> | ||||||
|  |             </div> | ||||||
|  |             <div class="modal-body"> | ||||||
|  |                 Choose note type / template of the new note: | ||||||
|  | 
 | ||||||
|  |                 <div class="dropdown"> | ||||||
|  |                     <button class="note-type-dropdown-trigger" type="button" style="display: none;" data-toggle="dropdown">Dropdown trigger</button> | ||||||
|  | 
 | ||||||
|  |                     <div class="note-type-dropdown dropdown-menu"></div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div>`; | ||||||
|  | 
 | ||||||
|  | export default class NoteTypeChooserDialog extends BasicWidget { | ||||||
|  |     constructor(props) { | ||||||
|  |         super(props); | ||||||
|  | 
 | ||||||
|  |         this.resolve = null; | ||||||
|  |         this.$originalFocused = null; // element focused before the dialog was opened, so we can return to it afterwards
 | ||||||
|  |         this.$originalDialog = null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     doRender() { | ||||||
|  |         this.$widget = $(TPL); | ||||||
|  |         this.$noteTypeDropdown = this.$widget.find(".note-type-dropdown"); | ||||||
|  |         this.$noteTypeDropdownTrigger = this.$widget.find(".note-type-dropdown-trigger"); | ||||||
|  |         this.$noteTypeDropdownTrigger.dropdown(); | ||||||
|  | 
 | ||||||
|  |         this.$widget.on("hidden.bs.modal", () => { | ||||||
|  |             if (this.resolve) { | ||||||
|  |                 this.resolve({success: false}); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (this.$originalFocused) { | ||||||
|  |                 this.$originalFocused.trigger('focus'); | ||||||
|  |                 this.$originalFocused = null; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             glob.activeDialog = this.$originalDialog; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         this.$noteTypeDropdown.on('click', '.dropdown-item', e => this.doResolve(e)); | ||||||
|  | 
 | ||||||
|  |         this.$noteTypeDropdown.on('focus', '.dropdown-item', e => { | ||||||
|  |             this.$noteTypeDropdown.find('.dropdown-item').each((i, el) => { | ||||||
|  |                 $(el).toggleClass('active', el === e.target); | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         this.$noteTypeDropdown.on('keydown', '.dropdown-item', e => { | ||||||
|  |             if (e.key === 'Enter') { | ||||||
|  |                 this.doResolve(e); | ||||||
|  |                 e.preventDefault(); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         this.$noteTypeDropdown.parent().on('hide.bs.dropdown', e => { | ||||||
|  |             // prevent closing dropdown by clicking outside
 | ||||||
|  |             if (e.clickEvent) { | ||||||
|  |                 e.preventDefault(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async chooseNoteTypeEvent({callback}) { | ||||||
|  |         this.$originalFocused = $(':focus'); | ||||||
|  | 
 | ||||||
|  |         const noteTypes = await noteTypesService.getNoteTypeItems(); | ||||||
|  | 
 | ||||||
|  |         this.$noteTypeDropdown.empty(); | ||||||
|  | 
 | ||||||
|  |         for (const noteType of noteTypes) { | ||||||
|  |             if (noteType.title === '----') { | ||||||
|  |                 this.$noteTypeDropdown.append($('<h6 class="dropdown-header">').append("Templates:")); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 this.$noteTypeDropdown.append( | ||||||
|  |                     $('<a class="dropdown-item" tabindex="0">') | ||||||
|  |                         .attr("data-note-type", noteType.type) | ||||||
|  |                         .attr("data-template-note-id", noteType.templateNoteId) | ||||||
|  |                         .append($("<span>").addClass(noteType.uiIcon)) | ||||||
|  |                         .append(" " + noteType.title) | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.$noteTypeDropdownTrigger.dropdown('show'); | ||||||
|  | 
 | ||||||
|  |         this.$originalDialog = glob.activeDialog; | ||||||
|  |         glob.activeDialog = this.$widget; | ||||||
|  |         this.$widget.modal(); | ||||||
|  | 
 | ||||||
|  |         this.$noteTypeDropdown.find(".dropdown-item:first").focus(); | ||||||
|  | 
 | ||||||
|  |         this.resolve = callback; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     doResolve(e) { | ||||||
|  |         const $item = $(e.target).closest(".dropdown-item"); | ||||||
|  |         const noteType = $item.attr("data-note-type"); | ||||||
|  |         const templateNoteId = $item.attr("data-template-note-id"); | ||||||
|  | 
 | ||||||
|  |         this.resolve({ | ||||||
|  |             success: true, | ||||||
|  |             noteType, | ||||||
|  |             templateNoteId | ||||||
|  |         }); | ||||||
|  |         this.resolve = null; | ||||||
|  | 
 | ||||||
|  |         this.$widget.modal("hide"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -31,7 +31,6 @@ | |||||||
| <%- include('dialogs/clone_to.ejs') %> | <%- include('dialogs/clone_to.ejs') %> | ||||||
| <%- include('dialogs/move_to.ejs') %> | <%- include('dialogs/move_to.ejs') %> | ||||||
| <%- include('dialogs/delete_notes.ejs') %> | <%- include('dialogs/delete_notes.ejs') %> | ||||||
| <%- include('dialogs/note_type_chooser.ejs') %> |  | ||||||
| 
 | 
 | ||||||
| <script type="text/javascript"> | <script type="text/javascript"> | ||||||
|     global = globalThis; /* fixes https://github.com/webpack/webpack/issues/10035 */ |     global = globalThis; /* fixes https://github.com/webpack/webpack/issues/10035 */ | ||||||
|  | |||||||
| @ -1,34 +0,0 @@ | |||||||
| <style> |  | ||||||
|     #note-type-dropdown { |  | ||||||
|         position: relative; |  | ||||||
|         font-size: large; |  | ||||||
|         padding: 20px; |  | ||||||
|         width: 100%; |  | ||||||
|         margin-top: 15px; |  | ||||||
|         max-height: 80vh; |  | ||||||
|         overflow: auto; |  | ||||||
|     } |  | ||||||
| </style> |  | ||||||
| 
 |  | ||||||
| <div id="note-type-chooser-dialog" class="modal mx-auto" tabindex="-1" role="dialog"> |  | ||||||
|     <div class="modal-dialog" style="max-width: 500px;" role="document"> |  | ||||||
|         <div class="modal-content"> |  | ||||||
|             <div class="modal-header"> |  | ||||||
|                 <h5 class="modal-title mr-auto">Choose note type</h5> |  | ||||||
| 
 |  | ||||||
|                 <button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0 !important;"> |  | ||||||
|                     <span aria-hidden="true">×</span> |  | ||||||
|                 </button> |  | ||||||
|             </div> |  | ||||||
|             <div class="modal-body"> |  | ||||||
|                 Choose note type / template of the new note: |  | ||||||
| 
 |  | ||||||
|                 <div class="dropdown"> |  | ||||||
|                     <button id="note-type-dropdown-trigger" type="button" style="display: none;" data-toggle="dropdown">Dropdown trigger</button> |  | ||||||
| 
 |  | ||||||
|                     <div id="note-type-dropdown" class="dropdown-menu"></div> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam