diff --git a/package-lock.json b/package-lock.json index f86622619..420451552 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1602,16 +1602,16 @@ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" }, "browserslist": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.2.tgz", - "integrity": "sha512-jSDZyqJmkKMEMi7SZAgX5UltFdR5NAO43vY0AwTpu4X3sGH7GLLQ83KiUomgrnvZRCeW0yPPnKqnxPqQOER9zQ==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz", + "integrity": "sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001261", - "electron-to-chromium": "^1.3.854", + "caniuse-lite": "^1.0.30001264", + "electron-to-chromium": "^1.3.857", "escalade": "^3.1.1", - "nanocolors": "^0.2.12", - "node-releases": "^1.1.76" + "node-releases": "^1.1.77", + "picocolors": "^0.2.1" } }, "buffer": { @@ -3578,9 +3578,9 @@ } }, "electron-to-chromium": { - "version": "1.3.857", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.857.tgz", - "integrity": "sha512-a5kIr2lajm4bJ5E4D3fp8Y/BRB0Dx2VOcCRE5Gtb679mXIME/OFhWler8Gy2ksrf8gFX+EFCSIGA33FB3gqYpg==", + "version": "1.3.859", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.859.tgz", + "integrity": "sha512-gXRXKNWedfdiKIzwr0Mg/VGCvxXzy+4SuK9hp1BDvfbCwx0O5Ot+2f4CoqQkqEJ3Zj/eAV/GoAFgBVFgkBLXuQ==", "dev": true }, "electron-window-state": { @@ -5824,12 +5824,6 @@ "xtend": "^4.0.0" } }, - "nanocolors": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.12.tgz", - "integrity": "sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug==", - "dev": true - }, "nanoid": { "version": "3.1.25", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", @@ -6363,6 +6357,12 @@ "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" }, + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -8098,9 +8098,9 @@ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "webpack": { - "version": "5.56.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.56.1.tgz", - "integrity": "sha512-MRbTPooHJuSAfbx7Lh/qEMRUe/d0p4cRj2GPo/fq+4JUeR/+Q1EfLvS1lexslbMcJZyPXxxz/k/NzVepkA5upA==", + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.57.0.tgz", + "integrity": "sha512-kbKX1HOJpEhX9GZDFgHauU/7HfgGeGzUzjSUV+wZjGxP3PFeau7BgYFtm5+UTtJJSqmXYKFuBpWRDrSdQ3d8zA==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", diff --git a/package.json b/package.json index 3ba89bb1c..5d732da40 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "jsdoc": "3.6.7", "lorem-ipsum": "2.0.4", "rcedit": "3.0.1", - "webpack": "5.56.1", + "webpack": "5.57.0", "webpack-cli": "4.8.0" }, "optionalDependencies": { diff --git a/src/becca/becca_service.js b/src/becca/becca_service.js index 836747798..afea5af03 100644 --- a/src/becca/becca_service.js +++ b/src/becca/becca_service.js @@ -140,6 +140,10 @@ function getSomePathInner(note, path, respectHoisting) { path.push(note.noteId); path.reverse(); + if (path.includes("hidden")) { + return false; + } + if (respectHoisting && !path.includes(cls.getHoistedNoteId())) { return false; } diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 2eee0b842..0f420a2e9 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -44,6 +44,7 @@ import CalendarMenuWidget from "../widgets/buttons/calendar_menu.js"; import EditedNotesWidget from "../widgets/ribbon_widgets/edited_notes.js"; import OpenNoteButtonWidget from "../widgets/buttons/open_note_button_widget.js"; import MermaidWidget from "../widgets/mermaid.js"; +import BookmarkButtons from "../widgets/bookmark_buttons.js"; export default class DesktopLayout { constructor(customWidgets) { @@ -72,8 +73,6 @@ export default class DesktopLayout { .title("Jump to note") .command("jumpToNote")) .child(new OpenNoteButtonWidget() - .icon("bx-map-alt") - .title("Global note map") .targetNote('globalnotemap')) .child(new ButtonWidget() .icon("bx-history") @@ -84,6 +83,7 @@ export default class DesktopLayout { .child(new FlexContainer("column") .id("plugin-buttons") .contentSized()) + .child(new BookmarkButtons()) .child(new SpacerWidget(0, 1000)) .child(new ProtectedSessionStatusWidget()) .child(new SyncStatusWidget()) diff --git a/src/public/app/widgets/bookmark_buttons.js b/src/public/app/widgets/bookmark_buttons.js new file mode 100644 index 000000000..49b4ad0c5 --- /dev/null +++ b/src/public/app/widgets/bookmark_buttons.js @@ -0,0 +1,52 @@ +import FlexContainer from "./containers/flex_container.js"; +import searchService from "../services/search.js"; +import OpenNoteButtonWidget from "./buttons/open_note_button_widget.js"; + +export default class BookmarkButtons extends FlexContainer { + constructor() { + super("column"); + + this.contentSized(); + } + + async refresh() { + const bookmarkedNotes = await searchService.searchForNotes("#bookmarked"); + + this.$widget.empty(); + this.children = []; + this.noteIds = []; + + for (const note of bookmarkedNotes) { + this.noteIds.push(note.noteId); + + const buttonWidget = new OpenNoteButtonWidget().targetNote(note.noteId); + + this.child(buttonWidget); + + this.$widget.append(buttonWidget.render()); + + buttonWidget.refreshIcon(); + } + } + + initialRenderCompleteEvent() { + this.refresh(); + } + + entitiesReloadedEvent({loadResults}) { + if (loadResults.getAttributes().find(attr => attr.type === 'label' && attr.name === 'bookmarked')) { + this.refresh(); + } + + if (loadResults.getNoteIds().find(noteId => this.noteIds.includes(noteId))) { + this.refresh(); + } + + if (loadResults.getAttributes().find(attr => attr.type === 'label' + && ['iconClass', 'workspaceIconClass'].includes(attr.name) + && this.noteIds.includes(attr.noteId)) + ) { + this.refresh(); + } + } +} diff --git a/src/public/app/widgets/bookmark_switch.js b/src/public/app/widgets/bookmark_switch.js new file mode 100644 index 000000000..841367d21 --- /dev/null +++ b/src/public/app/widgets/bookmark_switch.js @@ -0,0 +1,107 @@ +import NoteContextAwareWidget from "./note_context_aware_widget.js"; +import protectedSessionService from "../services/protected_session.js"; +import attributeService from "../services/attributes.js"; + +const TPL = ` +
+ + +
+ Bookmark + +   + + + +
+
+ Bookmark + +   + + + +
+
`; + +export default class BookmarkSwitchWidget extends NoteContextAwareWidget { + doRender() { + this.$widget = $(TPL); + + this.$addBookmarkButton = this.$widget.find(".add-bookmark-button"); + this.$addBookmarkButton.on('click', () => attributeService.setLabel(this.noteId, 'bookmarked')); + + this.$removeBookmarkButton = this.$widget.find(".remove-bookmark-button"); + this.$removeBookmarkButton.on('click', async () => { + for (const label of this.note.getLabels('bookmarked')) { + await attributeService.removeAttributeById(this.noteId, label.attributeId); + } + }); + } + + refreshWithNote(note) { + const isBookmarked = note.hasLabel('bookmarked'); + + this.$addBookmarkButton.toggle(!isBookmarked); + this.$removeBookmarkButton.toggle(isBookmarked); + } + + entitiesReloadedEvent({loadResults}) { + for (const attr of loadResults.getAttributes()) { + if (attr.type === 'label' + && attr.name === 'bookmarked' + && attributeService.isAffecting(attr, this.note)) { + + this.refresh(); + break; + } + } + } +} diff --git a/src/public/app/widgets/buttons/open_note_button_widget.js b/src/public/app/widgets/buttons/open_note_button_widget.js index 9e25eb2a6..4190c0cc3 100644 --- a/src/public/app/widgets/buttons/open_note_button_widget.js +++ b/src/public/app/widgets/buttons/open_note_button_widget.js @@ -1,12 +1,22 @@ import ButtonWidget from "./button_widget.js"; import appContext from "../../services/app_context.js"; - -// TODO: here we could read icon and title of the target note and use it for tooltip and displayed icon +import froca from "../../services/froca.js"; export default class OpenNoteButtonWidget extends ButtonWidget { targetNote(noteId) { + froca.getNote(noteId).then(note => { + this.icon(note.getIcon()); + this.title(note.title); + + this.refreshIcon(); + }); + this.onClick(() => appContext.tabManager.openTabWithNoteWithHoisting(noteId, true)); return this; } + + initialRenderCompleteEvent() { + // we trigger refresh above + } } diff --git a/src/public/app/widgets/protected_note_switch.js b/src/public/app/widgets/protected_note_switch.js index 93cca599d..46bad6db0 100644 --- a/src/public/app/widgets/protected_note_switch.js +++ b/src/public/app/widgets/protected_note_switch.js @@ -5,7 +5,7 @@ const TPL = `
diff --git a/src/public/app/widgets/ribbon_widgets/basic_properties.js b/src/public/app/widgets/ribbon_widgets/basic_properties.js index 6e997aa79..8907283db 100644 --- a/src/public/app/widgets/ribbon_widgets/basic_properties.js +++ b/src/public/app/widgets/ribbon_widgets/basic_properties.js @@ -2,6 +2,7 @@ import NoteContextAwareWidget from "../note_context_aware_widget.js"; import NoteTypeWidget from "../note_type.js"; import ProtectedNoteSwitchWidget from "../protected_note_switch.js"; import EditabilitySelectWidget from "../editability_select.js"; +import BookmarkSwitchWidget from "../bookmark_switch.js"; const TPL = `
@@ -33,6 +34,8 @@ const TPL = `
Editable:  
+ +
`; export default class BasicPropertiesWidget extends NoteContextAwareWidget { @@ -42,8 +45,14 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget { this.noteTypeWidget = new NoteTypeWidget().contentSized(); this.protectedNoteSwitchWidget = new ProtectedNoteSwitchWidget().contentSized(); this.editabilitySelectWidget = new EditabilitySelectWidget().contentSized(); + this.bookmarkSwitchWidget = new BookmarkSwitchWidget().contentSized(); - this.child(this.noteTypeWidget, this.protectedNoteSwitchWidget, this.editabilitySelectWidget); + this.child( + this.noteTypeWidget, + this.protectedNoteSwitchWidget, + this.editabilitySelectWidget, + this.bookmarkSwitchWidget + ); } get name() { @@ -55,7 +64,7 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget { } isEnabled() { - return this.note && (this.note.type === 'text' || this.note.type === 'code' || this.note.type == 'mermaid'); + return this.note && (this.note.type === 'text' || this.note.type === 'code' || this.note.type === 'mermaid'); } getTitle() { @@ -73,5 +82,6 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget { this.$widget.find(".note-type-container").append(this.noteTypeWidget.render()); this.$widget.find(".protected-note-switch-container").append(this.protectedNoteSwitchWidget.render()); this.$widget.find(".editability-select-container").append(this.editabilitySelectWidget.render()); + this.$widget.find(".bookmark-switch-container").append(this.bookmarkSwitchWidget.render()); } }