mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
added new label "sorted" which will keep children notes alphabetically sorted, fixes #82
This commit is contained in:
parent
9452fc236b
commit
2d24bf81dd
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user