mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	converted note type chooser dialog to new pattern
This commit is contained in:
		| @@ -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 PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js"; | ||||
| import IncludeNoteDialog from "../widgets/dialogs/include_note.js"; | ||||
| import NoteTypeChooserDialog from "../widgets/dialogs/note_type_chooser.js"; | ||||
|  | ||||
| export default class DesktopLayout { | ||||
|     constructor(customWidgets) { | ||||
| @@ -194,6 +195,7 @@ export default class DesktopLayout { | ||||
|             .child(new BranchPrefixDialog()) | ||||
|             .child(new SortChildNotesDialog()) | ||||
|             .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') { | ||||
|             const noteTypeChooserDialog = await import('../dialogs/note_type_chooser.js'); | ||||
|             const {success, noteType, templateNoteId} = await noteTypeChooserDialog.chooseNoteType(); | ||||
|             const {success, noteType, templateNoteId} = await noteCreateService.chooseNoteType(); | ||||
|  | ||||
|             if (!success) { | ||||
|                 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 = {}) { | ||||
|     const noteTypeChooserDialog = await import('../dialogs/note_type_chooser.js'); | ||||
|     const {success, noteType, templateNoteId} = await noteTypeChooserDialog.chooseNoteType(); | ||||
|     const {success, noteType, templateNoteId} = await chooseNoteType(); | ||||
|  | ||||
|     if (!success) { | ||||
|         return; | ||||
| @@ -121,5 +126,6 @@ async function duplicateSubtree(noteId, parentNotePath) { | ||||
| export default { | ||||
|     createNote, | ||||
|     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/move_to.ejs') %> | ||||
| <%- include('dialogs/delete_notes.ejs') %> | ||||
| <%- include('dialogs/note_type_chooser.ejs') %> | ||||
|  | ||||
| <script type="text/javascript"> | ||||
|     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> | ||||
		Reference in New Issue
	
	Block a user