mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
add "top" label to keep notes on top, allow sorting by label, #2343
This commit is contained in:
parent
df4cf80be4
commit
211ff90ee8
@ -189,6 +189,7 @@ const ATTR_HELP = {
|
||||
"runAtHour": "On which hour should this run. Should be used together with <code>#run=hourly</code>. Can be defined multiple times for more runs during the day.",
|
||||
"disableInclusion": "scripts with this label won't be included into parent script execution.",
|
||||
"sorted": "keeps child notes sorted by title alphabetically",
|
||||
"top": "keep given note on top in its parent (applies only on sorted parents)",
|
||||
"hidePromotedAttributes": "Hide promoted attributes on this note",
|
||||
"readOnly": "editor is in read only mode. Works only for text and code notes.",
|
||||
"autoReadOnlyDisabled": "text/code notes can be set automatically into read mode when they are too large. You can disable this behavior on per-note basis by adding this label to the note",
|
||||
@ -208,6 +209,8 @@ const ATTR_HELP = {
|
||||
"inbox": "default inbox location for new notes",
|
||||
"hoistedInbox": "default inbox location for new notes when hoisted to some ancestor of this note",
|
||||
"sqlConsoleHome": "default location of SQL console notes",
|
||||
"bookmarked": "note with this label will appear in bookmarks",
|
||||
"bookmarkFolder": "note with this label will appear in bookmarks as folder (allowing access to its children)"
|
||||
},
|
||||
"relation": {
|
||||
"runOnNoteCreation": "executes when note is created on backend",
|
||||
|
@ -49,6 +49,8 @@ const BUILTIN_ATTRIBUTES = [
|
||||
{ type: 'label', name: 'mapRootNoteId' },
|
||||
{ type: 'label', name: 'bookmarked' },
|
||||
{ type: 'label', name: 'bookmarkFolder' },
|
||||
{ type: 'label', name: 'sorted' },
|
||||
{ type: 'label', name: 'top' },
|
||||
|
||||
// relation names
|
||||
{ type: 'relation', name: 'runOnNoteCreation', isDangerous: true },
|
||||
|
@ -39,6 +39,10 @@ eventService.subscribe(eventService.NOTE_TITLE_CHANGED, note => {
|
||||
eventService.subscribe([ eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED ], ({ entityName, entity }) => {
|
||||
if (entityName === 'attributes') {
|
||||
runAttachedRelations(entity.getNote(), 'runOnAttributeChange', entity);
|
||||
|
||||
if (entity.type === 'label' && entity.name === 'sorted') {
|
||||
handleSortedAttribute(entity);
|
||||
}
|
||||
}
|
||||
else if (entityName === 'notes') {
|
||||
runAttachedRelations(entity, 'runOnNoteChange', entity);
|
||||
@ -83,17 +87,7 @@ eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) =>
|
||||
}
|
||||
}
|
||||
else if (entity.type === 'label' && entity.name === 'sorted') {
|
||||
treeService.sortNotesIfNeeded(entity.noteId);
|
||||
|
||||
if (entity.isInheritable) {
|
||||
const note = becca.notes[entity.noteId];
|
||||
|
||||
if (note) {
|
||||
for (const noteId of note.getSubtreeNoteIds()) {
|
||||
treeService.sortNotesIfNeeded(noteId);
|
||||
}
|
||||
}
|
||||
}
|
||||
handleSortedAttribute(entity);
|
||||
}
|
||||
}
|
||||
else if (entityName === 'notes') {
|
||||
@ -122,6 +116,20 @@ function processInverseRelations(entityName, entity, handler) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleSortedAttribute(entity) {
|
||||
treeService.sortNotesIfNeeded(entity.noteId);
|
||||
|
||||
if (entity.isInheritable) {
|
||||
const note = becca.notes[entity.noteId];
|
||||
|
||||
if (note) {
|
||||
for (const noteId of note.getSubtreeNoteIds()) {
|
||||
treeService.sortNotesIfNeeded(noteId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eventService.subscribe(eventService.ENTITY_CHANGED, ({ entityName, entity }) => {
|
||||
processInverseRelations(entityName, entity, (definition, note, targetNote) => {
|
||||
// we need to make sure that also target's inverse attribute exists and if not, then create it
|
||||
|
@ -108,9 +108,9 @@ function loadSubtreeNoteIds(parentNoteId, subtreeNoteIds) {
|
||||
}
|
||||
}
|
||||
|
||||
function sortNotes(parentNoteId, sortBy = 'title', reverse = false, foldersFirst = false) {
|
||||
if (!sortBy) {
|
||||
sortBy = 'title';
|
||||
function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, foldersFirst = false) {
|
||||
if (!customSortBy) {
|
||||
customSortBy = 'title';
|
||||
}
|
||||
|
||||
sql.transactional(() => {
|
||||
@ -129,10 +129,41 @@ function sortNotes(parentNoteId, sortBy = 'title', reverse = false, foldersFirst
|
||||
}
|
||||
}
|
||||
|
||||
let aEl = normalize(a[sortBy]);
|
||||
let bEl = normalize(b[sortBy]);
|
||||
function fetchValue(note, key) {
|
||||
const rawValue = ['title', 'dateCreated', 'dateModified'].includes(key)
|
||||
? note[key]
|
||||
: note.getLabelValue(key);
|
||||
|
||||
return aEl < bEl ? -1 : 1;
|
||||
return normalize(rawValue);
|
||||
}
|
||||
|
||||
function compare(a, b) {
|
||||
return b === null || b === undefined || a < b ? -1 : 1;
|
||||
}
|
||||
|
||||
const topAEl = fetchValue(a, 'top');
|
||||
const topBEl = fetchValue(b, 'top');
|
||||
|
||||
console.log(a.title, topAEl);
|
||||
console.log(b.title, topBEl);
|
||||
console.log("comp", compare(topAEl, topBEl) && !reverse);
|
||||
|
||||
if (topAEl !== topBEl) {
|
||||
// since "top" should not be reversible, we'll reverse it once more to nullify this effect
|
||||
return compare(topAEl, topBEl) * (reverse ? -1 : 1);
|
||||
}
|
||||
|
||||
const customAEl = fetchValue(a, customSortBy);
|
||||
const customBEl = fetchValue(b, customSortBy);
|
||||
|
||||
if (customAEl !== customBEl) {
|
||||
return compare(customAEl, customBEl);
|
||||
}
|
||||
|
||||
const titleAEl = fetchValue(a, 'title');
|
||||
const titleBEl = fetchValue(b, 'title');
|
||||
|
||||
return compare(titleAEl, titleBEl);
|
||||
});
|
||||
|
||||
if (reverse) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user