mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 11:39:01 +01:00 
			
		
		
		
	add move to dialog
This commit is contained in:
		
							parent
							
								
									5b4a2bd71c
								
							
						
					
					
						commit
						4cda661c1b
					
				| @ -83,31 +83,14 @@ CREATE TABLE IF NOT EXISTS "branches" ( | |||||||
| CREATE INDEX `IDX_branches_noteId` ON `branches` (`noteId`); | CREATE INDEX `IDX_branches_noteId` ON `branches` (`noteId`); | ||||||
| CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (`noteId`,`parentNoteId`); | CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (`noteId`,`parentNoteId`); | ||||||
| CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId); | CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId); | ||||||
| CREATE TABLE IF NOT EXISTS "note_revisions" (`noteRevisionId`	TEXT NOT NULL PRIMARY KEY, |  | ||||||
|                                                 `noteId`	TEXT NOT NULL, |  | ||||||
|                                                 `title`	TEXT, |  | ||||||
|                                                 `contentLength`	INT NOT NULL, |  | ||||||
|                                                 `isProtected`	INT NOT NULL DEFAULT 0, |  | ||||||
|                                                 `utcDateLastEdited` TEXT NOT NULL, |  | ||||||
|                                                 `utcDateCreated` TEXT NOT NULL, |  | ||||||
|                                                 `utcDateModified` TEXT NOT NULL, |  | ||||||
|                                                 `dateLastEdited` TEXT NOT NULL, |  | ||||||
|                                                 `dateCreated` TEXT NOT NULL, |  | ||||||
|                                                 type TEXT DEFAULT '' NOT NULL, |  | ||||||
|                                                 mime TEXT DEFAULT '' NOT NULL, |  | ||||||
|                                                 hash TEXT DEFAULT '' NOT NULL); |  | ||||||
| CREATE TABLE IF NOT EXISTS "note_revision_contents" (`noteRevisionId`	TEXT NOT NULL PRIMARY KEY, | CREATE TABLE IF NOT EXISTS "note_revision_contents" (`noteRevisionId`	TEXT NOT NULL PRIMARY KEY, | ||||||
|                                                  `content`	TEXT, |                                                  `content`	TEXT, | ||||||
|                                                  hash TEXT DEFAULT '' NOT NULL, |                                                  hash TEXT DEFAULT '' NOT NULL, | ||||||
|                                                  `utcDateModified` TEXT NOT NULL); |                                                  `utcDateModified` TEXT NOT NULL); | ||||||
| CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (`noteId`); |  | ||||||
| CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCreated`); |  | ||||||
| CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`); |  | ||||||
| CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`); |  | ||||||
| CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`); |  | ||||||
| CREATE TABLE IF NOT EXISTS "notes" ( | CREATE TABLE IF NOT EXISTS "notes" ( | ||||||
|                                            `noteId`	TEXT NOT NULL, |                                            `noteId`	TEXT NOT NULL, | ||||||
|                                            `title`	TEXT NOT NULL DEFAULT "note", |                                            `title`	TEXT NOT NULL DEFAULT "note", | ||||||
|  |                                            `contentLength`	INT NOT NULL, | ||||||
|                                            `isProtected`	INT NOT NULL DEFAULT 0, |                                            `isProtected`	INT NOT NULL DEFAULT 0, | ||||||
|                                            `type` TEXT NOT NULL DEFAULT 'text', |                                            `type` TEXT NOT NULL DEFAULT 'text', | ||||||
|                                            `mime` TEXT NOT NULL DEFAULT 'text/html', |                                            `mime` TEXT NOT NULL DEFAULT 'text/html', | ||||||
| @ -126,3 +109,22 @@ CREATE INDEX `IDX_notes_dateCreated` ON `notes` (`dateCreated`); | |||||||
| CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`); | CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`); | ||||||
| CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`); | CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`); | ||||||
| CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`); | CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`); | ||||||
|  | CREATE TABLE IF NOT EXISTS "note_revisions" (`noteRevisionId`	TEXT NOT NULL PRIMARY KEY, | ||||||
|  |                                                  `noteId`	TEXT NOT NULL, | ||||||
|  |                                                  `title`	TEXT, | ||||||
|  |                                                  `contentLength`	INT NOT NULL, | ||||||
|  |                                                  `isErased`	INT NOT NULL DEFAULT 0, | ||||||
|  |                                                  `isProtected`	INT NOT NULL DEFAULT 0, | ||||||
|  |                                                  `utcDateLastEdited` TEXT NOT NULL, | ||||||
|  |                                                  `utcDateCreated` TEXT NOT NULL, | ||||||
|  |                                                  `utcDateModified` TEXT NOT NULL, | ||||||
|  |                                                  `dateLastEdited` TEXT NOT NULL, | ||||||
|  |                                                  `dateCreated` TEXT NOT NULL, | ||||||
|  |                                                  type TEXT DEFAULT '' NOT NULL, | ||||||
|  |                                                  mime TEXT DEFAULT '' NOT NULL, | ||||||
|  |                                                  hash TEXT DEFAULT '' NOT NULL); | ||||||
|  | CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (`noteId`); | ||||||
|  | CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCreated`); | ||||||
|  | CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`); | ||||||
|  | CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`); | ||||||
|  | CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`); | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "version": "0.36.4", |   "version": "0.36.5", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  | |||||||
							
								
								
									
										62
									
								
								src/public/javascripts/dialogs/move_to.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/public/javascripts/dialogs/move_to.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | |||||||
