mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 13:01:31 +08:00 
			
		
		
		
	configuration of displayed link types + max number of links
This commit is contained in:
		
							parent
							
								
									ccbb2e2e12
								
							
						
					
					
						commit
						8ab081a3fd
					
				| @ -506,7 +506,7 @@ | |||||||
| 		Springy.requestAnimationFrame(function step() { | 		Springy.requestAnimationFrame(function step() { | ||||||
| 			t.tick(0.03); | 			t.tick(0.03); | ||||||
| 
 | 
 | ||||||
| 			if (render !== undefined) { | 			if (!t._stop && render !== undefined) { | ||||||
| 				render(); | 				render(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,14 +16,22 @@ const linkOverlays = [ | |||||||
|     } ] |     } ] | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
|  | const LINK_TYPES = [ "hyper", "image", "relation", "relation-map" ]; | ||||||
|  | 
 | ||||||
| const $dialog = $("#link-map-dialog"); | const $dialog = $("#link-map-dialog"); | ||||||
|  | const $maxNotesInput = $("#link-map-max-notes"); | ||||||
| 
 | 
 | ||||||
| let jsPlumbInstance = null; | let jsPlumbInstance = null; | ||||||
| let pzInstance = null; | let pzInstance = null; | ||||||
|  | let renderer = null; | ||||||
| 
 | 
 | ||||||
| async function showDialog() { | async function showDialog() { | ||||||
|     glob.activeDialog = $dialog; |     glob.activeDialog = $dialog; | ||||||
| 
 | 
 | ||||||
|  |     // set default settings
 | ||||||
|  |     $maxNotesInput.val(50); | ||||||
|  |     LINK_TYPES.forEach(lt => $("#link-map-" + lt).attr("checked", "checked")); | ||||||
|  | 
 | ||||||
|     await libraryLoader.requireLibrary(libraryLoader.LINK_MAP); |     await libraryLoader.requireLibrary(libraryLoader.LINK_MAP); | ||||||
| 
 | 
 | ||||||
|     jsPlumb.ready(() => { |     jsPlumb.ready(() => { | ||||||
| @ -38,12 +46,26 @@ async function showDialog() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function loadNotesAndRelations() { | async function loadNotesAndRelations() { | ||||||
|  |     cleanup(); | ||||||
|  | 
 | ||||||
|  |     const linkTypes = LINK_TYPES.filter(lt => $(`#link-map-${lt}:checked`).length > 0); | ||||||
|  |     const maxNotes = parseInt($maxNotesInput.val()); | ||||||
|  | 
 | ||||||
|  |     console.log(linkTypes); | ||||||
|  | 
 | ||||||
|     const activeNoteId = noteDetailService.getActiveNoteId(); |     const activeNoteId = noteDetailService.getActiveNoteId(); | ||||||
| 
 | 
 | ||||||
|     const links = await server.get(`notes/${activeNoteId}/link-map`); |     const links = await server.post(`notes/${activeNoteId}/link-map`, { | ||||||
|  |         linkTypes, | ||||||
|  |         maxNotes | ||||||
|  |     }); | ||||||
| 
 | 
 | ||||||
|     const noteIds = new Set(links.map(l => l.noteId).concat(links.map(l => l.targetNoteId))); |     const noteIds = new Set(links.map(l => l.noteId).concat(links.map(l => l.targetNoteId))); | ||||||
| 
 | 
 | ||||||
|  |     if (noteIds.size === 0) { | ||||||
|  |         noteIds.add(activeNoteId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // preload all notes
 |     // preload all notes
 | ||||||
|     const notes = await treeCache.getNotes(Array.from(noteIds)); |     const notes = await treeCache.getNotes(Array.from(noteIds)); | ||||||
| 
 | 
 | ||||||
| @ -94,7 +116,7 @@ async function loadNotesAndRelations() { | |||||||
|         return $noteBox; |         return $noteBox; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const renderer = new Springy.Renderer( |     renderer = new Springy.Renderer( | ||||||
|         layout, |         layout, | ||||||
|         () => {}, |         () => {}, | ||||||
|         (edge, p1, p2) => { |         (edge, p1, p2) => { | ||||||
| @ -150,6 +172,10 @@ function initPanZoom() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function cleanup() { | function cleanup() { | ||||||
|  |     if (renderer) { | ||||||
|  |         renderer.stop(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // delete all endpoints and connections
 |     // delete all endpoints and connections
 | ||||||
|     // this is done at this point (after async operations) to reduce flicker to the minimum
 |     // this is done at this point (after async operations) to reduce flicker to the minimum
 | ||||||
|     jsPlumbInstance.deleteEveryEndpoint(); |     jsPlumbInstance.deleteEveryEndpoint(); | ||||||
| @ -183,6 +209,10 @@ function noteIdToId(noteId) { | |||||||
|     return "link-map-note-" + noteId; |     return "link-map-note-" + noteId; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | $(".link-map-settings").change(loadNotesAndRelations); | ||||||
|  | 
 | ||||||
|  | $maxNotesInput.on("input", loadNotesAndRelations); | ||||||
|  | 
 | ||||||
| export default { | export default { | ||||||
|     showDialog |     showDialog | ||||||
| }; | }; | ||||||
| @ -336,9 +336,3 @@ li.dropdown-submenu:hover > ul.dropdown-menu { | |||||||
| .note-tab-row:not(.note-tab-row-is-sorting) .note-tab.note-tab-was-just-dragged { | .note-tab-row:not(.note-tab-row-is-sorting) .note-tab.note-tab-was-just-dragged { | ||||||
|     transition: transform 120ms ease-in-out; |     transition: transform 120ms ease-in-out; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #link-map-container { |  | ||||||
|     position: relative; |  | ||||||
|     height: 700px; |  | ||||||
|     outline: none; /* remove dotted outline on click */ |  | ||||||
| } |  | ||||||
| @ -1,5 +1,7 @@ | |||||||
| .link-map-active-note { | #link-map-container { | ||||||
|     background-color: var(--more-accented-background-color) !important; |     position: relative; | ||||||
|  |     height: calc(95vh - 130px); | ||||||
|  |     outline: none; /* remove dotted outline on click */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #link-map-container .note-box { | #link-map-container .note-box { | ||||||
| @ -34,3 +36,7 @@ | |||||||
|     position: absolute !important; |     position: absolute !important; | ||||||
|     z-index: 100; |     z-index: 100; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .link-map-active-note { | ||||||
|  |     background-color: var(--more-accented-background-color) !important; | ||||||
|  | } | ||||||
| @ -2,8 +2,8 @@ | |||||||
| 
 | 
 | ||||||
| const sql = require('../../services/sql'); | const sql = require('../../services/sql'); | ||||||
| 
 | 
 | ||||||
| async function getLinks(noteIds) { | async function getLinks(noteIds, linkTypes) { | ||||||
|     return await sql.getManyRows(` |     return (await sql.getManyRows(` | ||||||
|         SELECT noteId, targetNoteId, type |         SELECT noteId, targetNoteId, type | ||||||
|         FROM links |         FROM links | ||||||
|         WHERE (noteId IN (???) OR targetNoteId IN (???)) |         WHERE (noteId IN (???) OR targetNoteId IN (???)) | ||||||
| @ -14,17 +14,18 @@ async function getLinks(noteIds) { | |||||||
|         WHERE (noteId IN (???) OR value IN (???)) |         WHERE (noteId IN (???) OR value IN (???)) | ||||||
|           AND type = 'relation' |           AND type = 'relation' | ||||||
|           AND isDeleted = 0 |           AND isDeleted = 0 | ||||||
|     `, Array.from(noteIds));
 |     `, Array.from(noteIds))).filter(l => linkTypes.includes(l.type));
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function getLinkMap(req) { | async function getLinkMap(req) { | ||||||
|     const {noteId} = req.params; |     const {noteId} = req.params; | ||||||
|  |     const {linkTypes, maxNotes} = req.body; | ||||||
| 
 | 
 | ||||||
|     let noteIds = new Set([noteId]); |     let noteIds = new Set([noteId]); | ||||||
|     let links = []; |     let links = []; | ||||||
| 
 | 
 | ||||||
|     while (true) { |     while (true) { | ||||||
|         const newLinks = await getLinks(noteIds); |         const newLinks = await getLinks(noteIds, linkTypes); | ||||||
|         const newNoteIds = new Set(newLinks.map(l => l.noteId).concat(newLinks.map(l => l.targetNoteId))); |         const newNoteIds = new Set(newLinks.map(l => l.noteId).concat(newLinks.map(l => l.targetNoteId))); | ||||||
| 
 | 
 | ||||||
|         if (newNoteIds.size === noteIds.size) { |         if (newNoteIds.size === noteIds.size) { | ||||||
| @ -32,7 +33,7 @@ async function getLinkMap(req) { | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (newNoteIds.length > 50) { |         if (newNoteIds.size > maxNotes) { | ||||||
|             // to many notes to display
 |             // to many notes to display
 | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -155,7 +155,7 @@ function register(app) { | |||||||
|     apiRoute(GET, '/api/attributes/names', attributesRoute.getAttributeNames); |     apiRoute(GET, '/api/attributes/names', attributesRoute.getAttributeNames); | ||||||
|     apiRoute(GET, '/api/attributes/values/:attributeName', attributesRoute.getValuesForAttribute); |     apiRoute(GET, '/api/attributes/values/:attributeName', attributesRoute.getValuesForAttribute); | ||||||
| 
 | 
 | ||||||
|     apiRoute(GET, '/api/notes/:noteId/link-map', linkMapRoute.getLinkMap); |     apiRoute(POST, '/api/notes/:noteId/link-map', linkMapRoute.getLinkMap); | ||||||
| 
 | 
 | ||||||
|     apiRoute(GET, '/api/date-notes/date/:date', dateNotesRoute.getDateNote); |     apiRoute(GET, '/api/date-notes/date/:date', dateNotesRoute.getDateNote); | ||||||
|     apiRoute(GET, '/api/date-notes/month/:month', dateNotesRoute.getMonthNote); |     apiRoute(GET, '/api/date-notes/month/:month', dateNotesRoute.getMonthNote); | ||||||
|  | |||||||
| @ -1,8 +1,40 @@ | |||||||
| <div id="link-map-dialog" class="modal fade mx-auto" tabindex="-1" role="dialog"> | <div id="link-map-dialog" class="modal fade mx-auto" tabindex="-1" role="dialog"> | ||||||
|     <div class="modal-dialog modal-xl" role="document"> |     <div class="modal-dialog modal-xl" style="max-width: 90%;" role="document"> | ||||||
|         <div class="modal-content"> |         <div class="modal-content"> | ||||||
|             <div class="modal-header"> |             <div class="modal-header"> | ||||||
|                 <h5 class="modal-title mr-auto">Link map</h5> |                 <h5 class="modal-title" style="width: auto;">Link map</h5> | ||||||
|  | 
 | ||||||
|  |                 <div style="vertical-align: middle;"> | ||||||
|  |                     <div class="form-check form-check-inline"> | ||||||
|  |                         <input class="form-check-input link-map-settings" type="checkbox" id="link-map-hyper"> | ||||||
|  |                         <label class="form-check-label" for="link-map-hyper">text links</label> | ||||||
|  |                     </div> | ||||||
|  | 
 | ||||||
|  |                     <div class="form-check form-check-inline"> | ||||||
|  |                         <input class="form-check-input link-map-settings" type="checkbox" id="link-map-image"> | ||||||
|  |                         <label class="form-check-label" for="link-map-image">image links</label> | ||||||
|  |                     </div> | ||||||
|  | 
 | ||||||
|  |                     <div class="form-check form-check-inline"> | ||||||
|  |                         <input class="form-check-input link-map-settings" type="checkbox" id="link-map-relation"> | ||||||
|  |                         <label class="form-check-label" for="link-map-relation">relations</label> | ||||||
|  |                     </div> | ||||||
|  | 
 | ||||||
|  |                     <div class="form-check form-check-inline"> | ||||||
|  |                         <input class="form-check-input link-map-settings" type="checkbox" id="link-map-relation-map"> | ||||||
|  |                         <label class="form-check-label" for="link-map-relation-map">relation map links</label> | ||||||
|  |                     </div> | ||||||
|  | 
 | ||||||
|  |                     <div style="display: inline-block; position: relative; top: -3px;"> | ||||||
|  |                         <label for="link-map-max-notes" title="Max number of displayed notes"> | ||||||
|  |                             <strong>max notes:</strong> | ||||||
|  |                         </label> | ||||||
|  | 
 | ||||||
|  |                         <input id="link-map-max-notes" type="number" value="50" min="5" max="1000" step="10" | ||||||
|  |                                class="form-control form-control-sm" | ||||||
|  |                                style="width: 80px; display: inline-block; text-align: right;"/> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
| 
 | 
 | ||||||
|                 <button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0;"> |                 <button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0;"> | ||||||
|                     <span aria-hidden="true">×</span> |                     <span aria-hidden="true">×</span> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam