mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	added new label "sorted" which will keep children notes alphabetically sorted, fixes #82
This commit is contained in:
		| @@ -11,6 +11,7 @@ const os = require('os'); | ||||
| const sessionSecret = require('./services/session_secret'); | ||||
| const cls = require('./services/cls'); | ||||
| require('./entities/entity_constructor'); | ||||
| require('./services/handlers'); | ||||
|  | ||||
| const app = express(); | ||||
|  | ||||
|   | ||||
| @@ -30,6 +30,10 @@ class Note extends Entity { | ||||
|         catch(e) {} | ||||
|     } | ||||
|  | ||||
|     isRoot() { | ||||
|         return this.noteId === 'root'; | ||||
|     } | ||||
|  | ||||
|     isJson() { | ||||
|         return this.mime === "application/json"; | ||||
|     } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import infoService from "./info.js"; | ||||
|  | ||||
| const $outstandingSyncsCount = $("#outstanding-syncs-count"); | ||||
|  | ||||
| const syncMessageHandlers = []; | ||||
| const messageHandlers = []; | ||||
|  | ||||
| let ws; | ||||
| @@ -25,9 +26,17 @@ function subscribeToMessages(messageHandler) { | ||||
|     messageHandlers.push(messageHandler); | ||||
| } | ||||
|  | ||||
| function subscribeToSyncMessages(messageHandler) { | ||||
|     syncMessageHandlers.push(messageHandler); | ||||
| } | ||||
|  | ||||
| function handleMessage(event) { | ||||
|     const message = JSON.parse(event.data); | ||||
|  | ||||
|     for (const messageHandler of messageHandlers) { | ||||
|         messageHandler(message); | ||||
|     } | ||||
|  | ||||
|     if (message.type === 'sync') { | ||||
|         lastPingTs = new Date().getTime(); | ||||
|  | ||||
| @@ -39,8 +48,8 @@ function handleMessage(event) { | ||||
|  | ||||
|         const syncData = message.data.filter(sync => sync.sourceId !== glob.sourceId); | ||||
|  | ||||
|         for (const messageHandler of messageHandlers) { | ||||
|             messageHandler(syncData); | ||||
|         for (const syncMessageHandler of syncMessageHandlers) { | ||||
|             syncMessageHandler(syncData); | ||||
|         } | ||||
|  | ||||
|         $outstandingSyncsCount.html(message.outstandingSyncs); | ||||
| @@ -104,5 +113,6 @@ setTimeout(() => { | ||||
|  | ||||
| export default { | ||||
|     logError, | ||||
|     subscribeToMessages | ||||
|     subscribeToMessages, | ||||
|     subscribeToSyncMessages | ||||
| }; | ||||
| @@ -276,7 +276,7 @@ function focus() { | ||||
|     getComponent(note.type).focus(); | ||||
| } | ||||
|  | ||||
| messagingService.subscribeToMessages(syncData => { | ||||
| messagingService.subscribeToSyncMessages(syncData => { | ||||
|     if (syncData.some(sync => sync.entityName === 'notes' && sync.entityId === getCurrentNoteId())) { | ||||
|         infoService.showMessage('Reloading note because of background changes'); | ||||
|  | ||||
|   | ||||
| @@ -505,7 +505,13 @@ async function showTree() { | ||||
|     initFancyTree(tree); | ||||
| } | ||||
|  | ||||
| messagingService.subscribeToMessages(syncData => { | ||||
| messagingService.subscribeToMessages(message => { | ||||
|    if (message.type === 'refresh-tree') { | ||||
|        reload(); | ||||
|    } | ||||
| }); | ||||
|  | ||||
| messagingService.subscribeToSyncMessages(syncData => { | ||||
|     if (syncData.some(sync => sync.entityName === 'branches') | ||||
|         || syncData.some(sync => sync.entityName === 'notes')) { | ||||
|  | ||||
|   | ||||
| @@ -42,6 +42,7 @@ async function getRootCalendarNote() { | ||||
|         })).note; | ||||
|  | ||||
|         await labelService.createLabel(rootNote.noteId, CALENDAR_ROOT_LABEL); | ||||
|         await labelService.createLabel(rootNote.noteId, 'sorted'); | ||||
|     } | ||||
|  | ||||
|     return rootNote; | ||||
| @@ -60,6 +61,7 @@ async function getYearNote(dateTimeStr, rootNote) { | ||||
|         } | ||||
|  | ||||
|         await labelService.createLabel(yearNote.noteId, YEAR_LABEL, yearStr); | ||||
|         await labelService.createLabel(yearNote.noteId, 'sorted'); | ||||
|     } | ||||
|  | ||||
|     return yearNote; | ||||
| @@ -85,6 +87,7 @@ async function getMonthNote(dateTimeStr, rootNote) { | ||||
|         } | ||||
|  | ||||
|         await labelService.createLabel(monthNote.noteId, MONTH_LABEL, monthStr); | ||||
|         await labelService.createLabel(monthNote.noteId, 'sorted'); | ||||
|     } | ||||
|  | ||||
|     return monthNote; | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| const NOTE_TITLE_CHANGED = "NOTE_TITLE_CHANGED"; | ||||
| const ENTER_PROTECTED_SESSION = "ENTER_PROTECTED_SESSION"; | ||||
| const ENTITY_CHANGED = "ENTITY_CHANGED"; | ||||
|  | ||||
| @@ -19,10 +20,22 @@ function emit(eventType, data) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function syncEmit(eventType, data) { | ||||
|     const listeners = eventListeners[eventType]; | ||||
|  | ||||
|     if (listeners) { | ||||
|         for (const listener of listeners) { | ||||
|             await listener(data); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     subscribe, | ||||
|     emit, | ||||
|     syncEmit, | ||||
|     // event types: | ||||
|     NOTE_TITLE_CHANGED, | ||||
|     ENTER_PROTECTED_SESSION, | ||||
|     ENTITY_CHANGED | ||||
| }; | ||||
							
								
								
									
										27
									
								
								src/services/handlers.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/services/handlers.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| const eventService = require('./events'); | ||||
| const scriptService = require('./script'); | ||||
| const relationService = require('./relations'); | ||||
| const treeService = require('./tree'); | ||||
| const messagingService = require('./messaging'); | ||||
|  | ||||
| eventService.subscribe(eventService.NOTE_TITLE_CHANGED, async note => { | ||||
|     const relations = await relationService.getEffectiveRelations(note.noteId, 'runOnNoteTitleChange'); | ||||
|  | ||||
|     for (const relation of relations) { | ||||
|         const scriptNote = await relation.getTargetNote(); | ||||
|  | ||||
|         await scriptService.executeNote(scriptNote, scriptNote, note); | ||||
|     } | ||||
|  | ||||
|     if (!note.isRoot()) { | ||||
|         const parents = await note.getParentNotes(); | ||||
|  | ||||
|         for (const parent of parents) { | ||||
|             if (await parent.hasLabel("sorted")) { | ||||
|                 await treeService.sortNotesAlphabetically(parent.noteId); | ||||
|  | ||||
|                 messagingService.sendMessageToAllClients({ type: 'refresh-tree' }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -3,6 +3,7 @@ const optionService = require('./options'); | ||||
| const dateUtils = require('./date_utils'); | ||||
| const syncTableService = require('./sync_table'); | ||||
| const labelService = require('./labels'); | ||||
| const eventService = require('./events'); | ||||
| const repository = require('./repository'); | ||||
| const Note = require('../entities/note'); | ||||
| const NoteImage = require('../entities/note_image'); | ||||
| @@ -34,6 +35,10 @@ async function getNewNotePosition(parentNoteId, noteData) { | ||||
|     return newNotePos; | ||||
| } | ||||
|  | ||||
| async function triggerNoteTitleChanged(note) { | ||||
|     await eventService.emit(eventService.NOTE_TITLE_CHANGED, note); | ||||
| } | ||||
|  | ||||
| async function createNewNote(parentNoteId, noteData) { | ||||
|     const newNotePos = await getNewNotePosition(parentNoteId, noteData); | ||||
|  | ||||
| @@ -60,6 +65,8 @@ async function createNewNote(parentNoteId, noteData) { | ||||
|         isExpanded: 0 | ||||
|     }).save(); | ||||
|  | ||||
|     await triggerNoteTitleChanged(note); | ||||
|  | ||||
|     return { | ||||
|         note, | ||||
|         branch | ||||
| @@ -92,6 +99,8 @@ async function createNote(parentNoteId, title, content = "", extraOptions = {}) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     await triggerNoteTitleChanged(note); | ||||
|  | ||||
|     return {note, branch}; | ||||
| } | ||||
|  | ||||
| @@ -200,11 +209,17 @@ async function updateNote(noteId, noteUpdates) { | ||||
|  | ||||
|     await saveNoteRevision(note); | ||||
|  | ||||
|     const noteTitleChanged = note.title !== noteUpdates.title; | ||||
|  | ||||
|     note.title = noteUpdates.title; | ||||
|     note.setContent(noteUpdates.content); | ||||
|     note.isProtected = noteUpdates.isProtected; | ||||
|     await note.save(); | ||||
|  | ||||
|     if (noteTitleChanged) { | ||||
|         await triggerNoteTitleChanged(note); | ||||
|     } | ||||
|  | ||||
|     await saveNoteImages(note); | ||||
|  | ||||
|     await protectNoteRevisions(note); | ||||
|   | ||||
| @@ -4,7 +4,8 @@ const repository = require('./repository'); | ||||
| const Relation = require('../entities/relation'); | ||||
|  | ||||
| const BUILTIN_RELATIONS = [ | ||||
|     'runOnNoteView' | ||||
|     'runOnNoteView', | ||||
|     'runOnNoteTitleChange' | ||||
| ]; | ||||
|  | ||||
| async function getNotesWithRelation(name, targetNoteId) { | ||||
| @@ -36,8 +37,8 @@ async function createRelation(sourceNoteId, name, targetNoteId) { | ||||
|     }).save(); | ||||
| } | ||||
|  | ||||
| async function getEffectiveRelations(noteId) { | ||||
|     return await repository.getEntities(` | ||||
| async function getEffectiveRelations(noteId, relationName) { | ||||
|     const relations = await repository.getEntities(` | ||||
|         WITH RECURSIVE tree(noteId) AS ( | ||||
|         SELECT ? | ||||
|             UNION | ||||
| @@ -48,6 +49,13 @@ async function getEffectiveRelations(noteId) { | ||||
|         ) | ||||
|         SELECT relations.* FROM relations JOIN tree ON relations.sourceNoteId = tree.noteId  | ||||
|         WHERE relations.isDeleted = 0 AND (relations.isInheritable = 1 OR relations.sourceNoteId = ?)`, [noteId, noteId]); | ||||
|  | ||||
|     if (relationName) { | ||||
|         return relations.filter(relation => relation.name === relationName); | ||||
|     } | ||||
|     else { | ||||
|         return relations; | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|   | ||||
| @@ -4,14 +4,14 @@ const repository = require('./repository'); | ||||
| const cls = require('./cls'); | ||||
| const sourceIdService = require('./source_id'); | ||||
|  | ||||
| async function executeNote(note) { | ||||
| async function executeNote(note, targetNote) { | ||||
|     if (!note.isJavaScript()) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const bundle = await getScriptBundle(note); | ||||
|  | ||||
|     await executeBundle(bundle); | ||||
|     await executeBundle(bundle, note, targetNote); | ||||
| } | ||||
|  | ||||
| async function executeBundle(bundle, startNote, targetNote = null) { | ||||
|   | ||||
| @@ -5,6 +5,7 @@ const utils = require('./utils'); | ||||
| const dateUtils = require('./date_utils'); | ||||
| const labelService = require('./labels'); | ||||
| const dateNoteService = require('./date_notes'); | ||||
| const treeService = require('./tree'); | ||||
| const config = require('./config'); | ||||
| const repository = require('./repository'); | ||||
| const axios = require('axios'); | ||||
| @@ -61,6 +62,8 @@ function ScriptApi(startNote, currentNote, targetNote) { | ||||
|     this.getRootCalendarNote = dateNoteService.getRootCalendarNote; | ||||
|     this.getDateNote = dateNoteService.getDateNote; | ||||
|  | ||||
|     this.sortNotesAlphabetically = treeService.sortNotesAlphabetically; | ||||
|  | ||||
|     this.transactional = sql.transactional; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user