|  | import noteAutocompleteService from "../services/note_autocomplete.js"; | ||||||
|  | import utils from "../services/utils.js"; | ||||||
|  | import cloningService from "../services/cloning.js"; | ||||||
|  | import treeUtils from "../services/tree_utils.js"; | ||||||
|  | import toastService from "../services/toast.js"; | ||||||
|  | import treeCache from "../services/tree_cache.js"; | ||||||
|  | import treeChangesService from "../services/branches.js"; | ||||||
|  | import treeService from "../services/tree.js"; | ||||||
|  | 
 | ||||||
|  | const $dialog = $("#move-to-dialog"); | ||||||
|  | const $form = $("#move-to-form"); | ||||||
|  | const $noteAutoComplete = $("#move-to-note-autocomplete"); | ||||||
|  | const $movePrefix = $("#move-prefix"); | ||||||
|  | const $noteList = $("#move-to-note-list"); | ||||||
|  | 
 | ||||||
|  | let movedNodes; | ||||||
|  | 
 | ||||||
|  | export async function showDialog(nodes) { | ||||||
|  |     movedNodes = nodes; | ||||||
|  | 
 | ||||||
|  |     utils.closeActiveDialog(); | ||||||
|  | 
 | ||||||
|  |     glob.activeDialog = $dialog; | ||||||
|  | 
 | ||||||
|  |     $dialog.modal(); | ||||||
|  | 
 | ||||||
|  |     $noteAutoComplete.val('').trigger('focus'); | ||||||
|  | 
 | ||||||
|  |     $noteList.empty(); | ||||||
|  | 
 | ||||||
|  |     for (const node of movedNodes) { | ||||||
|  |         const note = await treeCache.getNote(node.data.noteId); | ||||||
|  | 
 | ||||||
|  |         $noteList.append($("<li>").text(note.title)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     noteAutocompleteService.initNoteAutocomplete($noteAutoComplete); | ||||||
|  |     noteAutocompleteService.showRecentNotes($noteAutoComplete); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function moveNotesTo(notePath) { | ||||||
|  |     const targetNode = await treeService.getNodeFromPath(notePath); | ||||||
|  | 
 | ||||||
|  |     await treeChangesService.moveToNode(movedNodes, targetNode); | ||||||
|  | 
 | ||||||
|  |     toastService.showMessage(`Selected notes have been moved into ${targetNode.title}`); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | $form.on('submit', () => { | ||||||
|  |     const notePath = $noteAutoComplete.getSelectedPath(); | ||||||
|  | 
 | ||||||
|  |     if (notePath) { | ||||||
|  |         $dialog.modal('hide'); | ||||||
|  | 
 | ||||||
|  |         moveNotesTo(notePath); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         console.error("No path to move to."); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return false; | ||||||
|  | }); | ||||||
| @ -18,6 +18,7 @@ const NOTE_INFO = "../dialogs/note_info.js"; | |||||||
| const ABOUT = "../dialogs/about.js"; | const ABOUT = "../dialogs/about.js"; | ||||||
| const LINK_MAP = "../dialogs/link_map.js"; | const LINK_MAP = "../dialogs/link_map.js"; | ||||||
| const CLONE_TO = "../dialogs/clone_to.js"; | const CLONE_TO = "../dialogs/clone_to.js"; | ||||||
|  | const MOVE_TO = "../dialogs/move_to.js"; | ||||||
| 
 | 
 | ||||||
| function registerEntrypoints() { | function registerEntrypoints() { | ||||||
|     // hot keys are active also inside inputs and content editables
 |     // hot keys are active also inside inputs and content editables
 | ||||||
| @ -189,14 +190,22 @@ function registerEntrypoints() { | |||||||
| 
 | 
 | ||||||
|     utils.bindGlobalShortcut('ctrl+shift+c', () => import(CLONE_TO).then(d => { |     utils.bindGlobalShortcut('ctrl+shift+c', () => import(CLONE_TO).then(d => { | ||||||
|         const activeNode = treeService.getActiveNode(); |         const activeNode = treeService.getActiveNode(); | ||||||
|         console.log("activeNode", activeNode); | 
 | ||||||
|         const selectedOrActiveNodes = treeService.getSelectedOrActiveNodes(activeNode); |         const selectedOrActiveNodes = treeService.getSelectedOrActiveNodes(activeNode); | ||||||
|         console.log("selectedOrActiveNodes", selectedOrActiveNodes); |  | ||||||
| 
 | 
 | ||||||
|         const noteIds = selectedOrActiveNodes.map(node => node.data.noteId); |         const noteIds = selectedOrActiveNodes.map(node => node.data.noteId); | ||||||
| 
 | 
 | ||||||
|         d.showDialog(noteIds); |         d.showDialog(noteIds); | ||||||
|     })); |     })); | ||||||
|  | 
 | ||||||
|  |     utils.bindGlobalShortcut('ctrl+shift+x', () => import(MOVE_TO).then(d => { | ||||||
|  |         const activeNode = treeService.getActiveNode(); | ||||||
|  | 
 | ||||||
|  |         const selectedOrActiveNodes = treeService.getSelectedOrActiveNodes(activeNode); | ||||||
|  | 
 | ||||||
|  |         d.showDialog(selectedOrActiveNodes); | ||||||
|  |     })); | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|  | |||||||
| @ -17,11 +17,12 @@ class TreeContextMenu { | |||||||
| 
 | 
 | ||||||
|     getNoteTypeItems(baseCmd) { |     getNoteTypeItems(baseCmd) { | ||||||
|         return [ |         return [ | ||||||
|             { title: "Text", cmd: baseCmd + "_text", uiIcon: "file" }, |             { title: "Text", cmd: baseCmd + "_text", uiIcon: "note" }, | ||||||
|             { title: "Code", cmd: baseCmd + "_code", uiIcon: "terminal" }, |             { title: "Code", cmd: baseCmd + "_code", uiIcon: "code" }, | ||||||
|             { title: "Saved search", cmd: baseCmd + "_search", uiIcon: "search-folder" }, |             { title: "Saved search", cmd: baseCmd + "_search", uiIcon: "file-find" }, | ||||||
|             { title: "Relation Map", cmd: baseCmd + "_relation-map", uiIcon: "map" }, |             { title: "Relation Map", cmd: baseCmd + "_relation-map", uiIcon: "map-alt" }, | ||||||
|             { title: "Render HTML note", cmd: baseCmd + "_render", uiIcon: "play" } |             { title: "Render HTML note", cmd: baseCmd + "_render", uiIcon: "extension" }, | ||||||
|  |             { title: "Book", cmd: baseCmd + "_book", uiIcon: "book" } | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -63,11 +64,13 @@ class TreeContextMenu { | |||||||
|             { title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield", enabled: noSelectedNotes }, |             { title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield", enabled: noSelectedNotes }, | ||||||
|             { title: "----" }, |             { title: "----" }, | ||||||
|             { title: "Copy / clone <kbd>Ctrl+C</kbd>", cmd: "copy", uiIcon: "copy", |             { title: "Copy / clone <kbd>Ctrl+C</kbd>", cmd: "copy", uiIcon: "copy", | ||||||
|                 enabled: isNotRoot }, |                 enabled: isNotRoot && !isHoisted }, | ||||||
|             { title: "Clone to ... <kbd>Ctrl+Shift+C</kbd>", cmd: "cloneTo", uiIcon: "empty", |             { title: "Clone to ... <kbd>Ctrl+Shift+C</kbd>", cmd: "cloneTo", uiIcon: "empty", | ||||||
|                 enabled: isNotRoot }, |                 enabled: isNotRoot && !isHoisted }, | ||||||
|             { title: "Cut <kbd>Ctrl+X</kbd>", cmd: "cut", uiIcon: "cut", |             { title: "Cut <kbd>Ctrl+X</kbd>", cmd: "cut", uiIcon: "cut", | ||||||
|                 enabled: isNotRoot && !isHoisted && parentNotSearch }, |                 enabled: isNotRoot && !isHoisted && parentNotSearch }, | ||||||
|  |             { title: "Move to ... <kbd>Ctrl+Shift+X</kbd>", cmd: "moveTo", uiIcon: "empty", | ||||||
|  |                 enabled: isNotRoot && !isHoisted && parentNotSearch }, | ||||||
|             { title: "Paste into <kbd>Ctrl+V</kbd>", cmd: "pasteInto", uiIcon: "paste", |             { title: "Paste into <kbd>Ctrl+V</kbd>", cmd: "pasteInto", uiIcon: "paste", | ||||||
|                 enabled: !clipboard.isEmpty() && notSearch && noSelectedNotes }, |                 enabled: !clipboard.isEmpty() && notSearch && noSelectedNotes }, | ||||||
|             { title: "Paste after", cmd: "pasteAfter", uiIcon: "paste", |             { title: "Paste after", cmd: "pasteAfter", uiIcon: "paste", | ||||||
| @ -127,11 +130,16 @@ class TreeContextMenu { | |||||||
|             const nodes = treeService.getSelectedOrActiveNodes(this.node); |             const nodes = treeService.getSelectedOrActiveNodes(this.node); | ||||||
|             const noteIds = nodes.map(node => node.data.noteId); |             const noteIds = nodes.map(node => node.data.noteId); | ||||||
| 
 | 
 | ||||||
|             import("../dialogs/clone_to.js").then(d => d.showDialog(noteIds)) |             import("../dialogs/clone_to.js").then(d => d.showDialog(noteIds)); | ||||||
|         } |         } | ||||||
|         else if (cmd === "cut") { |         else if (cmd === "cut") { | ||||||
|             clipboard.cut(treeService.getSelectedOrActiveNodes(this.node)); |             clipboard.cut(treeService.getSelectedOrActiveNodes(this.node)); | ||||||
|         } |         } | ||||||
|  |         else if (cmd === "moveTo") { | ||||||
|  |             const nodes = treeService.getSelectedOrActiveNodes(this.node); | ||||||
|  | 
 | ||||||
|  |             import("../dialogs/move_to.js").then(d => d.showDialog(nodes)); | ||||||
|  |         } | ||||||
|         else if (cmd === "pasteAfter") { |         else if (cmd === "pasteAfter") { | ||||||
|             clipboard.pasteAfter(this.node); |             clipboard.pasteAfter(this.node); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -166,7 +166,7 @@ async function findBrokenReferenceIssues() { | |||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     await findAndFixIssues(` |     await findIssues(` | ||||||
|           SELECT noteRevisionId, note_revisions.noteId |           SELECT noteRevisionId, note_revisions.noteId | ||||||
|           FROM note_revisions LEFT JOIN notes USING(noteId) |           FROM note_revisions LEFT JOIN notes USING(noteId) | ||||||
|           WHERE notes.noteId IS NULL`,
 |           WHERE notes.noteId IS NULL`,
 | ||||||
|  | |||||||
| @ -176,6 +176,7 @@ | |||||||
|     <% include dialogs/note_info.ejs %> |     <% include dialogs/note_info.ejs %> | ||||||
|     <% include dialogs/link_map.ejs %> |     <% include dialogs/link_map.ejs %> | ||||||
|     <% include dialogs/clone_to.ejs %> |     <% include dialogs/clone_to.ejs %> | ||||||
|  |     <% include dialogs/move_to.ejs %> | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| <script type="text/javascript"> | <script type="text/javascript"> | ||||||
|  | |||||||
							
								
								
									
										31
									
								
								src/views/dialogs/move_to.ejs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/views/dialogs/move_to.ejs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | <div id="move-to-dialog" class="modal mx-auto" tabindex="-1" role="dialog"> | ||||||
|  |     <div class="modal-dialog modal-lg" style="max-width: 1000px" role="document"> | ||||||
|  |         <div class="modal-content"> | ||||||
|  |             <div class="modal-header"> | ||||||
|  |                 <h5 class="modal-title mr-auto">Move notes to ...</h5> | ||||||
|  |                  | ||||||
|  |                 <button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0 !important;"> | ||||||
|  |                     <span aria-hidden="true">×</span> | ||||||
|  |                 </button> | ||||||
|  |             </div> | ||||||
|  |             <form id="move-to-form"> | ||||||
|  |                 <div class="modal-body"> | ||||||
|  |                     <h5>Notes to move</h5> | ||||||
|  | 
 | ||||||
|  |                     <ul id="move-to-note-list" style="max-height: 200px; overflow: auto;"></ul> | ||||||
|  | 
 | ||||||
|  |                     <div class="form-group"> | ||||||
|  |                         <label for="move-to-note-autocomplete">Target parent note</label> | ||||||
|  | 
 | ||||||
|  |                         <div class="input-group"> | ||||||
|  |                             <input id="move-to-note-autocomplete" class="form-control" placeholder="search for note by its name"> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="modal-footer"> | ||||||
|  |                     <button type="submit" class="btn btn-primary">Move to selected note <kbd>enter</kbd></button> | ||||||
|  |                 </div> | ||||||
|  |             </form> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam