From d3ec9f022c6aecaa95caa2cc5691bc6235c50f01 Mon Sep 17 00:00:00 2001
From: Nriver <6752679+Nriver@users.noreply.github.com>
Date: Fri, 10 Mar 2023 14:35:36 +0800
Subject: [PATCH 1/2] add natural sort for notes, introduce new label
#sortNatural
---
.../app/widgets/dialogs/sort_child_notes.js | 14 +++++++++++++-
src/routes/api/notes.js | 6 +++---
src/services/builtin_attributes.js | 1 +
src/services/handlers.js | 4 ++--
src/services/tree.js | 16 ++++++++++++----
5 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/src/public/app/widgets/dialogs/sort_child_notes.js b/src/public/app/widgets/dialogs/sort_child_notes.js
index 65440efe4..ccb12544a 100644
--- a/src/public/app/widgets/dialogs/sort_child_notes.js
+++ b/src/public/app/widgets/dialogs/sort_child_notes.js
@@ -65,6 +65,17 @@ const TPL = `
+
+
+
+ Natural Sort
+
+
+
+
@@ -95,8 +104,9 @@ export default class SortChildNotesDialog extends BasicWidget {
const sortDirection = this.$form.find("input[name='sort-direction']:checked").val();
const foldersFirst = this.$form.find("input[name='sort-folders-first']").is(":checked");
const sortNatural = this.$form.find("input[name='sort-natural']").is(":checked");
+ const sortLocale = this.$form.find("input[name='sort-locale']").val();
- await server.put(`notes/${this.parentNoteId}/sort-children`, {sortBy, sortDirection, foldersFirst, sortNatural});
+ await server.put(`notes/${this.parentNoteId}/sort-children`, {sortBy, sortDirection, foldersFirst, sortNatural, sortLocale});
utils.closeActiveDialog();
});
diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js
index e019ddb8b..8ce603f37 100644
--- a/src/routes/api/notes.js
+++ b/src/routes/api/notes.js
@@ -94,13 +94,13 @@ function undeleteNote(req) {
function sortChildNotes(req) {
const noteId = req.params.noteId;
- const {sortBy, sortDirection, foldersFirst, sortNatural} = req.body;
+ const {sortBy, sortDirection, foldersFirst, sortNatural, sortLocale} = req.body;
- log.info(`Sorting '${noteId}' children with ${sortBy} ${sortDirection}, foldersFirst=${foldersFirst}, sortNatural=${sortNatural}`);
+ log.info(`Sorting '${noteId}' children with ${sortBy} ${sortDirection}, foldersFirst=${foldersFirst}, sortNatural=${sortNatural}, sortLocale=${sortLocale}`);
const reverse = sortDirection === 'desc';
- treeService.sortNotes(noteId, sortBy, reverse, foldersFirst, sortNatural);
+ treeService.sortNotes(noteId, sortBy, reverse, foldersFirst, sortNatural, sortLocale);
}
function protectNote(req) {
diff --git a/src/services/builtin_attributes.js b/src/services/builtin_attributes.js
index b05ef66e5..6ab9b8a52 100644
--- a/src/services/builtin_attributes.js
+++ b/src/services/builtin_attributes.js
@@ -43,6 +43,7 @@ module.exports = [
{ type: 'label', name: 'sortDirection' },
{ type: 'label', name: 'sortFoldersFirst' },
{ type: 'label', name: 'sortNatural' },
+ { type: 'label', name: 'sortLocale' },
{ type: 'label', name: 'top' },
{ type: 'label', name: 'fullContentWidth' },
{ type: 'label', name: 'shareHiddenFromTree' },
diff --git a/src/services/handlers.js b/src/services/handlers.js
index e0902d8bc..75f5563b3 100644
--- a/src/services/handlers.js
+++ b/src/services/handlers.js
@@ -46,7 +46,7 @@ eventService.subscribe([ eventService.ENTITY_CHANGED, eventService.ENTITY_DELETE
if (entityName === 'attributes') {
runAttachedRelations(entity.getNote(), 'runOnAttributeChange', entity);
- if (entity.type === 'label' && ['sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural'].includes(entity.name)) {
+ if (entity.type === 'label' && ['sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural', 'sortLocale'].includes(entity.name)) {
handleSortedAttribute(entity);
} else if (entity.type === 'label') {
handleMaybeSortingLabel(entity);
@@ -101,7 +101,7 @@ eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) =>
noteService.duplicateSubtreeWithoutRoot(templateNote.noteId, note.noteId);
}
}
- else if (entity.type === 'label' && ['sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural'].includes(entity.name)) {
+ else if (entity.type === 'label' && ['sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural', 'sortLocale'].includes(entity.name)) {
handleSortedAttribute(entity);
}
else if (entity.type === 'label') {
diff --git a/src/services/tree.js b/src/services/tree.js
index bf537c985..1038e8772 100644
--- a/src/services/tree.js
+++ b/src/services/tree.js
@@ -123,11 +123,16 @@ function loadSubtreeNoteIds(parentNoteId, subtreeNoteIds) {
}
}
-function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, foldersFirst = false, sortNatural = false) {
+function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, foldersFirst = false, sortNatural = false, sortLocale) {
if (!customSortBy) {
customSortBy = 'title';
}
+ if (!sortLocale) {
+ // sortLocale can not be empty string or null value, default value must be set to undefined.
+ sortLocale = undefined;
+ }
+
sql.transactional(() => {
const notes = becca.getNote(parentNoteId).getChildNotes();
@@ -157,8 +162,8 @@ function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, folder
// alphabetical sort
return b === null || b === undefined || a < b ? -1 : 1;
} else {
- // alphanumeric sort, or natural sort
- return a.localeCompare(b, undefined, {numeric: true, sensitivity: 'base'});
+ // natural sort
+ return a.localeCompare(b, sortLocale, {numeric: true, sensitivity: 'base'});
}
}
@@ -233,7 +238,9 @@ function sortNotesIfNeeded(parentNoteId) {
const sortFoldersFirst = sortFoldersFirstLabel && sortFoldersFirstLabel.value.toLowerCase() !== "false";
const sortNaturalLabel = parentNote.getLabel('sortNatural');
const sortNatural = sortNaturalLabel && sortNaturalLabel.value.toLowerCase() !== "false";
- sortNotes(parentNoteId, sortedLabel.value, sortReversed, sortFoldersFirst, sortNatural);
+ const sortLocale = parentNote.getLabelValue('sortLocale');
+
+ sortNotes(parentNoteId, sortedLabel.value, sortReversed, sortFoldersFirst, sortNatural, sortLocale);
}
/**